branches/alto2/src/emu/cpu/alto2/a2mem.c
| r26136 | r26137 | |
| 451 | 451 | LOG((LOG_MEM,5," memory error at dword addr:%07o data:%011o check:%03o\n", dw_addr * 2, dw_data, hpb)); |
| 452 | 452 | LOG((LOG_MEM,6," MEAR: %06o\n", m_mem.mear)); |
| 453 | 453 | LOG((LOG_MEM,6," MESR: %06o\n", m_mem.mesr ^ 0177777)); |
| 454 | | LOG((LOG_MEM,6," Hamming code read : %#o\n", GET_MESR_HAMMING(m_mem.mesr))); |
| 455 | | LOG((LOG_MEM,6," Parity error : %o\n", GET_MESR_PERR(m_mem.mesr))); |
| 456 | | LOG((LOG_MEM,6," Memory parity bit : %o\n", GET_MESR_PARITY(m_mem.mesr))); |
| 457 | | LOG((LOG_MEM,6," Hamming syndrome : %#o (bit #%d)\n", GET_MESR_SYNDROME(m_mem.mesr), hamming_lut[GET_MESR_SYNDROME(m_mem.mesr)])); |
| 458 | | LOG((LOG_MEM,6," Memory bank : %#o\n", GET_MESR_BANK(m_mem.mesr))); |
| 454 | LOG((LOG_MEM,7," Hamming code read : %#o\n", GET_MESR_HAMMING(m_mem.mesr))); |
| 455 | LOG((LOG_MEM,7," Parity error : %o\n", GET_MESR_PERR(m_mem.mesr))); |
| 456 | LOG((LOG_MEM,7," Memory parity bit : %o\n", GET_MESR_PARITY(m_mem.mesr))); |
| 457 | LOG((LOG_MEM,7," Hamming syndrome : %#o (bit #%d)\n", GET_MESR_SYNDROME(m_mem.mesr), hamming_lut[GET_MESR_SYNDROME(m_mem.mesr)])); |
| 458 | LOG((LOG_MEM,7," Memory bank : %#o\n", GET_MESR_BANK(m_mem.mesr))); |
| 459 | 459 | LOG((LOG_MEM,6," MECR: %06o\n", m_mem.mecr ^ 0177777)); |
| 460 | | LOG((LOG_MEM,6," Test Hamming code : %#o\n", GET_MECR_TEST_CODE(m_mem.mecr))); |
| 461 | | LOG((LOG_MEM,6," Test mode : %s\n", GET_MECR_TEST_MODE(m_mem.mecr) ? "on" : "off")); |
| 462 | | LOG((LOG_MEM,6," INT on single-bit err: %s\n", GET_MECR_INT_SBERR(m_mem.mecr) ? "on" : "off")); |
| 463 | | LOG((LOG_MEM,6," INT on double-bit err: %s\n", GET_MECR_INT_DBERR(m_mem.mecr) ? "on" : "off")); |
| 464 | | LOG((LOG_MEM,6," Error correction : %s\n", GET_MECR_ERRCORR(m_mem.mecr) ? "off" : "on")); |
| 460 | LOG((LOG_MEM,7," Test Hamming code : %#o\n", GET_MECR_TEST_CODE(m_mem.mecr))); |
| 461 | LOG((LOG_MEM,7," Test mode : %s\n", GET_MECR_TEST_MODE(m_mem.mecr) ? "on" : "off")); |
| 462 | LOG((LOG_MEM,7," INT on single-bit err: %s\n", GET_MECR_INT_SBERR(m_mem.mecr) ? "on" : "off")); |
| 463 | LOG((LOG_MEM,7," INT on double-bit err: %s\n", GET_MECR_INT_DBERR(m_mem.mecr) ? "on" : "off")); |
| 464 | LOG((LOG_MEM,7," Error correction : %s\n", GET_MECR_ERRCORR(m_mem.mecr) ? "off" : "on")); |
| 465 | 465 | } |
| 466 | 466 | if (-1 == hamming_lut[syndrome]) { |
| 467 | 467 | /* double-bit error: wake task_part, if we're told so */ |
| r26136 | r26137 | |
| 629 | 629 | * starting a memory refresh cycle |
| 630 | 630 | * currently we don't do anything special |
| 631 | 631 | */ |
| 632 | | LOG((LOG_MEM,5, " MAR<-; refresh cycle @ %#o\n", addr)); |
| 632 | LOG((LOG_MEM,5, " MAR←; refresh cycle @ %#o\n", addr)); |
| 633 | 633 | } else if (addr < ALTO2_RAM_SIZE) { |
| 634 | | LOG((LOG_MEM,2, " MAR<-; mar = %#o\n", addr)); |
| 634 | LOG((LOG_MEM,2, " MAR←; mar = %#o\n", addr)); |
| 635 | 635 | m_mem.access = ALTO2_MEM_RAM; |
| 636 | 636 | m_mem.mar = addr; |
| 637 | 637 | /* fetch memory double-word to read/write latches */ |
branches/alto2/src/emu/cpu/alto2/a2emu.c
| r26136 | r26137 | |
| 164 | 164 | * From the schematics: 08_ALU, page 6 (PDF page 4) |
| 165 | 165 | * |
| 166 | 166 | * EMACT emulator task active |
| 167 | | * F2[0-2]=111b <-ACSOURCE and F2_17 |
| 168 | | * F2[0-2]=101b DNS<- and ACDEST<- |
| 167 | * F2[0-2]=111b ←ACSOURCE and F2_17 |
| 168 | * F2[0-2]=101b DNS← and ACDEST← |
| 169 | 169 | * |
| 170 | 170 | * u49 (8 input NAND 74S30) |
| 171 | 171 | * ---------------------------------------------- |
| r26136 | r26137 | |
| 254 | 254 | * |
| 255 | 255 | * The high order bits of IR cannot be read directly, but the |
| 256 | 256 | * displacement field of IR (8 low order bits) may be read with |
| 257 | | * the <-DISP bus source. If the X field of the instruction is |
| 257 | * the ←DISP bus source. If the X field of the instruction is |
| 258 | 258 | * zero (i.e., it specifies page 0 addressing), then the DISP |
| 259 | 259 | * field of the instruction is put on BUS[8-15] and BUS[0-7] |
| 260 | 260 | * is zeroed. If the X field of the instruction is non-zero |
| r26136 | r26137 | |
| 268 | 268 | if (IR_X(m_emu.ir)) { |
| 269 | 269 | r = ((signed char)r) & 0177777; |
| 270 | 270 | } |
| 271 | | LOG((LOG_EMU,2, " <-DISP (%06o)\n", r)); |
| 271 | LOG((LOG_EMU,2, " ←DISP (%06o)\n", r)); |
| 272 | 272 | m_bus &= r; |
| 273 | 273 | } |
| 274 | 274 | |
| r26136 | r26137 | |
| 302 | 302 | */ |
| 303 | 303 | void alto2_cpu_device::f1_emu_load_rmr_1() |
| 304 | 304 | { |
| 305 | | LOG((LOG_EMU,2," RMR<-; BUS (%#o)\n", m_bus)); |
| 305 | LOG((LOG_EMU,2," RMR←; BUS (%#o)\n", m_bus)); |
| 306 | 306 | m_reset_mode = m_bus; |
| 307 | 307 | } |
| 308 | 308 | |
| r26136 | r26137 | |
| 311 | 311 | */ |
| 312 | 312 | void alto2_cpu_device::f1_emu_load_esrb_1() |
| 313 | 313 | { |
| 314 | | LOG((LOG_EMU,2," ESRB<-; BUS[12-14] (%#o)\n", m_bus)); |
| 314 | LOG((LOG_EMU,2," ESRB←; BUS[12-14] (%#o)\n", m_bus)); |
| 315 | 315 | m_s_reg_bank[m_task] = A2_GET32(m_bus,16,12,14); |
| 316 | 316 | } |
| 317 | 317 | |
| r26136 | r26137 | |
| 324 | 324 | void alto2_cpu_device::f1_rsnf_0() |
| 325 | 325 | { |
| 326 | 326 | UINT16 r = 0177400 | m_ether_id; |
| 327 | | LOG((LOG_EMU,2," <-RSNF; (%#o)\n", r)); |
| 327 | LOG((LOG_EMU,2," ←RSNF; (%#o)\n", r)); |
| 328 | 328 | m_bus &= r; |
| 329 | 329 | } |
| 330 | 330 | |
| r26136 | r26137 | |
| 385 | 385 | { |
| 386 | 386 | int XC; |
| 387 | 387 | switch (MIR_F1(m_mir)) { |
| 388 | | case f1_l_lsh_1: // <-L MLSH 1 |
| 388 | case f1_l_lsh_1: // ←L MLSH 1 |
| 389 | 389 | XC = (m_t >> 15) & 1; |
| 390 | 390 | m_shifter = (m_l << 1) & 0177777; |
| 391 | 391 | m_shifter |= XC; |
| 392 | | LOG((LOG_EMU,2," <-L MLSH 1 (shifer:%06o XC:%o)", m_shifter, XC)); |
| 392 | LOG((LOG_EMU,2," ←L MLSH 1 (shifer:%06o XC:%o)", m_shifter, XC)); |
| 393 | 393 | break; |
| 394 | | case f1_l_rsh_1: // <-L MRSH 1 |
| 394 | case f1_l_rsh_1: // ←L MRSH 1 |
| 395 | 395 | XC = m_t & 1; |
| 396 | 396 | m_shifter = m_l >> 1; |
| 397 | 397 | m_shifter |= XC << 15; |
| 398 | | LOG((LOG_EMU,2," <-L MRSH 1 (shifter:%06o XC:%o)", m_shifter, XC)); |
| 398 | LOG((LOG_EMU,2," ←L MRSH 1 (shifter:%06o XC:%o)", m_shifter, XC)); |
| 399 | 399 | break; |
| 400 | | case f1_l_lcy_8: // <-L LCY 8 |
| 400 | case f1_l_lcy_8: // ←L LCY 8 |
| 401 | 401 | default: // other |
| 402 | 402 | break; |
| 403 | 403 | } |
| r26136 | r26137 | |
| 415 | 415 | #else |
| 416 | 416 | A2_PUT8(m_rsel, 5, 3, 4, IR_DstAC(m_emu.ir) ^ 3); |
| 417 | 417 | #endif |
| 418 | | LOG((LOG_EMU,2," DNS<-; rsel := DstAC (%#o %s)\n", m_rsel, r_name(m_rsel))); |
| 418 | LOG((LOG_EMU,2," DNS←; rsel := DstAC (%#o %s)\n", m_rsel, r_name(m_rsel))); |
| 419 | 419 | } |
| 420 | 420 | |
| 421 | 421 | /** |
| r26136 | r26137 | |
| 437 | 437 | * XC = !(!(DNS & exorD) & !(MAGIC & OUTza)) |
| 438 | 438 | * = (DNS & exorD) | (MAGIC & OUTza) |
| 439 | 439 | * = exorD, because this is DNS |
| 440 | | * NEWCARRY = [XC, L(00), L(15), XC] for F1 = no shift, <-L RSH 1, <-L LSH 1, LCY 8 |
| 440 | * NEWCARRY = [XC, L(00), L(15), XC] for F1 = no shift, ←L RSH 1, ←L LSH 1, LCY 8 |
| 441 | 441 | * SHZERO = shifter == 0 |
| 442 | 442 | * DCARRY = !((!IR12 & NEWCARRY) | (IR12 & CARRY)) |
| 443 | 443 | * = (((IR12 ^ 1) & NEWCARRY) | (IR12 & CARRY)) ^ 1 |
| r26136 | r26137 | |
| 466 | 466 | UINT8 SHZERO; |
| 467 | 467 | |
| 468 | 468 | switch (MIR_F1(m_mir)) { |
| 469 | | case f1_l_rsh_1: // <-L RSH 1 |
| 469 | case f1_l_rsh_1: // ←L RSH 1 |
| 470 | 470 | NEWCARRY = m_l & 1; |
| 471 | 471 | m_shifter = ((m_l >> 1) | (XC << 15)) & 0177777; |
| 472 | | LOG((LOG_EMU,2," DNS; <-L RSH 1 (shifter:%06o XC:%o NEWCARRY:%o)", m_shifter, XC, NEWCARRY)); |
| 472 | LOG((LOG_EMU,2," DNS; ←L RSH 1 (shifter:%06o XC:%o NEWCARRY:%o)", m_shifter, XC, NEWCARRY)); |
| 473 | 473 | break; |
| 474 | | case f1_l_lsh_1: // <-L LSH 1 |
| 474 | case f1_l_lsh_1: // ←L LSH 1 |
| 475 | 475 | NEWCARRY = (m_l >> 15) & 1; |
| 476 | 476 | m_shifter = ((m_l << 1) | XC) & 0177777; |
| 477 | | LOG((LOG_EMU,2," DNS; <-L LSH 1 (shifter:%06o XC:%o NEWCARRY:%o)", m_shifter, XC, NEWCARRY)); |
| 477 | LOG((LOG_EMU,2," DNS; ←L LSH 1 (shifter:%06o XC:%o NEWCARRY:%o)", m_shifter, XC, NEWCARRY)); |
| 478 | 478 | break; |
| 479 | | case f1_l_lcy_8: // <-L LCY 8 |
| 479 | case f1_l_lcy_8: // ←L LCY 8 |
| 480 | 480 | default: /* other */ |
| 481 | 481 | NEWCARRY = XC; |
| 482 | 482 | LOG((LOG_EMU,2," DNS; (shifter:%06o NEWCARRY:%o)", m_shifter, NEWCARRY)); |
| r26136 | r26137 | |
| 506 | 506 | #else |
| 507 | 507 | A2_PUT8(m_rsel, 5, 3, 4, IR_DstAC(m_emu.ir) ^ 3); |
| 508 | 508 | #endif |
| 509 | | LOG((LOG_EMU,2," ACDEST<-; mux (rsel:%#o %s)\n", m_rsel, r_name(m_rsel))); |
| 509 | LOG((LOG_EMU,2," ACDEST←; mux (rsel:%#o %s)\n", m_rsel, r_name(m_rsel))); |
| 510 | 510 | } |
| 511 | 511 | |
| 512 | 512 | #if ALTO2_DEBUG |
| r26136 | r26137 | |
| 628 | 628 | if (IR_ARITH(m_emu.ir)) { |
| 629 | 629 | /* 1xxxxxxxxxxxxxxx */ |
| 630 | 630 | r = IR_SH(m_emu.ir) ^ 3; /* complement of SH */ |
| 631 | | LOG((LOG_EMU,2," IDISP<-; branch on SH^3 (%#o|%#o)\n", m_next2, r)); |
| 631 | LOG((LOG_EMU,2," IDISP←; branch on SH^3 (%#o|%#o)\n", m_next2, r)); |
| 632 | 632 | } else { |
| 633 | 633 | int addr = CTL2K_U3(f2_emu_idisp) + A2_GET32(m_emu.ir,16,1,7); |
| 634 | 634 | /* 0???????xxxxxxxx */ |
| 635 | 635 | r = m_ctl2k_u3[addr]; |
| 636 | | LOG((LOG_EMU,2," IDISP<-; IR (%#o) branch on PROM ctl2k_u3[%03o] (%#o|%#o)\n", m_emu.ir, addr, m_next2, r)); |
| 636 | LOG((LOG_EMU,2," IDISP←; IR (%#o) branch on PROM ctl2k_u3[%03o] (%#o|%#o)\n", m_emu.ir, addr, m_next2, r)); |
| 637 | 637 | } |
| 638 | 638 | m_next2 |= r; |
| 639 | 639 | } |
| r26136 | r26137 | |
| 649 | 649 | #else |
| 650 | 650 | A2_PUT8(m_rsel, 5, 3, 4, IR_SrcAC(m_emu.ir) ^ 3); |
| 651 | 651 | #endif |
| 652 | | LOG((LOG_EMU,2," <-ACSOURCE; rsel := SrcAC (%#o %s)\n", m_rsel, r_name(m_rsel))); |
| 652 | LOG((LOG_EMU,2," ←ACSOURCE; rsel := SrcAC (%#o %s)\n", m_rsel, r_name(m_rsel))); |
| 653 | 653 | } |
| 654 | 654 | |
| 655 | 655 | /** |
| r26136 | r26137 | |
| 662 | 662 | if (IR_ARITH(m_emu.ir)) { |
| 663 | 663 | /* 1xxxxxxxxxxxxxxx */ |
| 664 | 664 | r = IR_SH(m_emu.ir) ^ 3; /* complement of SH */ |
| 665 | | LOG((LOG_EMU,2," <-ACSOURCE; branch on SH^3 (%#o|%#o)\n", m_next2, r)); |
| 665 | LOG((LOG_EMU,2," ←ACSOURCE; branch on SH^3 (%#o|%#o)\n", m_next2, r)); |
| 666 | 666 | } else { |
| 667 | 667 | int addr = CTL2K_U3(f2_emu_acsource) + A2_GET32(m_emu.ir,16,1,7); |
| 668 | 668 | /* 0???????xxxxxxxx */ |
| 669 | 669 | r = m_ctl2k_u3[addr]; |
| 670 | | LOG((LOG_EMU,2," <-ACSOURCE; branch on PROM ctl2k_u3[%03o] (%#o|%#o)\n", addr, m_next2, r)); |
| 670 | LOG((LOG_EMU,2," ←ACSOURCE; branch on PROM ctl2k_u3[%03o] (%#o|%#o)\n", addr, m_next2, r)); |
| 671 | 671 | } |
| 672 | 672 | m_next2 |= r; |
| 673 | 673 | } |
branches/alto2/src/emu/cpu/alto2/a2disk.c
| r26136 | r26137 | |
| 96 | 96 | static const char *rwc_name[4] = {"read", "check", "write", "write2"}; |
| 97 | 97 | #endif |
| 98 | 98 | |
| 99 | | #if JKFF_FUNCTION |
| 100 | | |
| 101 | 99 | #if ALTO2_DEBUG |
| 102 | 100 | static const char *jkff_name; |
| 103 | 101 | /** @brief macro to set the name of a FF in DEBUG=1 builds only */ |
| r26136 | r26137 | |
| 106 | 104 | #define DEBUG_NAME(x) |
| 107 | 105 | #endif |
| 108 | 106 | |
| 107 | #if JKFF_FUNCTION |
| 108 | |
| 109 | 109 | /** |
| 110 | 110 | * @brief simulate a 74109 J-K flip-flop with set and reset inputs |
| 111 | 111 | * |
| 112 | 112 | * @param s0 is the previous state of the FF's in- and outputs |
| 113 | 113 | * @param s1 is the next state |
| 114 | | * @result returns the next state and probably modified Q output |
| 114 | * @return returns the next state and probably modified Q output |
| 115 | 115 | */ |
| 116 | | static inline jkff_t update_jkff(jkff_t s0, jkff_t s1) |
| 116 | jkff_t alto2_cpu_device::update_jkff(UINT8 s0, UINT8 s1) |
| 117 | 117 | { |
| 118 | 118 | switch (s1 & (JKFF_C | JKFF_S)) { |
| 119 | 119 | case JKFF_C | JKFF_S: /* C' is 1, and S' is 1 */ |
| r26136 | r26137 | |
| 124 | 124 | /* both J and K' are 0: set Q to 0, Q' to 1 */ |
| 125 | 125 | s1 = (s1 & ~JKFF_Q) | JKFF_Q0; |
| 126 | 126 | if (s0 & JKFF_Q) { |
| 127 | | LOG((LOG_DISK,5,"%s J:0 K':0 -> Q:0\n", jkff_name)); |
| 127 | LOG((LOG_DISK,5,"%s J:0 K':0 → Q:0\n", jkff_name)); |
| 128 | 128 | } |
| 129 | 129 | break; |
| 130 | 130 | case JKFF_J: |
| r26136 | r26137 | |
| 151 | 151 | /* both J and K' are 1: set Q to 1 */ |
| 152 | 152 | s1 = (s1 | JKFF_Q) & ~JKFF_Q0; |
| 153 | 153 | if (!(s0 & JKFF_Q)) { |
| 154 | | LOG((LOG_DISK,5,"%s J:1 K':1 -> Q:1\n", |
| 154 | LOG((LOG_DISK,5,"%s J:1 K':1 → Q:1\n", |
| 155 | 155 | jkff_name)); |
| 156 | 156 | } |
| 157 | 157 | break; |
| r26136 | r26137 | |
| 165 | 165 | /* S' is 1, C' is 0: set Q to 0, Q' to 1 */ |
| 166 | 166 | s1 = (s1 & ~JKFF_Q) | JKFF_Q0; |
| 167 | 167 | if (s0 & JKFF_Q) { |
| 168 | | LOG((LOG_DISK,5,"%s C':0 -> Q:0\n", jkff_name)); |
| 168 | LOG((LOG_DISK,5,"%s C':0 → Q:0\n", jkff_name)); |
| 169 | 169 | } |
| 170 | 170 | break; |
| 171 | 171 | case JKFF_C: |
| 172 | 172 | /* S' is 0, C' is 1: set Q to 1, Q' to 0 */ |
| 173 | 173 | s1 = (s1 | JKFF_Q) & ~JKFF_Q0; |
| 174 | 174 | if (!(s0 & JKFF_Q)) { |
| 175 | | LOG((LOG_DISK,5,"%s S':0 -> Q:1\n", jkff_name)); |
| 175 | LOG((LOG_DISK,5,"%s S':0 → Q:1\n", jkff_name)); |
| 176 | 176 | } |
| 177 | 177 | break; |
| 178 | 178 | case 0: |
| 179 | 179 | default: |
| 180 | 180 | /* unstable state (what to do?) */ |
| 181 | 181 | s1 = s1 | JKFF_Q | JKFF_Q0; |
| 182 | | LOG((LOG_DISK,5,"%s C':0 S':0 -> Q:1 and Q':1 <unstable>\n", jkff_name)); |
| 182 | LOG((LOG_DISK,5,"%s C':0 S':0 → Q:1 and Q':1 <unstable>\n", jkff_name)); |
| 183 | 183 | break; |
| 184 | 184 | } |
| 185 | 185 | return s1; |
| r26136 | r26137 | |
| 767 | 767 | 0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f |
| 768 | 768 | } |
| 769 | 769 | }; |
| 770 | #endif |
| 770 | 771 | |
| 771 | | |
| 772 | | /** @brief just ignore debug arguments with the lookup table */ |
| 773 | | #define DEBUG_NAME(name) |
| 774 | | |
| 775 | | /** @brief lookup JK flip-flop state change from s0 to s1 */ |
| 776 | | #define update_jkff(s0,s1) static_cast<jkff_t>(jkff_lookup[(s1)&63][(s0)&63]) |
| 777 | | |
| 772 | jkff_t alto2_cpu_device::update_jkff(UINT8 s0, UINT8 s1) |
| 773 | { |
| 774 | UINT8 result = jkff_lookup[s1 & 63][ s0 & 63]; |
| 775 | #if ALTO2_DEBUG |
| 776 | LOG((LOG_DISK,8,"%s : ", jkff_name)); |
| 777 | if ((s0 ^ result) & JKFF_CLK) |
| 778 | LOG((LOG_DISK,8," CLK:%d→%d", s0 & 1, result & 1)); |
| 779 | if ((s0 ^ result) & JKFF_J) |
| 780 | LOG((LOG_DISK,8," J:%d→%d", (s0 >> 1) & 1, (result >> 1) & 1)); |
| 781 | if ((s0 ^ result) & JKFF_K) |
| 782 | LOG((LOG_DISK,8," K:%d→%d", (s0 >> 2) & 1, (result >> 2) & 1)); |
| 783 | if ((s0 ^ result) & JKFF_S) |
| 784 | LOG((LOG_DISK,8," S:%d→%d", (s0 >> 3) & 1, (result >> 3) & 1)); |
| 785 | if ((s0 ^ result) & JKFF_C) |
| 786 | LOG((LOG_DISK,8," C:%d→%d", (s0 >> 4) & 1, (result >> 4) & 1)); |
| 787 | if ((s0 ^ result) & JKFF_Q) |
| 788 | LOG((LOG_DISK,8," Q:%d→%d", (s0 >> 5) & 1, (result >> 5) & 1)); |
| 789 | if ((s0 ^ result) & JKFF_Q0) |
| 790 | LOG((LOG_DISK,8," Q':%d→%d", (s0 >> 6) & 1, (result >> 6) & 1)); |
| 791 | LOG((LOG_DISK,8,"\n")); |
| 778 | 792 | #endif |
| 793 | return static_cast<jkff_t>(result); |
| 794 | } |
| 779 | 795 | |
| 780 | 796 | /** |
| 781 | 797 | * <PRE> |
| r26136 | r26137 | |
| 1037 | 1053 | |
| 1038 | 1054 | diablo_hd_device* dhd = m_drive[m_dsk.drive]; |
| 1039 | 1055 | if (!dhd) { |
| 1056 | LOG((LOG_DISK,3," unit #%d\n", m_dsk.drive)); |
| 1040 | 1057 | // FIXME: set all signals for a not connected drive |
| 1041 | 1058 | return; |
| 1042 | 1059 | } |
| r26136 | r26137 | |
| 1092 | 1109 | } |
| 1093 | 1110 | |
| 1094 | 1111 | if (wddone0 != wddone1) { |
| 1095 | | LOG((LOG_DISK,2," WDDONE':%d->%d\n", wddone0, wddone1)); |
| 1112 | LOG((LOG_DISK,2," WDDONE':%d→%d\n", wddone0, wddone1)); |
| 1096 | 1113 | } |
| 1097 | 1114 | |
| 1098 | 1115 | if (m_dsk.carry) { |
| r26136 | r26137 | |
| 1142 | 1159 | for (i = 0; i < 4; i++) { |
| 1143 | 1160 | |
| 1144 | 1161 | if (m_sysclka0[i] != m_sysclka1[i]) { |
| 1145 | | LOG((LOG_DISK,7," SYSCLKA':%d->%d\n", m_sysclka0[i], m_sysclka1[i])); |
| 1162 | LOG((LOG_DISK,7," SYSCLKA' : %d→%d\n", m_sysclka0[i], m_sysclka1[i])); |
| 1146 | 1163 | } |
| 1147 | 1164 | if (m_sysclkb0[i] != m_sysclkb1[i]) { |
| 1148 | | LOG((LOG_DISK,7," SYSCLKB':%d->%d\n", m_sysclkb0[i], m_sysclkb1[i])); |
| 1165 | LOG((LOG_DISK,7," SYSCLKB' : %d→%d\n", m_sysclkb0[i], m_sysclkb1[i])); |
| 1149 | 1166 | } |
| 1150 | 1167 | |
| 1151 | 1168 | /** |
| r26136 | r26137 | |
| 1234 | 1251 | s1 |= JKFF_K; |
| 1235 | 1252 | s1 |= JKFF_S; |
| 1236 | 1253 | s1 |= JKFF_C; // FIXME: CLRSTAT' ? |
| 1237 | | |
| 1238 | 1254 | m_dsk.ff_45a = update_jkff(s0, s1); |
| 1239 | 1255 | |
| 1240 | 1256 | /** |
| r26136 | r26137 | |
| 1635 | 1651 | r = m_dsk.kstat; |
| 1636 | 1652 | |
| 1637 | 1653 | LOG((LOG_DISK,1," ←KSTAT; BUS &= %#o\n", r)); |
| 1638 | | LOG((LOG_DISK,2," sector: %d\n", GET_KSTAT_SECTOR(m_dsk.kstat))); |
| 1639 | | LOG((LOG_DISK,2," done: %d\n", GET_KSTAT_DONE(m_dsk.kstat))); |
| 1640 | | LOG((LOG_DISK,2," seekfail: %d\n", GET_KSTAT_SEEKFAIL(m_dsk.kstat))); |
| 1641 | | LOG((LOG_DISK,2," seek: %d\n", GET_KSTAT_SEEK(m_dsk.kstat))); |
| 1642 | | LOG((LOG_DISK,2," notrdy: %d\n", GET_KSTAT_NOTRDY(m_dsk.kstat))); |
| 1643 | | LOG((LOG_DISK,2," datalate: %d\n", GET_KSTAT_DATALATE(m_dsk.kstat))); |
| 1644 | | LOG((LOG_DISK,2," idle: %d\n", GET_KSTAT_IDLE(m_dsk.kstat))); |
| 1645 | | LOG((LOG_DISK,2," cksum: %d\n", GET_KSTAT_CKSUM(m_dsk.kstat))); |
| 1646 | | LOG((LOG_DISK,2," completion:%d\n", GET_KSTAT_COMPLETION(m_dsk.kstat))); |
| 1654 | LOG((LOG_DISK,2," sector : %#o\n", GET_KSTAT_SECTOR(m_dsk.kstat))); |
| 1655 | LOG((LOG_DISK,2," done : %#o\n", GET_KSTAT_DONE(m_dsk.kstat))); |
| 1656 | LOG((LOG_DISK,2," seekfail : %#o\n", GET_KSTAT_SEEKFAIL(m_dsk.kstat))); |
| 1657 | LOG((LOG_DISK,2," seek : %#o\n", GET_KSTAT_SEEK(m_dsk.kstat))); |
| 1658 | LOG((LOG_DISK,2," notrdy : %#o\n", GET_KSTAT_NOTRDY(m_dsk.kstat))); |
| 1659 | LOG((LOG_DISK,2," datalate : %#o\n", GET_KSTAT_DATALATE(m_dsk.kstat))); |
| 1660 | LOG((LOG_DISK,2," idle : %#o\n", GET_KSTAT_IDLE(m_dsk.kstat))); |
| 1661 | LOG((LOG_DISK,2," cksum : %#o\n", GET_KSTAT_CKSUM(m_dsk.kstat))); |
| 1662 | LOG((LOG_DISK,2," completion : %#o\n", GET_KSTAT_COMPLETION(m_dsk.kstat))); |
| 1647 | 1663 | |
| 1648 | 1664 | m_bus &= r; |
| 1649 | 1665 | } |
| r26136 | r26137 | |
| 1700 | 1716 | { |
| 1701 | 1717 | int i; |
| 1702 | 1718 | LOG((LOG_DISK,1," KSTAT←; BUS[12-15] %#o\n", m_bus)); |
| 1703 | | LOG((LOG_DISK,2," idle: %d\n", GET_KSTAT_IDLE(m_bus))); |
| 1704 | | LOG((LOG_DISK,2," cksum: %d\n", GET_KSTAT_CKSUM(m_bus))); |
| 1705 | | LOG((LOG_DISK,2," completion:%d\n", GET_KSTAT_COMPLETION(m_bus))); |
| 1719 | LOG((LOG_DISK,2," idle : %#o\n", GET_KSTAT_IDLE(m_bus))); |
| 1720 | LOG((LOG_DISK,2," cksum : %#o\n", GET_KSTAT_CKSUM(m_bus))); |
| 1721 | LOG((LOG_DISK,2," completion : %#o\n", GET_KSTAT_COMPLETION(m_bus))); |
| 1706 | 1722 | |
| 1707 | 1723 | /* KSTAT[12] is just taken from BUS[12] */ |
| 1708 | 1724 | PUT_KSTAT_IDLE(m_dsk.kstat, GET_KSTAT_IDLE(m_bus)); |
| r26136 | r26137 | |
| 1817 | 1833 | case RECNO_HEADER: |
| 1818 | 1834 | m_dsk.krecno = RECNO_LABEL; |
| 1819 | 1835 | m_dsk.krwc = GET_KADR_LABEL(m_dsk.kadr); |
| 1820 | | LOG((LOG_DISK,2," INCRECNO; HEADER -> LABEL (%o, rwc:%o)\n", |
| 1821 | | m_dsk.krecno, m_dsk.krwc)); |
| 1836 | LOG((LOG_DISK,2," INCRECNO; HEADER → LABEL (%o, rwc:%o)\n", m_dsk.krecno, m_dsk.krwc)); |
| 1822 | 1837 | break; |
| 1823 | 1838 | case RECNO_PAGENO: |
| 1824 | 1839 | m_dsk.krecno = RECNO_HEADER; |
| 1825 | 1840 | m_dsk.krwc = GET_KADR_HEADER(m_dsk.kadr); |
| 1826 | | LOG((LOG_DISK,2," INCRECNO; PAGENO -> HEADER (%o, rwc:%o)\n", |
| 1827 | | m_dsk.krecno, m_dsk.krwc)); |
| 1841 | LOG((LOG_DISK,2," INCRECNO; PAGENO → HEADER (%o, rwc:%o)\n", m_dsk.krecno, m_dsk.krwc)); |
| 1828 | 1842 | break; |
| 1829 | 1843 | case RECNO_LABEL: |
| 1830 | 1844 | m_dsk.krecno = RECNO_DATA; |
| 1831 | 1845 | m_dsk.krwc = GET_KADR_DATA(m_dsk.kadr); |
| 1832 | | LOG((LOG_DISK,2," INCRECNO; LABEL -> DATA (%o, rwc:%o)\n", |
| 1833 | | m_dsk.krecno, m_dsk.krwc)); |
| 1846 | LOG((LOG_DISK,2," INCRECNO; LABEL → DATA (%o, rwc:%o)\n", m_dsk.krecno, m_dsk.krwc)); |
| 1834 | 1847 | break; |
| 1835 | 1848 | case RECNO_DATA: |
| 1836 | 1849 | m_dsk.krecno = RECNO_PAGENO; |
| 1837 | 1850 | m_dsk.krwc = 0; /* read (?) */ |
| 1838 | | LOG((LOG_DISK,2," INCRECNO; DATA -> PAGENO (%o, rwc:%o)\n", |
| 1839 | | m_dsk.krecno, m_dsk.krwc)); |
| 1851 | LOG((LOG_DISK,2," INCRECNO; DATA → PAGENO (%o, rwc:%o)\n", m_dsk.krecno, m_dsk.krwc)); |
| 1840 | 1852 | break; |
| 1841 | 1853 | } |
| 1842 | 1854 | // TODO: show disk indicator |
| r26136 | r26137 | |
| 1854 | 1866 | { |
| 1855 | 1867 | diablo_hd_device* dhd = m_drive[m_dsk.drive]; |
| 1856 | 1868 | LOG((LOG_DISK,1," CLRSTAT\n")); |
| 1869 | UINT8 s0, s1; |
| 1857 | 1870 | |
| 1858 | 1871 | /* clears the LAI clocked flip-flop 44a |
| 1859 | 1872 | * JK flip-flop 44a (LAI' clocked) |
| r26136 | r26137 | |
| 1865 | 1878 | * Q to seekok |
| 1866 | 1879 | */ |
| 1867 | 1880 | DEBUG_NAME(" LAI 44a"); |
| 1868 | | m_dsk.ff_44a = update_jkff(m_dsk.ff_44a, |
| 1869 | | (m_dsk.ff_44a & JKFF_CLK) | |
| 1870 | | JKFF_J | |
| 1871 | | JKFF_K | |
| 1872 | | JKFF_S | |
| 1873 | | 0); |
| 1881 | s0 = m_dsk.ff_44a; |
| 1882 | s1 = m_dsk.ff_44a & JKFF_CLK; |
| 1883 | s1 |= JKFF_J; |
| 1884 | s1 |= JKFF_K; |
| 1885 | s1 |= JKFF_S; |
| 1886 | m_dsk.ff_44a = update_jkff(s0, s1); |
| 1874 | 1887 | |
| 1875 | 1888 | /* clears the CKSUM flip-flop 44b |
| 1876 | 1889 | * JK flip-flop 44b (KSTAT← clocked) |
| r26136 | r26137 | |
| 1882 | 1895 | * Q to seekok |
| 1883 | 1896 | */ |
| 1884 | 1897 | DEBUG_NAME(" CKSUM 44b"); |
| 1885 | | m_dsk.ff_44b = update_jkff(m_dsk.ff_44b, |
| 1886 | | (m_dsk.ff_44b & JKFF_CLK) | |
| 1887 | | (m_dsk.ff_44b & JKFF_J) | |
| 1888 | | JKFF_K | |
| 1889 | | JKFF_S | |
| 1890 | | 0); |
| 1898 | s0 = m_dsk.ff_44b; |
| 1899 | s1 = m_dsk.ff_44b & JKFF_CLK; |
| 1900 | s1 |= m_dsk.ff_44b & JKFF_J; |
| 1901 | s1 |= JKFF_K; |
| 1902 | s1 |= JKFF_S; |
| 1903 | m_dsk.ff_44b = update_jkff(s0, s1); |
| 1891 | 1904 | |
| 1892 | 1905 | /* clears the rdylat flip-flop 45a |
| 1893 | 1906 | * JK flip-flop 45a (ready latch) |
| r26136 | r26137 | |
| 1899 | 1912 | * Q RDYLAT' |
| 1900 | 1913 | */ |
| 1901 | 1914 | DEBUG_NAME(" RDYLAT 45a"); |
| 1902 | | m_dsk.ff_45a = update_jkff(m_dsk.ff_45a, |
| 1903 | | (m_dsk.ff_45a & JKFF_CLK) | |
| 1904 | | (dhd ? dhd->get_ready_0() : 1) | |
| 1905 | | JKFF_K | |
| 1906 | | JKFF_S | |
| 1907 | | 0); |
| 1915 | s0 = m_dsk.ff_45a; |
| 1916 | s1 = m_dsk.ff_45a & JKFF_CLK; |
| 1917 | if (dhd) |
| 1918 | s1 |= dhd->get_ready_0() ? JKFF_J : 0; |
| 1919 | else |
| 1920 | s1 |= JKFF_J; |
| 1921 | s1 |= JKFF_K; |
| 1922 | s1 |= JKFF_S; |
| 1923 | m_dsk.ff_45a = update_jkff(s0, s1); |
| 1908 | 1924 | |
| 1909 | 1925 | /* sets the seqerr flip-flop 45b (Q' is SEQERR) |
| 1910 | 1926 | * JK flip-flop 45b (seqerr latch) |
| r26136 | r26137 | |
| 1916 | 1932 | * Q to KSTAT[11] DATALATE |
| 1917 | 1933 | */ |
| 1918 | 1934 | DEBUG_NAME(" SEQERR 45b"); |
| 1919 | | m_dsk.ff_45b = update_jkff(m_dsk.ff_45b, |
| 1920 | | (m_dsk.ff_45b & JKFF_CLK) | |
| 1921 | | JKFF_J | |
| 1922 | | (m_dsk.ff_45b & JKFF_K) | |
| 1923 | | 0 | |
| 1924 | | JKFF_C); |
| 1935 | s0 = m_dsk.ff_45b; |
| 1936 | s1 = m_dsk.ff_45b & JKFF_CLK; |
| 1937 | s1 |= JKFF_J; |
| 1938 | s1 |= m_dsk.ff_45b & JKFF_K; |
| 1939 | s1 |= JKFF_C; |
| 1940 | m_dsk.ff_45b = update_jkff(s0, s1); |
| 1925 | 1941 | |
| 1926 | 1942 | /* set or reset monoflop 31a, depending on drive READY' */ |
| 1927 | 1943 | m_dsk.ready_mf31a = dhd ? dhd->get_ready_0() : 1; |
| r26136 | r26137 | |
| 1954 | 1970 | if (m_dsk.kcom != m_bus) { |
| 1955 | 1971 | m_dsk.kcom = m_bus; |
| 1956 | 1972 | LOG((LOG_DISK,2," KCOM←; BUS %06o\n", m_dsk.kcom)); |
| 1957 | | LOG((LOG_DISK,2," xferoff: %d\n", GET_KCOM_XFEROFF(m_dsk.kcom))); |
| 1958 | | LOG((LOG_DISK,2," wdinhib: %d\n", GET_KCOM_WDINHIB(m_dsk.kcom))); |
| 1959 | | LOG((LOG_DISK,2," bclksrc: %d\n", GET_KCOM_BCLKSRC(m_dsk.kcom))); |
| 1960 | | LOG((LOG_DISK,2," wffo: %d\n", GET_KCOM_WFFO(m_dsk.kcom))); |
| 1961 | | LOG((LOG_DISK,2," sendadr: %d\n", GET_KCOM_SENDADR(m_dsk.kcom))); |
| 1973 | LOG((LOG_DISK,2," xferoff : %#o\n", GET_KCOM_XFEROFF(m_dsk.kcom))); |
| 1974 | LOG((LOG_DISK,2," wdinhib : %#o\n", GET_KCOM_WDINHIB(m_dsk.kcom))); |
| 1975 | LOG((LOG_DISK,2," bclksrc : %#o\n", GET_KCOM_BCLKSRC(m_dsk.kcom))); |
| 1976 | LOG((LOG_DISK,2," wffo : %#o\n", GET_KCOM_WFFO(m_dsk.kcom))); |
| 1977 | LOG((LOG_DISK,2," sendadr : %#o\n", GET_KCOM_SENDADR(m_dsk.kcom))); |
| 1962 | 1978 | |
| 1963 | | // TODO: show disk indicator |
| 1979 | // TODO: show disk indicator in the GUI? |
| 1964 | 1980 | } |
| 1965 | 1981 | } |
| 1966 | 1982 | |
| r26136 | r26137 | |
| 2001 | 2017 | m_dsk.krwc = GET_KADR_HEADER(m_dsk.kadr); |
| 2002 | 2018 | |
| 2003 | 2019 | LOG((LOG_DISK,1," KADR←; BUS[8-14] #%o\n", m_dsk.kadr)); |
| 2004 | | LOG((LOG_DISK,2," seal: %#o\n", GET_KADR_SEAL(m_dsk.kadr))); |
| 2005 | | LOG((LOG_DISK,2," header: %s\n", rwc_name[GET_KADR_HEADER(m_dsk.kadr)])); |
| 2006 | | LOG((LOG_DISK,2," label: %s\n", rwc_name[GET_KADR_LABEL(m_dsk.kadr)])); |
| 2007 | | LOG((LOG_DISK,2," data: %s\n", rwc_name[GET_KADR_DATA(m_dsk.kadr)])); |
| 2008 | | LOG((LOG_DISK,2," noxfer: %d\n", GET_KADR_NOXFER(m_dsk.kadr))); |
| 2009 | | LOG((LOG_DISK,2," unused: %d (drive?)\n", GET_KADR_UNUSED(m_dsk.kadr))); |
| 2020 | LOG((LOG_DISK,2," seal : %#o\n", GET_KADR_SEAL(m_dsk.kadr))); |
| 2021 | LOG((LOG_DISK,2," header : %s (%#o)\n", rwc_name[GET_KADR_HEADER(m_dsk.kadr)], GET_KADR_HEADER(m_dsk.kadr))); |
| 2022 | LOG((LOG_DISK,2," label : %s (%#o)\n", rwc_name[GET_KADR_LABEL(m_dsk.kadr)], GET_KADR_LABEL(m_dsk.kadr))); |
| 2023 | LOG((LOG_DISK,2," data : %s (%#o)\n", rwc_name[GET_KADR_DATA(m_dsk.kadr)], GET_KADR_DATA(m_dsk.kadr))); |
| 2024 | LOG((LOG_DISK,2," noxfer : %#o\n", GET_KADR_NOXFER(m_dsk.kadr))); |
| 2025 | LOG((LOG_DISK,2," unused : %#o (drive?)\n", GET_KADR_UNUSED(m_dsk.kadr))); |
| 2010 | 2026 | |
| 2011 | | // TODO: show disk indicator |
| 2027 | // TODO: show disk indicator in the GUI? |
| 2012 | 2028 | } |
| 2013 | 2029 | |
| 2014 | 2030 | /** |
| r26136 | r26137 | |
| 2248 | 2264 | void alto2_cpu_device::next_sector(int unit) |
| 2249 | 2265 | { |
| 2250 | 2266 | diablo_hd_device* dhd = m_drive[unit]; |
| 2267 | LOG((LOG_DISK,0,"%s dhd=%p\n", __FUNCTION__, dhd)); |
| 2251 | 2268 | if (m_dsk.bitclk_timer) { |
| 2252 | 2269 | LOG((LOG_DISK,0," unit #%d stop bitclk\n", m_dsk.bitclk)); |
| 2253 | 2270 | m_dsk.bitclk_timer->enable(false); |
| r26136 | r26137 | |
| 2286 | 2303 | */ |
| 2287 | 2304 | void alto2_cpu_device::init_disk() |
| 2288 | 2305 | { |
| 2289 | | diablo_hd_device* dhd; |
| 2290 | | for (int unit = 0; unit < 2; unit++) { |
| 2291 | | dhd = m_drive[unit]; |
| 2292 | | if (!dhd) |
| 2293 | | continue; |
| 2294 | | dhd->set_sector_callback(this, &disk_sector_start); |
| 2295 | | } |
| 2296 | | |
| 2297 | 2306 | memset(&m_dsk, 0, sizeof(m_dsk)); |
| 2298 | 2307 | |
| 2299 | 2308 | /** @brief simulate previous sysclka */ |
| r26136 | r26137 | |
| 2334 | 2343 | m_dsk.ok_to_run_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(alto2_cpu_device::disk_ok_to_run),this)); |
| 2335 | 2344 | m_dsk.ok_to_run_timer->set_param(1); |
| 2336 | 2345 | m_dsk.ok_to_run_timer->adjust(attotime::from_nsec(15 * ALTO2_UCYCLE), 1); |
| 2346 | |
| 2347 | diablo_hd_device* dhd; |
| 2348 | for (int unit = 0; unit < diablo_hd_device::DIABLO_UNIT_MAX; unit++) { |
| 2349 | dhd = m_drive[unit]; |
| 2350 | if (!dhd) |
| 2351 | continue; |
| 2352 | dhd->set_sector_callback(this, &disk_sector_start); |
| 2353 | } |
| 2337 | 2354 | } |
| 2338 | 2355 | |