branches/alto2/src/emu/cpu/alto2/a2emu.c
| r26301 | r26302 | |
| 58 | 58 | * - - - - - - - - - - - - - 1 1 0 SEZ skip if either result is zero |
| 59 | 59 | * - - - - - - - - - - - - - 1 1 1 SBN skip if both results are non-zero |
| 60 | 60 | */ |
| 61 | | #define IR_ARITH(ir) A2_GET16(ir,16, 0, 0) |
| 62 | | #define IR_SrcAC(ir) A2_GET16(ir,16, 1, 2) |
| 63 | | #define IR_DstAC(ir) A2_GET16(ir,16, 3, 4) |
| 64 | | #define IR_AFunc(ir) A2_GET16(ir,16, 5, 7) |
| 65 | | #define IR_SH(ir) A2_GET16(ir,16, 8, 9) |
| 66 | | #define IR_CY(ir) A2_GET16(ir,16,10,11) |
| 67 | | #define IR_NL(ir) A2_GET16(ir,16,12,12) |
| 68 | | #define IR_SK(ir) A2_GET16(ir,16,13,15) |
| 61 | #define IR_ARITH(ir) X_RDBITS(ir,16, 0, 0) |
| 62 | #define IR_SrcAC(ir) X_RDBITS(ir,16, 1, 2) |
| 63 | #define IR_DstAC(ir) X_RDBITS(ir,16, 3, 4) |
| 64 | #define IR_AFunc(ir) X_RDBITS(ir,16, 5, 7) |
| 65 | #define IR_SH(ir) X_RDBITS(ir,16, 8, 9) |
| 66 | #define IR_CY(ir) X_RDBITS(ir,16,10,11) |
| 67 | #define IR_NL(ir) X_RDBITS(ir,16,12,12) |
| 68 | #define IR_SK(ir) X_RDBITS(ir,16,13,15) |
| 69 | 69 | |
| 70 | | #define IR_MFunc(ir) A2_GET16(ir,16, 1, 2) |
| 71 | | #define IR_JFunc(ir) A2_GET16(ir,16, 3, 4) |
| 72 | | #define IR_I(ir) A2_GET16(ir,16, 5, 5) |
| 73 | | #define IR_X(ir) A2_GET16(ir,16, 6, 7) |
| 74 | | #define IR_DISP(ir) A2_GET16(ir,16, 8,15) |
| 75 | | #define IR_AUGFUNC(ir) A2_GET16(ir,16, 3, 7) |
| 70 | #define IR_MFunc(ir) X_RDBITS(ir,16, 1, 2) |
| 71 | #define IR_JFunc(ir) X_RDBITS(ir,16, 3, 4) |
| 72 | #define IR_I(ir) X_RDBITS(ir,16, 5, 5) |
| 73 | #define IR_X(ir) X_RDBITS(ir,16, 6, 7) |
| 74 | #define IR_DISP(ir) X_RDBITS(ir,16, 8,15) |
| 75 | #define IR_AUGFUNC(ir) X_RDBITS(ir,16, 3, 7) |
| 76 | 76 | |
| 77 | 77 | #define op_MFUNC_MASK 0060000 //!< instruction register memory function mask |
| 78 | 78 | #define op_MFUNC_JUMP 0000000 //!< jump functions value |
| r26301 | r26302 | |
| 287 | 287 | "%s-%04o: r:%02o af:%02o bs:%02o f1:%02o f2:%02o" \ |
| 288 | 288 | " t:%o l:%o next:%05o next2:%05o cycle:%lld\n", |
| 289 | 289 | task_name(m_task), m_mpc, |
| 290 | | m_rsel, MIR_ALUF, MIR_BS, |
| 291 | | MIR_F1, MIR_F2, |
| 292 | | MIR_T, MIR_L, |
| 293 | | MIR_NEXT, m_next2, |
| 290 | m_rsel, m_daluf, m_dbs, m_df1, mdf2, |
| 291 | m_dloadt, m_dloatl, m_next, m_next2, |
| 294 | 292 | ntime() / CPU_MICROCYCLE_TIME); |
| 295 | 293 | #else |
| 296 | 294 | /* just ignore (?) */ |
| r26301 | r26302 | |
| 312 | 310 | void alto2_cpu_device::f1_late_emu_load_esrb() |
| 313 | 311 | { |
| 314 | 312 | LOG((LOG_EMU,2," ESRB←; BUS[12-14] (%#o)\n", m_bus)); |
| 315 | | m_s_reg_bank[m_task] = A2_GET16(m_bus,16,12,14); |
| 313 | m_s_reg_bank[m_task] = X_RDBITS(m_bus,16,12,14); |
| 316 | 314 | } |
| 317 | 315 | |
| 318 | 316 | /** |
| r26301 | r26302 | |
| 359 | 357 | { |
| 360 | 358 | LOG((LOG_EMU,2," STARTF (BUS is %06o)\n", m_bus)); |
| 361 | 359 | /* TODO: what do we do here? reset the CPU on bit 0? */ |
| 362 | | if (A2_BIT32(m_bus,16,0)) { |
| 360 | if (X_BIT(m_bus,16,0)) { |
| 363 | 361 | LOG((LOG_EMU,2,"**** Software boot feature\n")); |
| 364 | 362 | soft_reset(); |
| 365 | 363 | } else { |
| r26301 | r26302 | |
| 377 | 375 | m_next2 |= r; |
| 378 | 376 | } |
| 379 | 377 | |
| 380 | | #if 1 |
| 381 | 378 | /** |
| 382 | | * @brief f2_magic late: shift and use T |
| 379 | * @brief f2_magic late: shift and use T[0] or T[15] |
| 383 | 380 | */ |
| 384 | 381 | void alto2_cpu_device::f2_late_magic() |
| 385 | 382 | { |
| 386 | 383 | int XC; |
| 387 | | switch (MIR_F1(m_mir)) { |
| 384 | switch (m_d_f1) { |
| 388 | 385 | case f1_l_lsh_1: // ←L MLSH 1 |
| 389 | 386 | XC = (m_t >> 15) & 1; |
| 390 | | m_shifter = (m_l << 1) & 0177777; |
| 391 | | m_shifter |= XC; |
| 387 | m_shifter = (m_l << 1) | XC; |
| 392 | 388 | LOG((LOG_EMU,2," ←L MLSH 1 (shifer:%06o XC:%o)", m_shifter, XC)); |
| 393 | 389 | break; |
| 394 | 390 | case f1_l_rsh_1: // ←L MRSH 1 |
| 395 | | XC = m_t & 1; |
| 396 | | m_shifter = m_l >> 1; |
| 397 | | m_shifter |= XC << 15; |
| 391 | XC = (m_t & 1) << 15; |
| 392 | m_shifter = (m_l >> 1) | XC; |
| 398 | 393 | LOG((LOG_EMU,2," ←L MRSH 1 (shifter:%06o XC:%o)", m_shifter, XC)); |
| 399 | 394 | break; |
| 400 | 395 | case f1_l_lcy_8: // ←L LCY 8 |
| 396 | m_shifter = (m_l >> 8) | (m_l << 8); |
| 397 | break; |
| 401 | 398 | default: // other |
| 399 | m_shifter = m_l; |
| 402 | 400 | break; |
| 403 | 401 | } |
| 404 | 402 | } |
| 405 | | #endif |
| 406 | 403 | |
| 407 | 404 | /** |
| 408 | 405 | * @brief dns early: modify RESELECT with DstAC = (3 - IR[3-4]) |
| r26301 | r26302 | |
| 410 | 407 | void alto2_cpu_device::f2_early_load_dns() |
| 411 | 408 | { |
| 412 | 409 | #if USE_SCHEMATICS_RSEL |
| 413 | | A2_PUT8(m_rsel, 5, 3, 3, RA3(f2_emu_load_dns, m_emu.ir, m_rsel)); |
| 414 | | A2_PUT8(m_rsel, 5, 4, 4, RA4(f2_emu_load_dns, m_emu.ir, m_rsel)); |
| 410 | X_WRBITS(m_rsel, 5, 3, 3, RA3(f2_emu_load_dns, m_emu.ir, m_rsel)); |
| 411 | X_WRBITS(m_rsel, 5, 4, 4, RA4(f2_emu_load_dns, m_emu.ir, m_rsel)); |
| 415 | 412 | #else |
| 416 | | A2_PUT8(m_rsel, 5, 3, 4, IR_DstAC(m_emu.ir) ^ 3); |
| 413 | X_WRBITS(m_rsel, 5, 3, 4, IR_DstAC(m_emu.ir) ^ 3); |
| 417 | 414 | #endif |
| 418 | 415 | LOG((LOG_EMU,2," DNS←; rsel := DstAC (%#o %s)\n", m_rsel, r_name(m_rsel))); |
| 419 | 416 | } |
| r26301 | r26302 | |
| 448 | 445 | */ |
| 449 | 446 | void alto2_cpu_device::f2_late_load_dns() |
| 450 | 447 | { |
| 451 | | UINT8 IR10 = A2_BIT16(m_emu.ir,16,10); |
| 452 | | UINT8 IR11 = A2_BIT16(m_emu.ir,16,11); |
| 453 | | UINT8 IR12 = A2_BIT16(m_emu.ir,16,12); |
| 454 | | UINT8 IR13 = A2_BIT16(m_emu.ir,16,13); |
| 455 | | UINT8 IR14 = A2_BIT16(m_emu.ir,16,14); |
| 456 | | UINT8 IR15 = A2_BIT16(m_emu.ir,16,15); |
| 448 | UINT8 IR10 = X_BIT(m_emu.ir,16,10); |
| 449 | UINT8 IR11 = X_BIT(m_emu.ir,16,11); |
| 450 | UINT8 IR12 = X_BIT(m_emu.ir,16,12); |
| 451 | UINT8 IR13 = X_BIT(m_emu.ir,16,13); |
| 452 | UINT8 IR14 = X_BIT(m_emu.ir,16,14); |
| 453 | UINT8 IR15 = X_BIT(m_emu.ir,16,15); |
| 457 | 454 | UINT8 exorB = IR11 ^ IR10; |
| 458 | 455 | UINT8 CARRY = m_emu.cy ^ 1; |
| 459 | 456 | UINT8 ORA = (exorB | CARRY) ^ 1; |
| r26301 | r26302 | |
| 465 | 462 | UINT8 DSKIP; |
| 466 | 463 | UINT8 SHZERO; |
| 467 | 464 | |
| 468 | | switch (MIR_F1(m_mir)) { |
| 465 | switch (m_d_f1) { |
| 469 | 466 | case f1_l_rsh_1: // ←L RSH 1 |
| 470 | 467 | NEWCARRY = m_l & 1; |
| 471 | 468 | m_shifter = ((m_l >> 1) | (XC << 15)) & 0177777; |
| r26301 | r26302 | |
| 477 | 474 | LOG((LOG_EMU,2," DNS; ←L LSH 1 (shifter:%06o XC:%o NEWCARRY:%o)", m_shifter, XC, NEWCARRY)); |
| 478 | 475 | break; |
| 479 | 476 | case f1_l_lcy_8: // ←L LCY 8 |
| 480 | | default: /* other */ |
| 481 | 477 | NEWCARRY = XC; |
| 478 | m_shifter = (m_l >> 8) | (m_l << 8); |
| 482 | 479 | LOG((LOG_EMU,2," DNS; (shifter:%06o NEWCARRY:%o)", m_shifter, NEWCARRY)); |
| 483 | 480 | break; |
| 481 | default: // other |
| 482 | NEWCARRY = XC; |
| 483 | m_shifter = m_l; |
| 484 | LOG((LOG_EMU,2," DNS; (shifter:%06o NEWCARRY:%o)", m_shifter, NEWCARRY)); |
| 485 | break; |
| 484 | 486 | } |
| 485 | 487 | SHZERO = (m_shifter == 0); |
| 486 | 488 | DCARRY = (((IR12 ^ 1) & NEWCARRY) | (IR12 & CARRY)) ^ 1; |
| r26301 | r26302 | |
| 504 | 506 | ALTO2_PUT(m_rsel, 5, 3, 3, RA3(f2_emu_acdest, m_emu.ir, m_rsel)); |
| 505 | 507 | ALTO2_PUT(m_rsel, 5, 4, 4, RA4(f2_emu_acdest, m_emu.ir, m_rsel)); |
| 506 | 508 | #else |
| 507 | | A2_PUT8(m_rsel, 5, 3, 4, IR_DstAC(m_emu.ir) ^ 3); |
| 509 | X_WRBITS(m_rsel, 5, 3, 4, IR_DstAC(m_emu.ir) ^ 3); |
| 508 | 510 | #endif |
| 509 | 511 | LOG((LOG_EMU,2," ACDEST←; mux (rsel:%#o %s)\n", m_rsel, r_name(m_rsel))); |
| 510 | 512 | } |
| r26301 | r26302 | |
| 519 | 521 | |
| 520 | 522 | LOG((LOG_EMU,3," BITBLT AC1:%06o AC2:%06o\n", m_r[rsel_ac1], m_r[rsel_ac2])); |
| 521 | 523 | LOG((LOG_EMU,3," function : %06o\n", val)); |
| 522 | | LOG((LOG_EMU,3," src extRAM: %o\n", A2_BIT16(val,16,10))); |
| 523 | | LOG((LOG_EMU,3," dst extRAM: %o\n", A2_BIT16(val,16,11))); |
| 524 | | LOG((LOG_EMU,3," src type : %o (%s)\n", A2_GET16(val,16,12,13), type_name[A2_GET16(val,16,12,13)])); |
| 525 | | LOG((LOG_EMU,3," operation : %o (%s)\n", A2_GET16(val,16,14,15), oper_name[A2_GET16(val,16,14,15)])); |
| 524 | LOG((LOG_EMU,3," src extRAM: %o\n", X_BIT(val,16,10))); |
| 525 | LOG((LOG_EMU,3," dst extRAM: %o\n", X_BIT(val,16,11))); |
| 526 | LOG((LOG_EMU,3," src type : %o (%s)\n", X_RDBITS(val,16,12,13), type_name[X_RDBITS(val,16,12,13)])); |
| 527 | LOG((LOG_EMU,3," operation : %o (%s)\n", X_RDBITS(val,16,14,15), oper_name[X_RDBITS(val,16,14,15)])); |
| 526 | 528 | val = debug_read_mem(bbt+1); |
| 527 | 529 | LOG((LOG_EMU,3," unused AC2: %06o (%d)\n", val, val)); |
| 528 | 530 | val = debug_read_mem(bbt+2); |
| r26301 | r26302 | |
| 558 | 560 | */ |
| 559 | 561 | void alto2_cpu_device::f2_late_load_ir() |
| 560 | 562 | { |
| 561 | | UINT16 r = (A2_BIT16(m_bus,16,0) << 3) | A2_GET16(m_bus,16,5,7); |
| 563 | UINT16 r = (X_BIT(m_bus,16,0) << 3) | X_RDBITS(m_bus,16,5,7); |
| 562 | 564 | |
| 563 | 565 | /* special logging of some opcodes */ |
| 564 | 566 | switch (m_bus) { |
| r26301 | r26302 | |
| 630 | 632 | r = IR_SH(m_emu.ir) ^ 3; /* complement of SH */ |
| 631 | 633 | LOG((LOG_EMU,2," IDISP←; branch on SH^3 (%#o|%#o)\n", m_next2, r)); |
| 632 | 634 | } else { |
| 633 | | int addr = CTL2K_U3(f2_emu_idisp) + A2_GET16(m_emu.ir,16,1,7); |
| 635 | int addr = CTL2K_U3(f2_emu_idisp) + X_RDBITS(m_emu.ir,16,1,7); |
| 634 | 636 | /* 0???????xxxxxxxx */ |
| 635 | 637 | r = m_ctl2k_u3[addr]; |
| 636 | 638 | LOG((LOG_EMU,2," IDISP←; IR (%#o) branch on PROM ctl2k_u3[%03o] (%#o|%#o)\n", m_emu.ir, addr, m_next2, r)); |
| r26301 | r26302 | |
| 644 | 646 | void alto2_cpu_device::f2_early_acsource() |
| 645 | 647 | { |
| 646 | 648 | #if USE_SCHEMATICS_RSEL |
| 647 | | A2_PUT8(m_rsel, 5, 3, 3, RA3(f2_emu_acsource, m_emu.ir, m_rsel)); |
| 648 | | A2_PUT8(m_rsel, 5, 4, 4, RA4(f2_emu_acsource, m_emu.ir, m_rsel)); |
| 649 | X_WRBITS(m_rsel, 5, 3, 3, RA3(f2_emu_acsource, m_emu.ir, m_rsel)); |
| 650 | X_WRBITS(m_rsel, 5, 4, 4, RA4(f2_emu_acsource, m_emu.ir, m_rsel)); |
| 649 | 651 | #else |
| 650 | | A2_PUT8(m_rsel, 5, 3, 4, IR_SrcAC(m_emu.ir) ^ 3); |
| 652 | X_WRBITS(m_rsel, 5, 3, 4, IR_SrcAC(m_emu.ir) ^ 3); |
| 651 | 653 | #endif |
| 652 | 654 | LOG((LOG_EMU,2," ←ACSOURCE; rsel := SrcAC (%#o %s)\n", m_rsel, r_name(m_rsel))); |
| 653 | 655 | } |
| r26301 | r26302 | |
| 664 | 666 | r = IR_SH(m_emu.ir) ^ 3; /* complement of SH */ |
| 665 | 667 | LOG((LOG_EMU,2," ←ACSOURCE; branch on SH^3 (%#o|%#o)\n", m_next2, r)); |
| 666 | 668 | } else { |
| 667 | | int addr = CTL2K_U3(f2_emu_acsource) + A2_GET16(m_emu.ir,16,1,7); |
| 669 | int addr = CTL2K_U3(f2_emu_acsource) + X_RDBITS(m_emu.ir,16,1,7); |
| 668 | 670 | /* 0???????xxxxxxxx */ |
| 669 | 671 | r = m_ctl2k_u3[addr]; |
| 670 | 672 | LOG((LOG_EMU,2," ←ACSOURCE; branch on PROM ctl2k_u3[%03o] (%#o|%#o)\n", addr, m_next2, r)); |
branches/alto2/src/emu/cpu/alto2/a2disk.c
| r26301 | r26302 | |
| 12 | 12 | |
| 13 | 13 | #define JKFF_FUNCTION 0 //!< define 1 to debug the JK flip-flops, 0 to use a lookup table |
| 14 | 14 | |
| 15 | | #define GET_KADDR_SECTOR(kaddr) A2_GET16(kaddr,16, 0, 3) //!< get sector number from address register |
| 16 | | #define PUT_KADDR_SECTOR(kaddr,val) A2_PUT16(kaddr,16, 0, 3,val) //!< put sector number into address register |
| 17 | | #define GET_KADDR_CYLINDER(kaddr) A2_GET16(kaddr,16, 4,12) //!< get cylinder number from address register |
| 18 | | #define PUT_KADDR_CYLINDER(kaddr,val) A2_PUT16(kaddr,16, 4,12,val) //!< put cylinder number int address register |
| 19 | | #define GET_KADDR_HEAD(kaddr) A2_GET16(kaddr,16,13,13) //!< get head number from address register |
| 20 | | #define PUT_KADDR_HEAD(kaddr,val) A2_PUT16(kaddr,16,13,13,val) //!< put head number into address register |
| 21 | | #define GET_KADDR_DRIVE(kaddr) A2_GET16(kaddr,16,14,14) //!< get drive (unit) number from address register |
| 22 | | #define PUT_KADDR_DRIVE(kaddr,val) A2_PUT16(kaddr,16,14,14,val) //!< put drive (unit) number into address register |
| 23 | | #define GET_KADDR_RESTORE(kaddr) A2_GET16(kaddr,16,15,15) //!< get restore flag from address register |
| 24 | | #define PUT_KADDR_RESTORE(kaddr,val) A2_PUT16(kaddr,16,15,15,val) //!< putt restore flag into address register |
| 15 | #define GET_KADDR_SECTOR(kaddr) X_RDBITS(kaddr,16, 0, 3) //!< get sector number from address register |
| 16 | #define PUT_KADDR_SECTOR(kaddr,val) X_WRBITS(kaddr,16, 0, 3,val) //!< put sector number into address register |
| 17 | #define GET_KADDR_CYLINDER(kaddr) X_RDBITS(kaddr,16, 4,12) //!< get cylinder number from address register |
| 18 | #define PUT_KADDR_CYLINDER(kaddr,val) X_WRBITS(kaddr,16, 4,12,val) //!< put cylinder number int address register |
| 19 | #define GET_KADDR_HEAD(kaddr) X_RDBITS(kaddr,16,13,13) //!< get head number from address register |
| 20 | #define PUT_KADDR_HEAD(kaddr,val) X_WRBITS(kaddr,16,13,13,val) //!< put head number into address register |
| 21 | #define GET_KADDR_DRIVE(kaddr) X_RDBITS(kaddr,16,14,14) //!< get drive (unit) number from address register |
| 22 | #define PUT_KADDR_DRIVE(kaddr,val) X_WRBITS(kaddr,16,14,14,val) //!< put drive (unit) number into address register |
| 23 | #define GET_KADDR_RESTORE(kaddr) X_RDBITS(kaddr,16,15,15) //!< get restore flag from address register |
| 24 | #define PUT_KADDR_RESTORE(kaddr,val) X_WRBITS(kaddr,16,15,15,val) //!< putt restore flag into address register |
| 25 | 25 | |
| 26 | | #define GET_KADR_SEAL(kadr) A2_GET16(kadr,16, 0, 7) //!< get command seal from command register |
| 27 | | #define PUT_KADR_SEAL(kadr,val) A2_PUT16(kadr,16, 0, 7,val) //!< put command seal into command register |
| 28 | | #define GET_KADR_HEADER(kadr) A2_GET16(kadr,16, 8, 9) //!< get r/w/c for header from command register |
| 29 | | #define PUT_KADR_HEADER(kadr,val) A2_PUT16(kadr,16, 8, 9,val) //!< put r/w/c for header from command register |
| 30 | | #define GET_KADR_LABEL(kadr) A2_GET16(kadr,16,10,11) //!< get r/w/c for label from command register |
| 31 | | #define PUT_KADR_LABEL(kadr,val) A2_PUT16(kadr,16,10,11,val) //!< put r/w/c for label into command register |
| 32 | | #define GET_KADR_DATA(kadr) A2_GET16(kadr,16,12,13) //!< get r/w/c for data from command register |
| 33 | | #define PUT_KADR_DATA(kadr,val) A2_PUT16(kadr,16,12,13,val) //!< put r/w/c for data into command register |
| 34 | | #define GET_KADR_NOXFER(kadr) A2_GET16(kadr,16,14,14) //!< get no transfer flag from command register |
| 35 | | #define PUT_KADR_NOXFER(kadr,val) A2_PUT16(kadr,16,14,14,val) //!< put no transfer flag into command register |
| 36 | | #define GET_KADR_UNUSED(kadr) A2_GET16(kadr,16,15,15) //!< get unused (drive?) flag from command register |
| 37 | | #define PUT_KADR_UNUSED(kadr,val) A2_PUT16(kadr,16,15,15,val) //!< put unused (drive?) flag into command register |
| 26 | #define GET_KADR_SEAL(kadr) X_RDBITS(kadr,16, 0, 7) //!< get command seal from command register |
| 27 | #define PUT_KADR_SEAL(kadr,val) X_WRBITS(kadr,16, 0, 7,val) //!< put command seal into command register |
| 28 | #define GET_KADR_HEADER(kadr) X_RDBITS(kadr,16, 8, 9) //!< get r/w/c for header from command register |
| 29 | #define PUT_KADR_HEADER(kadr,val) X_WRBITS(kadr,16, 8, 9,val) //!< put r/w/c for header from command register |
| 30 | #define GET_KADR_LABEL(kadr) X_RDBITS(kadr,16,10,11) //!< get r/w/c for label from command register |
| 31 | #define PUT_KADR_LABEL(kadr,val) X_WRBITS(kadr,16,10,11,val) //!< put r/w/c for label into command register |
| 32 | #define GET_KADR_DATA(kadr) X_RDBITS(kadr,16,12,13) //!< get r/w/c for data from command register |
| 33 | #define PUT_KADR_DATA(kadr,val) X_WRBITS(kadr,16,12,13,val) //!< put r/w/c for data into command register |
| 34 | #define GET_KADR_NOXFER(kadr) X_RDBITS(kadr,16,14,14) //!< get no transfer flag from command register |
| 35 | #define PUT_KADR_NOXFER(kadr,val) X_WRBITS(kadr,16,14,14,val) //!< put no transfer flag into command register |
| 36 | #define GET_KADR_UNUSED(kadr) X_RDBITS(kadr,16,15,15) //!< get unused (drive?) flag from command register |
| 37 | #define PUT_KADR_UNUSED(kadr,val) X_WRBITS(kadr,16,15,15,val) //!< put unused (drive?) flag into command register |
| 38 | 38 | |
| 39 | | #define GET_KSTAT_SECTOR(kstat) A2_GET16(kstat,16,0,3) //!< get current sector number from status register |
| 40 | | #define PUT_KSTAT_SECTOR(kstat,val) A2_PUT16(kstat,16,0,3,val) //!< put current sector number into status register |
| 41 | | #define GET_KSTAT_DONE(kstat) A2_GET16(kstat,16,4,7) //!< get 'done' field from status register (017) |
| 42 | | #define PUT_KSTAT_DONE(kstat,val) A2_PUT16(kstat,16,4,7,val) //!< put 'done' field int status register (017) |
| 43 | | #define GET_KSTAT_SEEKFAIL(kstat) A2_GET16(kstat,16,8,8) //!< get seek fail flag from status register |
| 44 | | #define PUT_KSTAT_SEEKFAIL(kstat,val) A2_PUT16(kstat,16,8,8,val) //!< put seek fail flag into status register |
| 45 | | #define GET_KSTAT_SEEK(kstat) A2_GET16(kstat,16,9,9) //!< get seek busy flag (strobe) from status register |
| 46 | | #define PUT_KSTAT_SEEK(kstat,val) A2_PUT16(kstat,16,9,9,val) //!< put seek busy flag (strobe) into status register |
| 47 | | #define GET_KSTAT_NOTRDY(kstat) A2_GET16(kstat,16,10,10) //!< get drive not ready flag from status register |
| 48 | | #define PUT_KSTAT_NOTRDY(kstat,val) A2_PUT16(kstat,16,10,10,val) //!< put drive not ready flag into status register |
| 49 | | #define GET_KSTAT_DATALATE(kstat) A2_GET16(kstat,16,11,11) //!< get data late flag from status register |
| 50 | | #define PUT_KSTAT_DATALATE(kstat,val) A2_PUT16(kstat,16,11,11,val) //!< put data late flag into status register |
| 51 | | #define GET_KSTAT_IDLE(kstat) A2_GET16(kstat,16,12,12) //!< get idle flag from status register (idle is a software flag) |
| 52 | | #define PUT_KSTAT_IDLE(kstat,val) A2_PUT16(kstat,16,12,12,val) //!< put idle flag into status register (idle is a software flag) |
| 53 | | #define GET_KSTAT_CKSUM(kstat) A2_GET16(kstat,16,13,13) //!< get checksum flag from status register (checksum is a software flag; it is ORed when 0) |
| 54 | | #define PUT_KSTAT_CKSUM(kstat,val) A2_PUT16(kstat,16,13,13,val) //!< put checksum flag into status register (checksum is a software flag; it is ORed when 0) |
| 55 | | #define GET_KSTAT_COMPLETION(kstat) A2_GET16(kstat,16,14,15) //!< get completion code from status register (completion is a 2-bit software latch) |
| 56 | | #define PUT_KSTAT_COMPLETION(kstat,val) A2_PUT16(kstat,16,14,15,val) //!< put completion code into status register (completion is a 2-bit software latch) |
| 39 | #define GET_KSTAT_SECTOR(kstat) X_RDBITS(kstat,16,0,3) //!< get current sector number from status register |
| 40 | #define PUT_KSTAT_SECTOR(kstat,val) X_WRBITS(kstat,16,0,3,val) //!< put current sector number into status register |
| 41 | #define GET_KSTAT_DONE(kstat) X_RDBITS(kstat,16,4,7) //!< get 'done' field from status register (017) |
| 42 | #define PUT_KSTAT_DONE(kstat,val) X_WRBITS(kstat,16,4,7,val) //!< put 'done' field int status register (017) |
| 43 | #define GET_KSTAT_SEEKFAIL(kstat) X_RDBITS(kstat,16,8,8) //!< get seek fail flag from status register |
| 44 | #define PUT_KSTAT_SEEKFAIL(kstat,val) X_WRBITS(kstat,16,8,8,val) //!< put seek fail flag into status register |
| 45 | #define GET_KSTAT_SEEK(kstat) X_RDBITS(kstat,16,9,9) //!< get seek busy flag (strobe) from status register |
| 46 | #define PUT_KSTAT_SEEK(kstat,val) X_WRBITS(kstat,16,9,9,val) //!< put seek busy flag (strobe) into status register |
| 47 | #define GET_KSTAT_NOTRDY(kstat) X_RDBITS(kstat,16,10,10) //!< get drive not ready flag from status register |
| 48 | #define PUT_KSTAT_NOTRDY(kstat,val) X_WRBITS(kstat,16,10,10,val) //!< put drive not ready flag into status register |
| 49 | #define GET_KSTAT_DATALATE(kstat) X_RDBITS(kstat,16,11,11) //!< get data late flag from status register |
| 50 | #define PUT_KSTAT_DATALATE(kstat,val) X_WRBITS(kstat,16,11,11,val) //!< put data late flag into status register |
| 51 | #define GET_KSTAT_IDLE(kstat) X_RDBITS(kstat,16,12,12) //!< get idle flag from status register (idle is a software flag) |
| 52 | #define PUT_KSTAT_IDLE(kstat,val) X_WRBITS(kstat,16,12,12,val) //!< put idle flag into status register (idle is a software flag) |
| 53 | #define GET_KSTAT_CKSUM(kstat) X_RDBITS(kstat,16,13,13) //!< get checksum flag from status register (checksum is a software flag; it is ORed when 0) |
| 54 | #define PUT_KSTAT_CKSUM(kstat,val) X_WRBITS(kstat,16,13,13,val) //!< put checksum flag into status register (checksum is a software flag; it is ORed when 0) |
| 55 | #define GET_KSTAT_COMPLETION(kstat) X_RDBITS(kstat,16,14,15) //!< get completion code from status register (completion is a 2-bit software latch) |
| 56 | #define PUT_KSTAT_COMPLETION(kstat,val) X_WRBITS(kstat,16,14,15,val) //!< put completion code into status register (completion is a 2-bit software latch) |
| 57 | 57 | |
| 58 | | #define GET_KCOM_XFEROFF(kcom) A2_GET16(kcom,16,1,1) //!< get transfer off flag from controller command (hardware command register) |
| 59 | | #define PUT_KCOM_XFEROFF(kcom,val) A2_PUT16(kcom,16,1,1,val) //!< put transfer off flag into controller command (hardware command register) |
| 60 | | #define GET_KCOM_WDINHIB(kcom) A2_GET16(kcom,16,2,2) //!< get word task inhibit flag from controller command (hardware command register) |
| 61 | | #define PUT_KCOM_WDINHIB(kcom,val) A2_PUT16(kcom,16,2,2,val) //!< put word task inhibit flag into controller command (hardware command register) |
| 62 | | #define GET_KCOM_BCLKSRC(kcom) A2_GET16(kcom,16,3,3) //!< get bit clock source flag from controller command (hardware command register) |
| 63 | | #define PUT_KCOM_BCLKSRC(kcom,val) A2_PUT16(kcom,16,3,3,val) //!< put bit clock source flag into controller command (hardware command register) |
| 64 | | #define GET_KCOM_WFFO(kcom) A2_GET16(kcom,16,4,4) //!< get write fixed frequency oscillator flag from controller command (hardware command register) |
| 65 | | #define PUT_KCOM_WFFO(kcom,val) A2_PUT16(kcom,16,4,4,val) //!< put write fixed frequency oscillator flag into controller command (hardware command register) |
| 66 | | #define GET_KCOM_SENDADR(kcom) A2_GET16(kcom,16,5,5) //!< get send address flag from controller command (hardware command register) |
| 67 | | #define PUT_KCOM_SENDADR(kcom,val) A2_PUT16(kcom,16,5,5,val) //!< put send address flag into controller command (hardware command register) |
| 58 | #define GET_KCOM_XFEROFF(kcom) X_RDBITS(kcom,16,1,1) //!< get transfer off flag from controller command (hardware command register) |
| 59 | #define PUT_KCOM_XFEROFF(kcom,val) X_WRBITS(kcom,16,1,1,val) //!< put transfer off flag into controller command (hardware command register) |
| 60 | #define GET_KCOM_WDINHIB(kcom) X_RDBITS(kcom,16,2,2) //!< get word task inhibit flag from controller command (hardware command register) |
| 61 | #define PUT_KCOM_WDINHIB(kcom,val) X_WRBITS(kcom,16,2,2,val) //!< put word task inhibit flag into controller command (hardware command register) |
| 62 | #define GET_KCOM_BCLKSRC(kcom) X_RDBITS(kcom,16,3,3) //!< get bit clock source flag from controller command (hardware command register) |
| 63 | #define PUT_KCOM_BCLKSRC(kcom,val) X_WRBITS(kcom,16,3,3,val) //!< put bit clock source flag into controller command (hardware command register) |
| 64 | #define GET_KCOM_WFFO(kcom) X_RDBITS(kcom,16,4,4) //!< get write fixed frequency oscillator flag from controller command (hardware command register) |
| 65 | #define PUT_KCOM_WFFO(kcom,val) X_WRBITS(kcom,16,4,4,val) //!< put write fixed frequency oscillator flag into controller command (hardware command register) |
| 66 | #define GET_KCOM_SENDADR(kcom) X_RDBITS(kcom,16,5,5) //!< get send address flag from controller command (hardware command register) |
| 67 | #define PUT_KCOM_SENDADR(kcom,val) X_WRBITS(kcom,16,5,5,val) //!< put send address flag into controller command (hardware command register) |
| 68 | 68 | |
| 69 | 69 | /** @brief completion codes (only for documentation, since this is microcode defined) */ |
| 70 | 70 | enum { |
branches/alto2/src/emu/cpu/alto2/alto2cpu.c
| r26301 | r26302 | |
| 1128 | 1128 | save_item(NAME(m_eth.tx_count)); |
| 1129 | 1129 | save_item(NAME(m_eth.duckbreath)); |
| 1130 | 1130 | |
| 1131 | state_add( A2_AC3, "AC(3)", m_r[000]).formatstr("%06O"); |
| 1132 | state_add( A2_AC2, "AC(2)", m_r[001]).formatstr("%06O"); |
| 1133 | state_add( A2_AC1, "AC(1)", m_r[002]).formatstr("%06O"); |
| 1134 | state_add( A2_AC0, "AC(0)", m_r[003]).formatstr("%06O"); |
| 1135 | state_add( A2_R04, "R04", m_r[004]).formatstr("%06O"); |
| 1136 | state_add( A2_R05, "R05", m_r[005]).formatstr("%06O"); |
| 1137 | state_add( A2_PC, "PC", m_r[006]).formatstr("%06O"); |
| 1138 | state_add( A2_R07, "R07", m_r[007]).formatstr("%06O"); |
| 1139 | state_add( A2_R10, "R10", m_r[010]).formatstr("%06O"); |
| 1140 | state_add( A2_R11, "R11", m_r[011]).formatstr("%06O"); |
| 1141 | state_add( A2_R12, "R12", m_r[012]).formatstr("%06O"); |
| 1142 | state_add( A2_R13, "R13", m_r[013]).formatstr("%06O"); |
| 1143 | state_add( A2_R14, "R14", m_r[014]).formatstr("%06O"); |
| 1144 | state_add( A2_R15, "R15", m_r[015]).formatstr("%06O"); |
| 1145 | state_add( A2_R16, "R16", m_r[016]).formatstr("%06O"); |
| 1146 | state_add( A2_R17, "R17", m_r[017]).formatstr("%06O"); |
| 1147 | state_add( A2_R20, "R20", m_r[020]).formatstr("%06O"); |
| 1148 | state_add( A2_R21, "R21", m_r[021]).formatstr("%06O"); |
| 1149 | state_add( A2_R22, "R22", m_r[022]).formatstr("%06O"); |
| 1150 | state_add( A2_R23, "R23", m_r[023]).formatstr("%06O"); |
| 1151 | state_add( A2_R24, "R24", m_r[024]).formatstr("%06O"); |
| 1152 | state_add( A2_R25, "R25", m_r[025]).formatstr("%06O"); |
| 1153 | state_add( A2_R26, "R26", m_r[026]).formatstr("%06O"); |
| 1154 | state_add( A2_R27, "R27", m_r[027]).formatstr("%06O"); |
| 1155 | state_add( A2_R30, "R30", m_r[030]).formatstr("%06O"); |
| 1156 | state_add( A2_R31, "R31", m_r[031]).formatstr("%06O"); |
| 1157 | state_add( A2_R32, "R32", m_r[032]).formatstr("%06O"); |
| 1158 | state_add( A2_R33, "R33", m_r[033]).formatstr("%06O"); |
| 1159 | state_add( A2_R34, "R34", m_r[034]).formatstr("%06O"); |
| 1160 | state_add( A2_R35, "R35", m_r[035]).formatstr("%06O"); |
| 1161 | state_add( A2_R36, "R36", m_r[036]).formatstr("%06O"); |
| 1162 | state_add( A2_R37, "R37", m_r[037]).formatstr("%06O"); |
| 1163 | state_add_divider(-1); |
| 1164 | state_add( A2_S00, "R40", m_s[0][000]).formatstr("%06O"); |
| 1165 | state_add( A2_S01, "R41", m_s[0][001]).formatstr("%06O"); |
| 1166 | state_add( A2_S02, "R42", m_s[0][002]).formatstr("%06O"); |
| 1167 | state_add( A2_S03, "R43", m_s[0][003]).formatstr("%06O"); |
| 1168 | state_add( A2_S04, "R44", m_s[0][004]).formatstr("%06O"); |
| 1169 | state_add( A2_S05, "R45", m_s[0][005]).formatstr("%06O"); |
| 1170 | state_add( A2_S06, "R46", m_s[0][006]).formatstr("%06O"); |
| 1171 | state_add( A2_S07, "R47", m_s[0][007]).formatstr("%06O"); |
| 1172 | state_add( A2_S10, "R50", m_s[0][010]).formatstr("%06O"); |
| 1173 | state_add( A2_S11, "R51", m_s[0][011]).formatstr("%06O"); |
| 1174 | state_add( A2_S12, "R52", m_s[0][012]).formatstr("%06O"); |
| 1175 | state_add( A2_S13, "R53", m_s[0][013]).formatstr("%06O"); |
| 1176 | state_add( A2_S14, "R54", m_s[0][014]).formatstr("%06O"); |
| 1177 | state_add( A2_S15, "R55", m_s[0][015]).formatstr("%06O"); |
| 1178 | state_add( A2_S16, "R56", m_s[0][016]).formatstr("%06O"); |
| 1179 | state_add( A2_S17, "R57", m_s[0][017]).formatstr("%06O"); |
| 1180 | state_add( A2_S20, "R60", m_s[0][020]).formatstr("%06O"); |
| 1181 | state_add( A2_S21, "R61", m_s[0][021]).formatstr("%06O"); |
| 1182 | state_add( A2_S22, "R62", m_s[0][022]).formatstr("%06O"); |
| 1183 | state_add( A2_S23, "R63", m_s[0][023]).formatstr("%06O"); |
| 1184 | state_add( A2_S24, "R64", m_s[0][024]).formatstr("%06O"); |
| 1185 | state_add( A2_S25, "R65", m_s[0][025]).formatstr("%06O"); |
| 1186 | state_add( A2_S26, "R66", m_s[0][026]).formatstr("%06O"); |
| 1187 | state_add( A2_S27, "R67", m_s[0][027]).formatstr("%06O"); |
| 1188 | state_add( A2_S30, "R70", m_s[0][030]).formatstr("%06O"); |
| 1189 | state_add( A2_S31, "R71", m_s[0][031]).formatstr("%06O"); |
| 1190 | state_add( A2_S32, "R72", m_s[0][032]).formatstr("%06O"); |
| 1191 | state_add( A2_S33, "R73", m_s[0][033]).formatstr("%06O"); |
| 1192 | state_add( A2_S34, "R74", m_s[0][034]).formatstr("%06O"); |
| 1193 | state_add( A2_S35, "R75", m_s[0][035]).formatstr("%06O"); |
| 1194 | state_add( A2_S36, "R76", m_s[0][036]).formatstr("%06O"); |
| 1195 | state_add( A2_S37, "R77", m_s[0][037]).formatstr("%06O"); |
| 1196 | state_add_divider(-1); |
| 1131 | 1197 | state_add( A2_DRIVE, "DRIVE", m_dsk.drive).formatstr("%1u"); |
| 1132 | 1198 | state_add( A2_KADDR, "KADDR", m_dsk.kaddr).formatstr("%06O"); |
| 1133 | 1199 | state_add( A2_KADR, "KADR", m_dsk.kadr).formatstr("%06O"); |
| r26301 | r26302 | |
| 1165 | 1231 | state_add( A2_SHIFTER, "SHIFTER", m_shifter).formatstr("%06O"); |
| 1166 | 1232 | state_add( A2_LALUC0, "LALUC0", m_laluc0).formatstr("%1u"); |
| 1167 | 1233 | state_add( A2_M, "M", m_m).formatstr("%06O"); |
| 1168 | | state_add_divider(-1); |
| 1169 | | state_add( A2_AC3, "AC(3)", m_r[000]).formatstr("%06O"); |
| 1170 | | state_add( A2_AC2, "AC(2)", m_r[001]).formatstr("%06O"); |
| 1171 | | state_add( A2_AC1, "AC(1)", m_r[002]).formatstr("%06O"); |
| 1172 | | state_add( A2_AC0, "AC(0)", m_r[003]).formatstr("%06O"); |
| 1173 | | state_add( A2_R04, "R04", m_r[004]).formatstr("%06O"); |
| 1174 | | state_add( A2_R05, "R05", m_r[005]).formatstr("%06O"); |
| 1175 | | state_add( A2_PC, "PC", m_r[006]).formatstr("%06O"); |
| 1176 | | state_add( A2_R07, "R07", m_r[007]).formatstr("%06O"); |
| 1177 | | state_add( A2_R10, "R10", m_r[010]).formatstr("%06O"); |
| 1178 | | state_add( A2_R11, "R11", m_r[011]).formatstr("%06O"); |
| 1179 | | state_add( A2_R12, "R12", m_r[012]).formatstr("%06O"); |
| 1180 | | state_add( A2_R13, "R13", m_r[013]).formatstr("%06O"); |
| 1181 | | state_add( A2_R14, "R14", m_r[014]).formatstr("%06O"); |
| 1182 | | state_add( A2_R15, "R15", m_r[015]).formatstr("%06O"); |
| 1183 | | state_add( A2_R16, "R16", m_r[016]).formatstr("%06O"); |
| 1184 | | state_add( A2_R17, "R17", m_r[017]).formatstr("%06O"); |
| 1185 | | state_add( A2_R20, "R20", m_r[020]).formatstr("%06O"); |
| 1186 | | state_add( A2_R21, "R21", m_r[021]).formatstr("%06O"); |
| 1187 | | state_add( A2_R22, "R22", m_r[022]).formatstr("%06O"); |
| 1188 | | state_add( A2_R23, "R23", m_r[023]).formatstr("%06O"); |
| 1189 | | state_add( A2_R24, "R24", m_r[024]).formatstr("%06O"); |
| 1190 | | state_add( A2_R25, "R25", m_r[025]).formatstr("%06O"); |
| 1191 | | state_add( A2_R26, "R26", m_r[026]).formatstr("%06O"); |
| 1192 | | state_add( A2_R27, "R27", m_r[027]).formatstr("%06O"); |
| 1193 | | state_add( A2_R30, "R30", m_r[030]).formatstr("%06O"); |
| 1194 | | state_add( A2_R31, "R31", m_r[031]).formatstr("%06O"); |
| 1195 | | state_add( A2_R32, "R32", m_r[032]).formatstr("%06O"); |
| 1196 | | state_add( A2_R33, "R33", m_r[033]).formatstr("%06O"); |
| 1197 | | state_add( A2_R34, "R34", m_r[034]).formatstr("%06O"); |
| 1198 | | state_add( A2_R35, "R35", m_r[035]).formatstr("%06O"); |
| 1199 | | state_add( A2_R36, "R36", m_r[036]).formatstr("%06O"); |
| 1200 | | state_add( A2_R37, "R37", m_r[037]).formatstr("%06O"); |
| 1201 | | state_add_divider(-1); |
| 1202 | | state_add( A2_S00, "S00", m_s[0][000]).formatstr("%06O"); |
| 1203 | | state_add( A2_S01, "S01", m_s[0][001]).formatstr("%06O"); |
| 1204 | | state_add( A2_S02, "S02", m_s[0][002]).formatstr("%06O"); |
| 1205 | | state_add( A2_S03, "S03", m_s[0][003]).formatstr("%06O"); |
| 1206 | | state_add( A2_S04, "S04", m_s[0][004]).formatstr("%06O"); |
| 1207 | | state_add( A2_S05, "S05", m_s[0][005]).formatstr("%06O"); |
| 1208 | | state_add( A2_S06, "S06", m_s[0][006]).formatstr("%06O"); |
| 1209 | | state_add( A2_S07, "S07", m_s[0][007]).formatstr("%06O"); |
| 1210 | | state_add( A2_S10, "S10", m_s[0][010]).formatstr("%06O"); |
| 1211 | | state_add( A2_S11, "S11", m_s[0][011]).formatstr("%06O"); |
| 1212 | | state_add( A2_S12, "S12", m_s[0][012]).formatstr("%06O"); |
| 1213 | | state_add( A2_S13, "S13", m_s[0][013]).formatstr("%06O"); |
| 1214 | | state_add( A2_S14, "S14", m_s[0][014]).formatstr("%06O"); |
| 1215 | | state_add( A2_S15, "S15", m_s[0][015]).formatstr("%06O"); |
| 1216 | | state_add( A2_S16, "S16", m_s[0][016]).formatstr("%06O"); |
| 1217 | | state_add( A2_S17, "S17", m_s[0][017]).formatstr("%06O"); |
| 1218 | | state_add( A2_S20, "S20", m_s[0][020]).formatstr("%06O"); |
| 1219 | | state_add( A2_S21, "S21", m_s[0][021]).formatstr("%06O"); |
| 1220 | | state_add( A2_S22, "S22", m_s[0][022]).formatstr("%06O"); |
| 1221 | | state_add( A2_S23, "S23", m_s[0][023]).formatstr("%06O"); |
| 1222 | | state_add( A2_S24, "S24", m_s[0][024]).formatstr("%06O"); |
| 1223 | | state_add( A2_S25, "S25", m_s[0][025]).formatstr("%06O"); |
| 1224 | | state_add( A2_S26, "S26", m_s[0][026]).formatstr("%06O"); |
| 1225 | | state_add( A2_S27, "S27", m_s[0][027]).formatstr("%06O"); |
| 1226 | | state_add( A2_S30, "S30", m_s[0][030]).formatstr("%06O"); |
| 1227 | | state_add( A2_S31, "S31", m_s[0][031]).formatstr("%06O"); |
| 1228 | | state_add( A2_S32, "S32", m_s[0][032]).formatstr("%06O"); |
| 1229 | | state_add( A2_S33, "S33", m_s[0][033]).formatstr("%06O"); |
| 1230 | | state_add( A2_S34, "S34", m_s[0][034]).formatstr("%06O"); |
| 1231 | | state_add( A2_S35, "S35", m_s[0][035]).formatstr("%06O"); |
| 1232 | | state_add( A2_S36, "S36", m_s[0][036]).formatstr("%06O"); |
| 1233 | | state_add( A2_S37, "S37", m_s[0][037]).formatstr("%06O"); |
| 1234 | 1234 | |
| 1235 | 1235 | state_add(STATE_GENPC, "curpc", m_mpc).formatstr("%03X").noshow(); |
| 1236 | 1236 | state_add(STATE_GENFLAGS, "GENFLAGS", m_aluc0).formatstr("%5s").noshow(); |
| r26301 | r26302 | |
| 1273 | 1273 | return *reinterpret_cast<UINT16 *>(m_const_data + offset * 2); |
| 1274 | 1274 | } |
| 1275 | 1275 | |
| 1276 | | #define PUT_EVEN(dword,word) A2_PUT32(dword,32, 0,15,word) |
| 1277 | | #define GET_EVEN(dword) A2_GET32(dword,32, 0,15) |
| 1278 | | #define PUT_ODD(dword,word) A2_PUT32(dword,32,16,31,word) |
| 1279 | | #define GET_ODD(dword) A2_GET32(dword,32,16,31) |
| 1276 | #define PUT_EVEN(dword,word) X_WRBITS(dword,32, 0,15,word) |
| 1277 | #define GET_EVEN(dword) X_RDBITS(dword,32, 0,15) |
| 1278 | #define PUT_ODD(dword,word) X_WRBITS(dword,32,16,31,word) |
| 1279 | #define GET_ODD(dword) X_RDBITS(dword,32,16,31) |
| 1280 | 1280 | |
| 1281 | 1281 | //! read i/o space RAM |
| 1282 | 1282 | READ16_MEMBER ( alto2_cpu_device::ioram_r ) |
| r26301 | r26302 | |
| 1531 | 1531 | void alto2_cpu_device::fn_bs_bad_0() |
| 1532 | 1532 | { |
| 1533 | 1533 | fatal(9,"fatal: bad early bus source pointer for task %s, mpc:%05o bs:%s\n", |
| 1534 | | task_name(m_task), m_mpc, bs_name(MIR_BS(m_mir))); |
| 1534 | task_name(m_task), m_mpc, bs_name(m_d_bs)); |
| 1535 | 1535 | } |
| 1536 | 1536 | |
| 1537 | 1537 | /** @brief fatal exit on unitialized latching phase BUS source */ |
| 1538 | 1538 | void alto2_cpu_device::fn_bs_bad_1() |
| 1539 | 1539 | { |
| 1540 | 1540 | fatal(9,"fatal: bad late bus source pointer for task %s, mpc:%05o bs: %s\n", |
| 1541 | | task_name(m_task), m_mpc, bs_name(MIR_BS(m_mir))); |
| 1541 | task_name(m_task), m_mpc, bs_name(m_d_bs)); |
| 1542 | 1542 | } |
| 1543 | 1543 | |
| 1544 | 1544 | /** @brief fatal exit on unitialized dynamic phase F1 function */ |
| 1545 | 1545 | void alto2_cpu_device::fn_f1_bad_0() |
| 1546 | 1546 | { |
| 1547 | 1547 | fatal(9,"fatal: bad early f1 function pointer for task %s, mpc:%05o f1: %s\n", |
| 1548 | | task_name(m_task), m_mpc, f1_name(MIR_F1(m_mir))); |
| 1548 | task_name(m_task), m_mpc, f1_name(m_d_f1)); |
| 1549 | 1549 | } |
| 1550 | 1550 | |
| 1551 | 1551 | /** @brief fatal exit on unitialized latching phase F1 function */ |
| 1552 | 1552 | void alto2_cpu_device::fn_f1_bad_1() |
| 1553 | 1553 | { |
| 1554 | 1554 | fatal(9,"fatal: bad late f1 function pointer for task %s, mpc:%05o f1: %s\n", |
| 1555 | | task_name(m_task), m_mpc, f1_name(MIR_F1(m_mir))); |
| 1555 | task_name(m_task), m_mpc, f1_name(m_d_f1)); |
| 1556 | 1556 | } |
| 1557 | 1557 | |
| 1558 | 1558 | /** @brief fatal exit on unitialized dynamic phase F2 function */ |
| 1559 | 1559 | void alto2_cpu_device::fn_f2_bad_0() |
| 1560 | 1560 | { |
| 1561 | 1561 | fatal(9,"fatal: bad early f2 function pointer for task %s, mpc:%05o f2: %s\n", |
| 1562 | | task_name(m_task), m_mpc, f2_name(MIR_F2(m_mir))); |
| 1562 | task_name(m_task), m_mpc, f2_name(m_d_f2)); |
| 1563 | 1563 | } |
| 1564 | 1564 | |
| 1565 | 1565 | /** @brief fatal exit on unitialized latching phase F2 function */ |
| 1566 | 1566 | void alto2_cpu_device::fn_f2_bad_1() |
| 1567 | 1567 | { |
| 1568 | 1568 | fatal(9,"fatal: bad late f2 function pointer for task %s, mpc:%05o f2: %s\n", |
| 1569 | | task_name(m_task), m_mpc, f2_name(MIR_F2(m_mir))); |
| 1569 | task_name(m_task), m_mpc, f2_name(m_d_f2)); |
| 1570 | 1570 | } |
| 1571 | 1571 | |
| 1572 | 1572 | #if ALTO2_DEBUG |
| r26301 | r26302 | |
| 1701 | 1701 | */ |
| 1702 | 1702 | void alto2_cpu_device::bs_late_load_r() |
| 1703 | 1703 | { |
| 1704 | | if (MIR_F2(m_mir) != f2_emu_load_dns) { |
| 1704 | if (m_d_f2 != f2_emu_load_dns) { |
| 1705 | 1705 | m_r[m_rsel] = m_shifter; |
| 1706 | 1706 | LOG((LOG_CPU,2," R%02o←; %s = SHIFTER (%#o)\n", m_rsel, r_name(m_rsel), m_shifter)); |
| 1707 | #if 1 |
| 1707 | 1708 | /* HACK: programs writing r37 with xxx3 make the cursor |
| 1708 | 1709 | * display go nuts. Until I found the real reason for this |
| 1709 | 1710 | * obviously buggy display, I just clear the two |
| r26301 | r26302 | |
| 1713 | 1714 | printf("writing r37 = %#o\n", m_shifter); |
| 1714 | 1715 | m_r[037] &= ~3; |
| 1715 | 1716 | } |
| 1717 | #endif |
| 1716 | 1718 | } |
| 1717 | 1719 | } |
| 1718 | 1720 | |
| r26301 | r26302 | |
| 1760 | 1762 | { |
| 1761 | 1763 | UINT8 bank = m_bank_reg[m_task]; |
| 1762 | 1764 | UINT32 msb; |
| 1763 | | if (MIR_F2(m_mir) == f2_load_md) { |
| 1765 | if (m_d_f2 == f2_load_md) { |
| 1764 | 1766 | msb = GET_BANK_EXTENDED(bank) << 16; |
| 1765 | 1767 | LOG((LOG_CPU,7, " XMAR %#o\n", msb | m_alu)); |
| 1766 | 1768 | } else { |
| r26301 | r26302 | |
| 2051 | 2053 | #endif /* !USE_PRIO_F9318 */ |
| 2052 | 2054 | } |
| 2053 | 2055 | |
| 2054 | | #ifdef f1_block0_unused |
| 2055 | 2056 | /** |
| 2056 | 2057 | * @brief f1_block early: block task |
| 2057 | 2058 | * |
| 2058 | 2059 | * The task request for the active task is cleared |
| 2059 | 2060 | */ |
| 2060 | | void alto2_cpu_device::f1_block_0() |
| 2061 | void alto2_cpu_device::f1_early_block() |
| 2061 | 2062 | { |
| 2062 | | CPU_CLR_TASK_WAKEUP(m_task); |
| 2063 | m_task_wakeup &= ~(1 << m_task); |
| 2063 | 2064 | LOG((LOG_CPU,2, " BLOCK %02o:%s\n", m_task, task_name(m_task))); |
| 2064 | 2065 | } |
| 2065 | | #endif |
| 2066 | 2066 | |
| 2067 | 2067 | void alto2_cpu_device::f1_late_l_lsh_1() |
| 2068 | 2068 | { |
| 2069 | | #if 0 |
| 2070 | | if (m_task == task_emu) { |
| 2071 | | if (f2 == f2_emu_magic) { |
| 2072 | | m_shifter = ((m_l << 1) | (m_t >> 15)) & 0177777; |
| 2073 | | LOG((LOG_CPU,2," SHIFTER ←L MLSH 1 (%#o := %#o<<1|%#o)\n", m_shifter, m_l, m_t >> 15)); |
| 2074 | | } |
| 2075 | | if (f2 == f2_emu_load_dns) { |
| 2076 | | /* shifter is done in F2 */ |
| 2077 | | break; |
| 2078 | | } |
| 2079 | | } |
| 2080 | | #endif |
| 2081 | | m_shifter = (m_l << 1) & 0177777; |
| 2069 | m_shifter = m_l << 1; |
| 2082 | 2070 | LOG((LOG_CPU,2," SHIFTER ←L LSH 1 (%#o := %#o<<1)\n", m_shifter, m_l)); |
| 2083 | 2071 | } |
| 2084 | 2072 | |
| 2085 | 2073 | void alto2_cpu_device::f1_late_l_rsh_1() |
| 2086 | 2074 | { |
| 2087 | | #if 0 |
| 2088 | | if (m_task == task_emu) { |
| 2089 | | if (f2 == f2_emu_magic) { |
| 2090 | | m_shifter = ((m_l >> 1) | (m_t << 15)) & 0177777; |
| 2091 | | LOG((LOG_CPU,2," SHIFTER ←L MRSH 1 (%#o := %#o>>1|%#o)\n", m_shifter, m_l, (m_t << 15) & 0100000)); |
| 2092 | | break; |
| 2093 | | } |
| 2094 | | if (f2 == f2_emu_load_dns) { |
| 2095 | | /* shifter is done in F2 */ |
| 2096 | | break; |
| 2097 | | } |
| 2098 | | } |
| 2099 | | #endif |
| 2100 | 2075 | m_shifter = m_l >> 1; |
| 2101 | 2076 | LOG((LOG_CPU,2," SHIFTER ←L RSH 1 (%#o := %#o>>1)\n", m_shifter, m_l)); |
| 2102 | 2077 | } |
| 2103 | 2078 | |
| 2104 | 2079 | void alto2_cpu_device::f1_late_l_lcy_8() |
| 2105 | 2080 | { |
| 2106 | | m_shifter = ((m_l >> 8) | (m_l << 8)) & 0177777; |
| 2081 | m_shifter = (m_l >> 8) | (m_l << 8); |
| 2107 | 2082 | LOG((LOG_CPU,2," SHIFTER ←L LCY 8 (%#o := bswap %#o)\n", m_shifter, m_l)); |
| 2108 | 2083 | } |
| 2109 | 2084 | |
| r26301 | r26302 | |
| 2142 | 2117 | */ |
| 2143 | 2118 | void alto2_cpu_device::f2_late_bus() |
| 2144 | 2119 | { |
| 2145 | | UINT16 r = A2_GET16(m_bus,16,6,15); |
| 2120 | UINT16 r = X_RDBITS(m_bus,16,6,15); |
| 2146 | 2121 | LOG((LOG_CPU,2, " BUS; %sbranch (%#o|%#o)\n", r ? "" : "no ", m_next2, r)); |
| 2147 | 2122 | m_next2 |= r; |
| 2148 | 2123 | } |
| r26301 | r26302 | |
| 2167 | 2142 | #if ALTO2_DEBUG |
| 2168 | 2143 | UINT16 mar = m_mem.mar; |
| 2169 | 2144 | #endif |
| 2170 | | if (MIR_F1(m_mir) == f1_load_mar) { |
| 2145 | if (m_d_f1 == f1_load_mar) { |
| 2171 | 2146 | /* part of an XMAR */ |
| 2172 | 2147 | LOG((LOG_CPU,2, " XMAR %#o (%#o)\n", mar, m_bus)); |
| 2173 | 2148 | } else { |
| r26301 | r26302 | |
| 2256 | 2231 | if (GET_CRAM_HALFSEL(m_cram_addr)) { |
| 2257 | 2232 | val = val >> 16; |
| 2258 | 2233 | LOG((LOG_CPU,0,"upper:%06o\n", val)); |
| 2234 | printf("RD RAM%d [%04o] upper:%06o\n", bank, wordaddr, val); |
| 2259 | 2235 | } else { |
| 2260 | 2236 | val = val & 0177777; |
| 2261 | 2237 | LOG((LOG_CPU,0,"lower:%06o\n", val)); |
| 2238 | printf("RD RAM%d [%04o] lower:%06o\n", bank, wordaddr, val); |
| 2262 | 2239 | } |
| 2263 | 2240 | m_bus &= val; |
| 2264 | 2241 | } |
| r26301 | r26302 | |
| 2284 | 2261 | /* write RAM 0,1,2 */ |
| 2285 | 2262 | addr = bank * ALTO2_UCODE_PAGE_SIZE + wordaddr; |
| 2286 | 2263 | LOG((LOG_CPU,0," wrtram: RAM%d [%04o] upper:%06o lower:%06o", bank, wordaddr, m_m, m_alu)); |
| 2264 | printf("WR RAM%d [%04o] upper:%06o lower:%06o\n", bank, wordaddr, m_m, m_alu); |
| 2287 | 2265 | if (ALTO2_UCODE_RAM_BASE + addr >= ALTO2_UCODE_SIZE) { |
| 2288 | 2266 | LOG((LOG_CPU,0," invalid address\n")); |
| 2289 | 2267 | return; |
| r26301 | r26302 | |
| 2687 | 2665 | /* next instruction's mpc */ |
| 2688 | 2666 | m_mpc = m_next; |
| 2689 | 2667 | m_mir = RD_CROM(m_mpc); |
| 2690 | | m_rsel = MIR_RSEL(m_mir); |
| 2691 | | m_next = MIR_NEXT(m_mir) | m_next2; |
| 2692 | | m_next2 = A2_GET32(RD_CROM(m_next), 32, NEXT0, NEXT9) | (m_next2 & ~ALTO2_UCODE_PAGE_MASK); |
| 2693 | | UINT8 aluf = MIR_ALUF(m_mir); |
| 2694 | | UINT8 bs = MIR_BS(m_mir); |
| 2695 | | UINT8 f1 = MIR_F1(m_mir); |
| 2696 | | UINT8 f2 = MIR_F2(m_mir); |
| 2668 | |
| 2669 | m_d_rsel = m_rsel = X_RDBITS(m_mir, 32, DRSEL0, DRSEL4); |
| 2670 | m_d_aluf = X_RDBITS(m_mir, 32, DALUF0, DALUF3); |
| 2671 | m_d_bs = X_RDBITS(m_mir, 32, DBS0, DBS2); |
| 2672 | m_d_f1 = X_RDBITS(m_mir, 32, DF1_0, DF1_3); |
| 2673 | m_d_f2 = X_RDBITS(m_mir, 32, DF2_0, DF2_3); |
| 2674 | m_d_loadt = X_BIT(m_mir, 32, DLOADT); |
| 2675 | m_d_loadl = X_BIT(m_mir, 32, DLOADL); |
| 2676 | m_next = X_RDBITS(m_mir, 32, NEXT0, NEXT9) | m_next2; |
| 2677 | m_next2 = X_RDBITS(RD_CROM(m_next), 32, NEXT0, NEXT9) | (m_next2 & ~ALTO2_UCODE_PAGE_MASK); |
| 2697 | 2678 | LOG((LOG_CPU,2,"%s-%04o: %011o r:%02o aluf:%02o bs:%02o f1:%02o f2:%02o t:%o l:%o next:%05o next2:%05o\n", |
| 2698 | | task_name(m_task), m_mpc, m_mir, m_rsel, aluf, bs, f1, f2, MIR_T(m_mir), MIR_L(m_mir), m_next, m_next2)); |
| 2679 | task_name(m_task), m_mpc, m_mir, m_rsel, m_d_aluf, m_d_bs, m_d_f1, m_d_f2, MIR_T(m_mir), MIR_L(m_mir), m_next, m_next2)); |
| 2699 | 2680 | debugger_instruction_hook(this, m_mpc); |
| 2700 | 2681 | |
| 2701 | 2682 | /* |
| r26301 | r26302 | |
| 2703 | 2684 | * These functions use the BS field to provide part of the address |
| 2704 | 2685 | * to the constant ROM |
| 2705 | 2686 | */ |
| 2706 | | do_bs = !(f1 == f1_const || f2 == f2_const); |
| 2687 | do_bs = !(m_d_f1 == f1_const || m_d_f2 == f2_const); |
| 2707 | 2688 | |
| 2708 | | if (f1 == f1_load_mar) { |
| 2689 | if (m_d_f1 == f1_load_mar) { |
| 2709 | 2690 | if (check_mem_load_mar_stall(m_rsel)) { |
| 2710 | 2691 | LOG((LOG_CPU,3, " MAR← stall\n")); |
| 2711 | 2692 | m_next2 = m_next; |
| 2712 | 2693 | m_next = m_mpc; |
| 2713 | 2694 | continue; |
| 2714 | 2695 | } |
| 2715 | | } else if (f2 == f2_load_md) { |
| 2696 | } else if (m_d_f2 == f2_load_md) { |
| 2716 | 2697 | if (check_mem_write_stall()) { |
| 2717 | 2698 | LOG((LOG_CPU,3, " MD← stall\n")); |
| 2718 | 2699 | m_next2 = m_next; |
| r26301 | r26302 | |
| 2720 | 2701 | continue; |
| 2721 | 2702 | } |
| 2722 | 2703 | } |
| 2723 | | if (do_bs && bs == bs_read_md) { |
| 2704 | if (do_bs && m_d_bs == bs_read_md) { |
| 2724 | 2705 | if (check_mem_read_stall()) { |
| 2725 | 2706 | LOG((LOG_CPU,3, " ←MD stall\n")); |
| 2726 | 2707 | m_next2 = m_next; |
| r26301 | r26302 | |
| 2737 | 2718 | /* |
| 2738 | 2719 | * The constant memory is gated to the bus by F1 == f1_const, F2 == f2_const, or BS >= 4 |
| 2739 | 2720 | */ |
| 2740 | | if (!do_bs || bs >= bs_task_4) { |
| 2741 | | int addr = 8 * m_rsel + bs; |
| 2721 | if (!do_bs || m_d_bs >= bs_task_4) { |
| 2722 | int addr = 8 * m_rsel + m_d_bs; |
| 2742 | 2723 | UINT16 data = m_const_data[2*addr+0] | (m_const_data[2*addr+1] << 8); |
| 2743 | 2724 | m_bus &= data; |
| 2744 | 2725 | LOG((LOG_CPU,2," %#o; BUS &= %#o CONST[%03o]\n", m_bus, data, addr)); |
| r26301 | r26302 | |
| 2748 | 2729 | * early f2 has to be done before early bs, because the |
| 2749 | 2730 | * emulator f2 acsource or acdest may change m_rsel |
| 2750 | 2731 | */ |
| 2751 | | ((*this).*m_f2[0][m_task][f2])(); |
| 2732 | ((*this).*m_f2[0][m_task][m_d_f2])(); |
| 2752 | 2733 | |
| 2753 | 2734 | /* |
| 2754 | 2735 | * early bs can be done now |
| 2755 | 2736 | */ |
| 2756 | 2737 | if (do_bs) |
| 2757 | | ((*this).*m_bs[0][m_task][bs])(); |
| 2738 | ((*this).*m_bs[0][m_task][m_d_bs])(); |
| 2758 | 2739 | |
| 2759 | 2740 | /* |
| 2760 | 2741 | * early f1 |
| 2761 | 2742 | */ |
| 2762 | | ((*this).*m_f1[0][m_task][f1])(); |
| 2743 | ((*this).*m_f1[0][m_task][m_d_f1])(); |
| 2763 | 2744 | |
| 2764 | 2745 | #if USE_ALU_74181 |
| 2765 | 2746 | // The ALU a10 PROM address lines are |
| r26301 | r26302 | |
| 2768 | 2749 | // B0: unused B1: TSELECT B2: ALUCI' B3: ALUM' |
| 2769 | 2750 | // B4: ALUS0' B5: ALUS1' B6: ALUS2' B7: ALUS3' |
| 2770 | 2751 | // B1 and B3-B7 are inverted on loading the PROM |
| 2771 | | UINT8 a10 = m_alu_a10[(m_emu.skip << 4) | aluf]; |
| 2752 | UINT8 a10 = m_alu_a10[(m_emu.skip << 4) | m_d_aluf]; |
| 2772 | 2753 | UINT32 alu = alu_74181(m_bus, m_t, a10); |
| 2773 | 2754 | m_aluc0 = (alu >> 16) & 1; |
| 2774 | 2755 | flags = (a10 ^ ALUM2) & (TSELECT | ALUM2); |
| r26301 | r26302 | |
| 2996 | 2977 | m_shifter = m_l; |
| 2997 | 2978 | |
| 2998 | 2979 | /* late F1 is done now */ |
| 2999 | | ((*this).*m_f1[1][m_task][f1])(); |
| 2980 | ((*this).*m_f1[1][m_task][m_d_f1])(); |
| 3000 | 2981 | |
| 3001 | 2982 | /* late F2 is done now */ |
| 3002 | | ((*this).*m_f2[1][m_task][f2])(); |
| 2983 | ((*this).*m_f2[1][m_task][m_d_f2])(); |
| 3003 | 2984 | |
| 3004 | 2985 | /* late BS is done now, if no constant was put on the bus */ |
| 3005 | 2986 | if (do_bs) |
| 3006 | | ((*this).*m_bs[1][m_task][bs])(); |
| 2987 | ((*this).*m_bs[1][m_task][m_d_bs])(); |
| 3007 | 2988 | |
| 3008 | 2989 | // update L register and LALUC0, and also M register, if a RAM related task is active |
| 3009 | | if (MIR_L(m_mir)) { |
| 2990 | if (m_d_loadl) { |
| 3010 | 2991 | m_l = m_alu; // load L from ALU |
| 3011 | 2992 | if (flags & ALUM2) { |
| 3012 | 2993 | m_laluc0 = m_aluc0; |
| r26301 | r26302 | |
| 3023 | 3004 | } |
| 3024 | 3005 | |
| 3025 | 3006 | // update T register, if LOADT is set |
| 3026 | | if (MIR_T(m_mir)) { |
| 3027 | | m_cram_addr = m_alu; |
| 3007 | if (m_d_loadt) { |
| 3008 | m_cram_addr = m_alu; // latch CRAM address |
| 3028 | 3009 | if (flags & TSELECT) { |
| 3029 | 3010 | m_t = m_alu; // T source is ALU |
| 3030 | 3011 | LOG((LOG_CPU,2, " T← ALU (%#o)\n", m_alu)); |
branches/alto2/src/emu/cpu/alto2/a2ether.c
| r26301 | r26302 | |
| 13 | 13 | UINT8 ether_id = 254; |
| 14 | 14 | |
| 15 | 15 | /** @brief hardware status: write latch full/filled (? set by EODFCT) */ |
| 16 | | #define GET_ETH_WLF(st) A2_BIT16(st,16,4) |
| 17 | | #define PUT_ETH_WLF(st,val) A2_PUT16(st,16,4,4,val) |
| 16 | #define GET_ETH_WLF(st) X_BIT(st,16,4) |
| 17 | #define PUT_ETH_WLF(st,val) X_WRBITS(st,16,4,4,val) |
| 18 | 18 | |
| 19 | 19 | /** @brief hardware status: output end of transmission (set by EEFCT) */ |
| 20 | | #define GET_ETH_OEOT(st) A2_BIT16(st,16,5) |
| 21 | | #define PUT_ETH_OEOT(st,val) A2_PUT16(st,16,5,5,val) |
| 20 | #define GET_ETH_OEOT(st) X_BIT(st,16,5) |
| 21 | #define PUT_ETH_OEOT(st,val) X_WRBITS(st,16,5,5,val) |
| 22 | 22 | |
| 23 | 23 | /** @brief hardware status: input gone */ |
| 24 | | #define GET_ETH_IGONE(st) A2_BIT16(st,16,6) |
| 25 | | #define PUT_ETH_IGONE(st,val) A2_PUT16(st,16,6,6,val) |
| 24 | #define GET_ETH_IGONE(st) X_BIT(st,16,6) |
| 25 | #define PUT_ETH_IGONE(st,val) X_WRBITS(st,16,6,6,val) |
| 26 | 26 | |
| 27 | 27 | /** @brief hardware status: input busy (set by EISFCT, bit isn't visible to microcode) */ |
| 28 | | #define GET_ETH_IBUSY(st) A2_BIT16(st,16,7) |
| 29 | | #define PUT_ETH_IBUSY(st,val) A2_PUT16(st,16,7,7,val) |
| 28 | #define GET_ETH_IBUSY(st) X_BIT(st,16,7) |
| 29 | #define PUT_ETH_IBUSY(st,val) X_WRBITS(st,16,7,7,val) |
| 30 | 30 | |
| 31 | 31 | /** @brief hardware status: output gone */ |
| 32 | | #define GET_ETH_OGONE(st) A2_BIT16(st,16,8) |
| 33 | | #define PUT_ETH_OGONE(st,val) A2_PUT16(st,16,8,8,val) |
| 32 | #define GET_ETH_OGONE(st) X_BIT(st,16,8) |
| 33 | #define PUT_ETH_OGONE(st,val) X_WRBITS(st,16,8,8,val) |
| 34 | 34 | |
| 35 | 35 | /** @brief hardware status: output busy (set by EOSFCT, bit isn't visible to microcode) */ |
| 36 | | #define GET_ETH_OBUSY(st) A2_BIT16(st,16,9) |
| 37 | | #define PUT_ETH_OBUSY(st,val) A2_PUT16(st,16,9,9,val) |
| 36 | #define GET_ETH_OBUSY(st) X_BIT(st,16,9) |
| 37 | #define PUT_ETH_OBUSY(st,val) X_WRBITS(st,16,9,9,val) |
| 38 | 38 | |
| 39 | 39 | /** @brief hardware status: input data late */ |
| 40 | | #define GET_ETH_IDL(st) A2_BIT16(st,16,10) |
| 41 | | #define PUT_ETH_IDL(st,val) A2_PUT16(st,16,10,10,val) |
| 40 | #define GET_ETH_IDL(st) X_BIT(st,16,10) |
| 41 | #define PUT_ETH_IDL(st,val) X_WRBITS(st,16,10,10,val) |
| 42 | 42 | |
| 43 | 43 | /** @brief hardware status: collision */ |
| 44 | | #define GET_ETH_COLL(st) A2_BIT16(st,16,11) |
| 45 | | #define PUT_ETH_COLL(st,val) A2_PUT16(st,16,11,11,val) |
| 44 | #define GET_ETH_COLL(st) X_BIT(st,16,11) |
| 45 | #define PUT_ETH_COLL(st,val) X_WRBITS(st,16,11,11,val) |
| 46 | 46 | |
| 47 | 47 | /** @brief hardware status: CRC error */ |
| 48 | | #define GET_ETH_CRC(st) A2_BIT16(st,16,12) |
| 49 | | #define PUT_ETH_CRC(st,val) A2_PUT16(st,16,12,12,val) |
| 48 | #define GET_ETH_CRC(st) X_BIT(st,16,12) |
| 49 | #define PUT_ETH_CRC(st,val) X_WRBITS(st,16,12,12,val) |
| 50 | 50 | |
| 51 | 51 | /** @brief hardware status: input command (set from BUS[14] on SIO, reset by EPFCT) */ |
| 52 | | #define GET_ETH_ICMD(st) A2_BIT16(st,16,13) |
| 53 | | #define PUT_ETH_ICMD(st,val) A2_PUT16(st,16,13,13,val) |
| 52 | #define GET_ETH_ICMD(st) X_BIT(st,16,13) |
| 53 | #define PUT_ETH_ICMD(st,val) X_WRBITS(st,16,13,13,val) |
| 54 | 54 | |
| 55 | 55 | /** @brief hardware status: output command (set from BUS[15] on SIO, reset by EPFCT) */ |
| 56 | | #define GET_ETH_OCMD(st) A2_BIT16(st,16,14) |
| 57 | | #define PUT_ETH_OCMD(st,val) A2_PUT16(st,16,14,14,val) |
| 56 | #define GET_ETH_OCMD(st) X_BIT(st,16,14) |
| 57 | #define PUT_ETH_OCMD(st,val) X_WRBITS(st,16,14,14,val) |
| 58 | 58 | |
| 59 | 59 | /** @brief hardware status: IT flip flop & ISRFULL' */ |
| 60 | 60 | #define GET_ETH_IT(st) ALTO2_GET(st,16,15,15) |
| 61 | | #define PUT_ETH_IT(st,val) A2_PUT16(st,16,15,15,val) |
| 61 | #define PUT_ETH_IT(st,val) X_WRBITS(st,16,15,15,val) |
| 62 | 62 | |
| 63 | 63 | /** @brief missing PROM ether.u49; buffer empty (active low) */ |
| 64 | 64 | #define ETHER_A49_BE (m_ether_a49[16 * m_eth.fifo_wr + m_eth.fifo_rd] & (1 << 0)) |
| r26301 | r26302 | |
| 424 | 424 | |
| 425 | 425 | void alto2_cpu_device::eth_startf() |
| 426 | 426 | { |
| 427 | | PUT_ETH_ICMD(m_eth.status, A2_BIT16(m_bus,16,14)); |
| 428 | | PUT_ETH_OCMD(m_eth.status, A2_BIT16(m_bus,16,15)); |
| 427 | PUT_ETH_ICMD(m_eth.status, X_BIT(m_bus,16,14)); |
| 428 | PUT_ETH_OCMD(m_eth.status, X_BIT(m_bus,16,15)); |
| 429 | 429 | if (GET_ETH_ICMD(m_eth.status) || GET_ETH_OCMD(m_eth.status)) |
| 430 | 430 | m_task_wakeup |= 1 << task_ether; |
| 431 | 431 | } |
| r26301 | r26302 | |
| 485 | 485 | */ |
| 486 | 486 | void alto2_cpu_device::f1_early_epfct() |
| 487 | 487 | { |
| 488 | | UINT16 r = ~A2_GET16(m_eth.status,16,10,15) & 0177777; |
| 488 | UINT16 r = ~X_RDBITS(m_eth.status,16,10,15) & 0177777; |
| 489 | 489 | |
| 490 | 490 | LOG((LOG_ETH,3, " ←EPFCT; BUS[8-15] = STATUS (%#o)\n", r)); |
| 491 | 491 | m_bus &= r; |
| r26301 | r26302 | |
| 564 | 564 | void alto2_cpu_device::f2_late_erbfct() |
| 565 | 565 | { |
| 566 | 566 | UINT16 r = 0; |
| 567 | | A2_PUT16(r,10,6,6,GET_ETH_ICMD(m_eth.status)); |
| 568 | | A2_PUT16(r,10,7,7,GET_ETH_OCMD(m_eth.status)); |
| 567 | X_WRBITS(r,10,6,6,GET_ETH_ICMD(m_eth.status)); |
| 568 | X_WRBITS(r,10,7,7,GET_ETH_OCMD(m_eth.status)); |
| 569 | 569 | LOG((LOG_ETH,3, " ERBFCT; NEXT[6-7] = ICMD,OCMD (%#o | %#o)\n", m_next2, r)); |
| 570 | 570 | m_next2 |= r; |
| 571 | 571 | eth_wakeup(); |
| r26301 | r26302 | |
| 602 | 602 | void alto2_cpu_device::f2_late_ebfct() |
| 603 | 603 | { |
| 604 | 604 | UINT16 r = 0; |
| 605 | | A2_PUT16(r,10,6,6, GET_ETH_COLL(m_eth.status)); |
| 606 | | A2_PUT16(r,10,7,7, GET_ETH_IDL(m_eth.status) | |
| 605 | X_WRBITS(r,10,6,6, GET_ETH_COLL(m_eth.status)); |
| 606 | X_WRBITS(r,10,7,7, GET_ETH_IDL(m_eth.status) | |
| 607 | 607 | GET_ETH_ICMD(m_eth.status) | |
| 608 | 608 | GET_ETH_OCMD(m_eth.status) | |
| 609 | 609 | GET_ETH_IGONE(m_eth.status) | |
| r26301 | r26302 | |
| 621 | 621 | { |
| 622 | 622 | UINT16 r = 0; |
| 623 | 623 | /* TODO: the BE' (buffer empty) signal is output D0 of PROM a49 */ |
| 624 | | A2_PUT16(r,10,7,7,ETHER_A49_BE); |
| 624 | X_WRBITS(r,10,7,7,ETHER_A49_BE); |
| 625 | 625 | LOG((LOG_ETH,3, " ECBFCT; NEXT[7] = FIFO %sempty (%#o | %#o)\n", r ? "not " : "is ", m_next2, r)); |
| 626 | 626 | m_next2 |= r; |
| 627 | 627 | } |
branches/alto2/src/emu/cpu/alto2/alto2cpu.h
| r26301 | r26302 | |
| 19 | 19 | |
| 20 | 20 | #define ALTO2_TAG "alto2" |
| 21 | 21 | |
| 22 | /** |
| 23 | * \brief AltoII register names |
| 24 | */ |
| 25 | enum { |
| 26 | // micro code task, micro program counter, next and next2 |
| 27 | A2_TASK, A2_MPC, A2_NEXT, A2_NEXT2, |
| 28 | // BUS, ALU, temp, latch, memory latch and carry flags |
| 29 | A2_BUS, A2_T, A2_ALU, A2_ALUC0, A2_L, A2_SHIFTER, A2_LALUC0, A2_M, |
| 30 | A2_R, // 32 R registers |
| 31 | A2_AC3 = A2_R, A2_AC2, A2_AC1, A2_AC0, A2_R04, A2_R05, A2_PC, A2_R07, |
| 32 | A2_R10, A2_R11, A2_R12, A2_R13, A2_R14, A2_R15, A2_R16, A2_R17, |
| 33 | A2_R20, A2_R21, A2_R22, A2_R23, A2_R24, A2_R25, A2_R26, A2_R27, |
| 34 | A2_R30, A2_R31, A2_R32, A2_R33, A2_R34, A2_R35, A2_R36, A2_R37, |
| 35 | A2_S, // 32 S registers |
| 36 | A2_S00 = A2_S, A2_S01, A2_S02, A2_S03, A2_S04, A2_S05, A2_S06, A2_S07, |
| 37 | A2_S10, A2_S11, A2_S12, A2_S13, A2_S14, A2_S15, A2_S16, A2_S17, |
| 38 | A2_S20, A2_S21, A2_S22, A2_S23, A2_S24, A2_S25, A2_S26, A2_S27, |
| 39 | A2_S30, A2_S31, A2_S32, A2_S33, A2_S34, A2_S35, A2_S36, A2_S37, |
| 40 | // DISK controller registers |
| 41 | A2_DRIVE, A2_KADDR, A2_KADR, A2_KSTAT, A2_KCOM, A2_KRECNO, |
| 42 | A2_SHIFTIN, A2_SHIFTOUT, A2_DATAIN, A2_DATAOUT, A2_KRWC, |
| 43 | A2_KFER, A2_WDTSKENA, A2_WDINIT0, A2_WDINIT, A2_STROBE, |
| 44 | A2_BITCLK, A2_DATIN, A2_BITCNT, A2_CARRY, A2_SECLATE, |
| 45 | A2_SEEKOK, A2_OKTORUN, A2_READY |
| 46 | }; |
| 47 | |
| 22 | 48 | #ifndef ALTO2_DEBUG |
| 23 | 49 | #define ALTO2_DEBUG 0 //!< define to 1 to enable logerror() output |
| 24 | 50 | #endif |
| r26301 | r26302 | |
| 80 | 106 | //! inverted bits in the micro instruction 32 bit word |
| 81 | 107 | #define ALTO2_UCODE_INVERTED ((1 << 10) | (1 << 15) | (1 << 19)) |
| 82 | 108 | |
| 109 | /******************************************************************************** |
| 110 | * Bit field primitives |
| 111 | * These are some macros to make it easier to access variable by the bit- |
| 112 | * reversed notation that the Xerox Alto documents use all over the place. |
| 113 | * Bit number 0 is the most significant there, |
| 114 | * and bit number (width - 1) is the least significant. |
| 115 | * The X_ is for Xerox and to avoid collisions with MAME generic macros. |
| 116 | ********************************************************************************/ |
| 117 | |
| 118 | //! get the left shift required to access bit %to in a word of %width bits |
| 119 | #define X_BITSHIFT(width,to) ((width) - 1 - (to)) |
| 120 | |
| 121 | //! build a least significant bit mask for bits %from to %to (inclusive) |
| 122 | #define X_BITMASK(from,to) ((1ul << ((to) + 1 - (from))) - 1) |
| 123 | |
| 124 | //! get a single bit number %bit value from %reg, a word of %width bits |
| 125 | #define X_BIT(reg,width,bit) (((reg) >> X_BITSHIFT(width,bit)) & 1) |
| 126 | |
| 127 | //! get a bit field from %reg, a word of %width bits, starting at bit %from until bit %to |
| 128 | #define X_RDBITS(reg,width,from,to) (((reg) >> X_BITSHIFT(width,to)) & X_BITMASK(from,to)) |
| 129 | |
| 130 | //! put a value %val into %reg, a word of %width bits, starting at bit %from until bit %to |
| 131 | #define X_WRBITS(reg,width,from,to,val) do { \ |
| 132 | UINT32 mask = X_BITMASK(from,to) << X_BITSHIFT(width,to); \ |
| 133 | reg = ((reg) & ~mask) | (((val) << X_BITSHIFT(width,to)) & mask); \ |
| 134 | } while (0) |
| 135 | |
| 83 | 136 | /** |
| 84 | 137 | * @brief start value for the horizontal line counter |
| 85 | 138 | * |
| r26301 | r26302 | |
| 145 | 198 | #define ALTO2_DISPLAY_FIFO 16 //!< the display fifo has 16 words |
| 146 | 199 | #define ALTO2_DISPLAY_SCANLINE_WORDS (ALTO2_DISPLAY_TOTAL_WIDTH/16) //!< words per scanline |
| 147 | 200 | #define ALTO2_DISPLAY_HEIGHT 808 //!< number of visible scanlines per frame; 808 really, but there are some empty lines? |
| 148 | | #define ALTO2_DISPLAY_WIDTH 606 //!< visible width of the display; 38 words - 2 pixels |
| 201 | #define ALTO2_DISPLAY_WIDTH 606 //!< visible width of the display; 38 x 16 bit words - 2 pixels |
| 149 | 202 | #define ALTO2_DISPLAY_VISIBLE_WORDS ((ALTO2_DISPLAY_WIDTH+15)/16) //!< visible words per scanline |
| 150 | 203 | #define ALTO2_DISPLAY_BITCLOCK 20160000ll //!< display bit clock in in Hertz (20.16MHz) |
| 151 | 204 | #define ALTO2_DISPLAY_BITTIME(n) (U64(1000000000000)*(n)/ALTO2_DISPLAY_BITCLOCK) //!< display bit time in in pico seconds (~= 49.6031ns) |
| 152 | | #define ALTO2_DISPLAY_SCANLINE_TIME ALTO2_DISPLAY_BITTIME(ALTO2_DISPLAY_TOTAL_WIDTH)//!< time for a scanline in pico seconds (768 * 49.6031ns) |
| 153 | | #define ALTO2_DISPLAY_VISIBLE_TIME ALTO2_DISPLAY_BITTIME(ALTO2_DISPLAY_WIDTH) //!< time of the visible part of a scanline in pico seconds (606 * 49.6031ns) |
| 154 | | #define ALTO2_DISPLAY_WORD_TIME ALTO2_DISPLAY_BITTIME(16) //!< time for a word in pico seconds (16 pixels * 49.6031ns) |
| 205 | #define ALTO2_DISPLAY_SCANLINE_TIME ALTO2_DISPLAY_BITTIME(ALTO2_DISPLAY_TOTAL_WIDTH)//!< time for a scanline in pico seconds (768 * 49.6031ns ~= 38095.1808ns) |
| 206 | #define ALTO2_DISPLAY_VISIBLE_TIME ALTO2_DISPLAY_BITTIME(ALTO2_DISPLAY_WIDTH) //!< time of the visible part of a scanline in pico seconds (606 * 49.6031ns ~= 30059.4786ns) |
| 207 | #define ALTO2_DISPLAY_WORD_TIME ALTO2_DISPLAY_BITTIME(16) //!< time for a word in pico seconds (16 pixels * 49.6031ns ~= 793.6496ns) |
| 155 | 208 | #define ALTO2_DISPLAY_VBLANK_TIME ((ALTO2_DISPLAY_TOTAL_HEIGHT-ALTO2_DISPLAY_HEIGHT)*HZ_TO_ATTOSECONDS(26250)) |
| 156 | 209 | |
| 157 | | enum { |
| 158 | | // micro code task, micro program counter, next and next2 |
| 159 | | A2_TASK, A2_MPC, A2_NEXT, A2_NEXT2, |
| 160 | | // BUS, ALU, temp, latch, memory latch and carry flags |
| 161 | | A2_BUS, A2_T, A2_ALU, A2_ALUC0, A2_L, A2_SHIFTER, A2_LALUC0, A2_M, |
| 162 | | // DISK controller registers |
| 163 | | A2_DRIVE, A2_KADDR, A2_KADR, A2_KSTAT, A2_KCOM, A2_KRECNO, |
| 164 | | A2_SHIFTIN, A2_SHIFTOUT, A2_DATAIN, A2_DATAOUT, A2_KRWC, |
| 165 | | A2_KFER, A2_WDTSKENA, A2_WDINIT0, A2_WDINIT, A2_STROBE, |
| 166 | | A2_BITCLK, A2_DATIN, A2_BITCNT, A2_CARRY, A2_SECLATE, |
| 167 | | A2_SEEKOK, A2_OKTORUN, A2_READY, |
| 168 | | A2_R, // 32 R registers |
| 169 | | A2_AC3 = A2_R, A2_AC2, A2_AC1, A2_AC0, A2_R04, A2_R05, A2_PC, A2_R07, |
| 170 | | A2_R10, A2_R11, A2_R12, A2_R13, A2_R14, A2_R15, A2_R16, A2_R17, |
| 171 | | A2_R20, A2_R21, A2_R22, A2_R23, A2_R24, A2_R25, A2_R26, A2_R27, |
| 172 | | A2_R30, A2_R31, A2_R32, A2_R33, A2_R34, A2_R35, A2_R36, A2_R37, |
| 173 | | A2_S, // 32 S registers |
| 174 | | A2_S00 = A2_S, A2_S01, A2_S02, A2_S03, A2_S04, A2_S05, A2_S06, A2_S07, |
| 175 | | A2_S10, A2_S11, A2_S12, A2_S13, A2_S14, A2_S15, A2_S16, A2_S17, |
| 176 | | A2_S20, A2_S21, A2_S22, A2_S23, A2_S24, A2_S25, A2_S26, A2_S27, |
| 177 | | A2_S30, A2_S31, A2_S32, A2_S33, A2_S34, A2_S35, A2_S36, A2_S37 |
| 178 | | }; |
| 179 | | |
| 180 | 210 | /** |
| 181 | 211 | * @brief enumeration of the inputs and outputs of a JK flip-flop type 74109 |
| 182 | 212 | * <PRE> |
| r26301 | r26302 | |
| 347 | 377 | static const UINT8 m_ether_id = 0241; |
| 348 | 378 | |
| 349 | 379 | typedef void (alto2_cpu_device::*a2func)(); |
| 350 | | typedef void (alto2_cpu_device::*a2cb)(int unit); |
| 351 | | typedef void (alto2_cpu_device::*a2io_wr)(UINT32 addr, UINT16 data); |
| 352 | | typedef UINT16 (alto2_cpu_device::*a2io_rd)(UINT32 addr); |
| 353 | 380 | |
| 354 | 381 | //! task numbers |
| 355 | 382 | enum { |
| r26301 | r26302 | |
| 411 | 438 | enum { |
| 412 | 439 | /** |
| 413 | 440 | * \brief 00: ALU <- BUS |
| 414 | | * PROM data for S3-0,M,C: 1111/1/0 |
| 441 | * PROM data for S3-0,M,C,T: 1111/1/0/0 |
| 415 | 442 | * function F=A |
| 416 | 443 | * T source is ALU |
| 417 | 444 | */ |
| 418 | 445 | aluf_bus__alut, |
| 419 | 446 | /** |
| 420 | 447 | * \brief 01: ALU <- T |
| 421 | | * PROM data for S3-0,M,C: 1010/1/0 |
| 448 | * PROM data for S3-0,M,C,T: 1010/1/0/0 |
| 422 | 449 | * function F=B |
| 423 | 450 | * T source is BUS |
| 424 | 451 | */ |
| 425 | 452 | aluf_treg, |
| 426 | 453 | /** |
| 427 | 454 | * \brief 02: ALU <- BUS | T |
| 428 | | * PROM data for S3-0,M,C: 1110/1/0 |
| 455 | * PROM data for S3-0,M,C,T: 1110/1/0/1 |
| 429 | 456 | * function F=A|B |
| 430 | 457 | * T source is ALU |
| 431 | 458 | */ |
| 432 | 459 | aluf_bus_or_t__alut, |
| 433 | 460 | /** |
| 434 | 461 | * \brief 03: ALU <- BUS & T |
| 435 | | * PROM data for S3-0,M,C: 1011/1/0 |
| 462 | * PROM data for S3-0,M,C,T: 1011/1/0/0 |
| 436 | 463 | * function F=A&B |
| 437 | 464 | * T source is BUS |
| 438 | 465 | */ |
| 439 | 466 | aluf_bus_and_t, |
| 440 | 467 | /** |
| 441 | 468 | * \brief 04: ALU <- BUS ^ T |
| 442 | | * PROM data for S3-0,M,C: 0110/1/0 |
| 469 | * PROM data for S3-0,M,C,T: 0110/1/0/0 |
| 443 | 470 | * function F=A^B |
| 444 | 471 | * T source is BUS |
| 445 | 472 | */ |
| 446 | 473 | aluf_bus_xor_t, |
| 447 | 474 | /** |
| 448 | 475 | * \brief 05: ALU <- BUS + 1 |
| 449 | | * PROM data for S3-0,M,C: 0000/0/0 |
| 476 | * PROM data for S3-0,M,C,T: 0000/0/0/1 |
| 450 | 477 | * function F=A+1 |
| 451 | 478 | * T source is ALU |
| 452 | 479 | */ |
| 453 | 480 | aluf_bus_plus_1__alut, |
| 454 | 481 | /** |
| 455 | 482 | * \brief 06: ALU <- BUS - 1 |
| 456 | | * PROM data for S3-0,M,C: 1111/0/1 |
| 483 | * PROM data for S3-0,M,C,T: 1111/0/1/1 |
| 457 | 484 | * function F=A-1 |
| 458 | 485 | * T source is ALU |
| 459 | 486 | */ |
| 460 | 487 | aluf_bus_minus_1__alut, |
| 461 | 488 | /** |
| 462 | 489 | * \brief 07: ALU <- BUS + T |
| 463 | | * PROM data for S3-0,M,C: 1001/0/1 |
| 490 | * PROM data for S3-0,M,C,T: 1001/0/1/0 |
| 464 | 491 | * function F=A+B |
| 465 | 492 | * T source is BUS |
| 466 | 493 | */ |
| 467 | 494 | aluf_bus_plus_t, |
| 468 | 495 | /** |
| 469 | 496 | * \brief 10: ALU <- BUS - T |
| 470 | | * PROM data for S3-0,M,C: 0110/0/0 |
| 497 | * PROM data for S3-0,M,C,T: 0110/0/0/0 |
| 471 | 498 | * function F=A-B |
| 472 | 499 | * T source is BUS |
| 473 | 500 | */ |
| 474 | 501 | aluf_bus_minus_t, |
| 475 | 502 | /** |
| 476 | 503 | * \brief 11: ALU <- BUS - T - 1 |
| 477 | | * PROM data for S3-0,M,C: 0110/0/1 |
| 504 | * PROM data for S3-0,M,C,T: 0110/0/1/0 |
| 478 | 505 | * function F=A-B-1 |
| 479 | 506 | * T source is BUS |
| 480 | 507 | */ |
| r26301 | r26302 | |
| 488 | 515 | aluf_bus_plus_t_plus_1__alut, |
| 489 | 516 | /** |
| 490 | 517 | * \brief 13: ALU <- BUS + SKIP |
| 491 | | * PROM data for S3-0,M,C: 0000/0/SKIP |
| 518 | * PROM data for S3-0,M,C,T: 0000/0/SKIP/1 |
| 492 | 519 | * function F=A (SKIP=1) or F=A+1 (SKIP=0) |
| 493 | 520 | * T source is ALU |
| 494 | 521 | */ |
| 495 | 522 | aluf_bus_plus_skip__alut, |
| 496 | 523 | /** |
| 497 | 524 | * \brief 14: ALU <- BUS & T |
| 498 | | * PROM data for S3-0,M,C: 1011/1/0 |
| 525 | * PROM data for S3-0,M,C,T: 1011/1/0/1 |
| 499 | 526 | * function F=A&B |
| 500 | 527 | * T source is ALU |
| 501 | 528 | */ |
| 502 | 529 | aluf_bus_and_t__alut, |
| 503 | 530 | /** |
| 504 | 531 | * \brief 15: ALU <- BUS & ~T |
| 505 | | * PROM data for S3-0,M,C: 0111/1/0 |
| 532 | * PROM data for S3-0,M,C,T: 0111/1/0/0 |
| 506 | 533 | * function F=A&~B |
| 507 | 534 | * T source is BUS |
| 508 | 535 | */ |
| 509 | 536 | aluf_bus_and_not_t, |
| 510 | 537 | /** |
| 511 | | * \brief 16: ALU <- ??? |
| 512 | | * PROM data for S3-0,M,C: ????/?/? |
| 513 | | * perhaps F=0 (0011/0/0) |
| 514 | | * T source is BUS |
| 538 | * \brief 16: ALU <- BUS |
| 539 | * PROM data for S3-0,M,C,T: 1111/1/0/1 |
| 540 | * function F=A |
| 541 | * T source is ALU |
| 515 | 542 | */ |
| 516 | 543 | aluf_undef_16, |
| 517 | 544 | /** |
| 518 | | * \brief 17: ALU <- ??? |
| 519 | | * PROM data for S3-0,M,C: ????/?/? |
| 520 | | * perhaps F=0 (0011/0/0) |
| 521 | | * T source is BUS |
| 545 | * \brief 17: ALU <- BUS |
| 546 | * PROM data for S3-0,M,C,T: 1111/1/0/1 |
| 547 | * function F=A |
| 548 | * T source is ALU |
| 522 | 549 | */ |
| 523 | 550 | aluf_undef_17 |
| 524 | 551 | }; |
| r26301 | r26302 | |
| 670 | 697 | f2_kwd_strobon = f2_task_16, //!< f2 (1110) kwd: branches NEXT[9] on STROBE |
| 671 | 698 | }; |
| 672 | 699 | |
| 673 | | enum { |
| 674 | | p_dynamic, //!< dynamic functions (e.g. ALU and SHIFTER operations) |
| 675 | | p_latches //!< latching function (T, L, M, R, etc. register latch) |
| 676 | | }; |
| 677 | | |
| 678 | | |
| 679 | | /** |
| 680 | | * Bit field primitives |
| 681 | | * These are some inline functions to make it easier to access variable by the |
| 682 | | * bit-reversed notation that the Xerox Alto documents use all over the place. |
| 683 | | * Bit number 0 is the most significant there, and bit number (width - 1) |
| 684 | | * is the least significant. |
| 685 | | */ |
| 686 | | |
| 687 | | //! get the left shift required to access bit %to in a word of %width bits |
| 688 | | static inline UINT8 A2_BITSHIFT(UINT8 width, UINT8 to) { return width - 1 - to; } |
| 689 | | |
| 690 | | //! build a least significant bit mask for bits %from to %to (inclusive) |
| 691 | | static inline UINT32 A2_BITMASK(UINT8 from, UINT8 to) { return (1ul << (to + 1 - from)) - 1; } |
| 692 | | |
| 693 | | //! get a single bit number %bit value from %reg, a word of %width bits |
| 694 | | static inline UINT8 A2_BIT8(UINT8 reg, UINT8 width, UINT8 bit) { return (reg >> A2_BITSHIFT(width,bit)) & 1; } |
| 695 | | |
| 696 | | //! get a bit field from %reg, a word of %width bits, starting at bit %from until bit %to |
| 697 | | static inline UINT8 A2_GET8(UINT8 reg, UINT8 width, UINT8 from, UINT8 to) { return (reg >> A2_BITSHIFT(width,to)) & A2_BITMASK(from,to); } |
| 698 | | |
| 699 | | //! put a value %val into %reg, a word of %width bits, starting at bit %from until bit %to |
| 700 | | static inline void A2_PUT8(UINT8& reg, UINT8 width, UINT8 from, UINT8 to, UINT8 val) { |
| 701 | | UINT8 mask = A2_BITMASK(from,to) << A2_BITSHIFT(width,to); |
| 702 | | reg = (reg & ~mask) | ((val << A2_BITSHIFT(width,to)) & mask); |
| 703 | | } |
| 704 | | |
| 705 | | //! get a single bit number %bit value from %reg, a word of %width bits |
| 706 | | static inline UINT16 A2_BIT16(UINT16 reg, UINT8 width, UINT8 bit) { return (reg >> A2_BITSHIFT(width,bit)) & 1; } |
| 707 | | |
| 708 | | //! get a bit field from %reg, a word of %width bits, starting at bit %from until bit %to |
| 709 | | static inline UINT16 A2_GET16(UINT16 reg, UINT8 width, UINT8 from, UINT8 to) { return (reg >> A2_BITSHIFT(width,to)) & A2_BITMASK(from,to); } |
| 710 | | |
| 711 | | //! put a value %val into %reg, a word of %width bits, starting at bit %from until bit %to |
| 712 | | static inline void A2_PUT16(UINT16& reg, UINT8 width, UINT8 from, UINT8 to, UINT16 val) { |
| 713 | | UINT16 mask = A2_BITMASK(from,to) << A2_BITSHIFT(width,to); |
| 714 | | reg = (reg & ~mask) | ((val << A2_BITSHIFT(width,to)) & mask); |
| 715 | | } |
| 716 | | |
| 717 | | //! get a single bit number %bit value from %reg, a word of %width bits |
| 718 | | static inline UINT32 A2_BIT32(UINT32 reg, UINT8 width, UINT8 bit) { return (reg >> A2_BITSHIFT(width,bit)) & 1; } |
| 719 | | |
| 720 | | //! get a bit field from %reg, a word of %width bits, starting at bit %from until bit %to |
| 721 | | static inline UINT32 A2_GET32(UINT32 reg, UINT8 width, UINT8 from, UINT8 to) { return (reg >> A2_BITSHIFT(width,to)) & A2_BITMASK(from,to); } |
| 722 | | |
| 723 | | //! put a value %val into %reg, a word of %width bits, starting at bit %from until bit %to |
| 724 | | static inline void A2_PUT32(UINT32& reg, UINT8 width, UINT8 from, UINT8 to, UINT32 val) { |
| 725 | | UINT32 mask = A2_BITMASK(from,to) << A2_BITSHIFT(width,to); |
| 726 | | reg = (reg & ~mask) | ((val << A2_BITSHIFT(width,to)) & mask); |
| 727 | | } |
| 728 | | |
| 729 | 700 | //! enumeration of the micro code word bits |
| 730 | 701 | //! Note: The Alto documents enumerate bits from left (MSB = 0) to right (LSB = 31) |
| 731 | 702 | enum { |
| r26301 | r26302 | |
| 734 | 705 | DBS0, DBS1, DBS2, |
| 735 | 706 | DF1_0, DF1_1, DF1_2, DF1_3, |
| 736 | 707 | DF2_0, DF2_1, DF2_2, DF2_3, |
| 737 | | LOADT, |
| 738 | | LOADL, |
| 708 | DLOADT, |
| 709 | DLOADL, |
| 739 | 710 | NEXT0, NEXT1, NEXT2, NEXT3, NEXT4, NEXT5, NEXT6, NEXT7, NEXT8, NEXT9 |
| 740 | 711 | }; |
| 741 | 712 | |
| 742 | | //! get the RSEL value from a micro instruction word |
| 743 | | static inline UINT32 MIR_RSEL(UINT32 mir) { return A2_GET32(mir, 32, DRSEL0, DRSEL4); } |
| 744 | | |
| 745 | | //! get the ALUF value from a micro instruction word |
| 746 | | static inline UINT32 MIR_ALUF(UINT32 mir) { return A2_GET32(mir, 32, DALUF0, DALUF3); } |
| 747 | | |
| 748 | | //! get the BS value from a micro instruction word |
| 749 | | static inline UINT32 MIR_BS(UINT32 mir) { return A2_GET32(mir, 32, DBS0, DBS2); } |
| 750 | | |
| 751 | | //! get the F1 value from a micro instruction word |
| 752 | | static inline UINT32 MIR_F1(UINT32 mir) { return A2_GET32(mir, 32, DF1_0, DF1_3); } |
| 753 | | |
| 754 | | //! get the F2 value from a micro instruction word |
| 755 | | static inline UINT32 MIR_F2(UINT32 mir) { return A2_GET32(mir, 32, DF2_0, DF2_3); } |
| 756 | | |
| 757 | | //! get the T value from a micro instruction word |
| 758 | | static inline UINT32 MIR_T(UINT32 mir) { return A2_BIT32(mir, 32, LOADT); } |
| 759 | | |
| 760 | | //! get the L value from a micro instruction word |
| 761 | | static inline UINT32 MIR_L(UINT32 mir) { return A2_BIT32(mir, 32, LOADL); } |
| 762 | | |
| 763 | | //! get the NEXT value from a micro instruction word |
| 764 | | static inline UINT32 MIR_NEXT(UINT32 mir) { return A2_GET32(mir, 32, NEXT0, NEXT9); } |
| 765 | | |
| 766 | 713 | //! get the normally accessed bank number from a bank register |
| 767 | | static inline UINT16 GET_BANK_NORMAL(UINT16 breg) { return A2_GET16(breg,16,12,13); } |
| 714 | static inline UINT16 GET_BANK_NORMAL(UINT16 breg) { return X_RDBITS(breg,16,12,13); } |
| 768 | 715 | |
| 769 | 716 | //! get the extended bank number (accessed via XMAR) from a bank register |
| 770 | | static inline UINT16 GET_BANK_EXTENDED(UINT16 breg) { return A2_GET16(breg,16,14,15); } |
| 717 | static inline UINT16 GET_BANK_EXTENDED(UINT16 breg) { return X_RDBITS(breg,16,14,15); } |
| 771 | 718 | |
| 772 | 719 | //! get an ignored bit field from a control RAM address |
| 773 | | static inline UINT16 GET_CRAM_IGNORE(UINT16 addr) { return A2_GET16(addr,16,0,1); } |
| 720 | static inline UINT16 GET_CRAM_IGNORE(UINT16 addr) { return X_RDBITS(addr,16,0,1); } |
| 774 | 721 | |
| 775 | 722 | //! get the bank select bit field from a control RAM address |
| 776 | | static inline UINT16 GET_CRAM_BANKSEL(UINT16 addr) { return A2_GET16(addr,16,2,3); } |
| 723 | static inline UINT16 GET_CRAM_BANKSEL(UINT16 addr) { return X_RDBITS(addr,16,2,3); } |
| 777 | 724 | |
| 778 | 725 | //! get the ROM/RAM flag from a control RAM address |
| 779 | | static inline UINT16 GET_CRAM_RAMROM(UINT16 addr) { return A2_GET16(addr,16,4,4); } |
| 726 | static inline UINT16 GET_CRAM_RAMROM(UINT16 addr) { return X_RDBITS(addr,16,4,4); } |
| 780 | 727 | |
| 781 | 728 | //! get the half select flag from a control RAM address |
| 782 | | static inline UINT16 GET_CRAM_HALFSEL(UINT16 addr) { return A2_GET16(addr,16,5,5); } |
| 729 | static inline UINT16 GET_CRAM_HALFSEL(UINT16 addr) { return X_RDBITS(addr,16,5,5); } |
| 783 | 730 | |
| 784 | 731 | //! get the word address bit field from a control RAM address |
| 785 | | static inline UINT16 GET_CRAM_WORDADDR(UINT16 addr) { return A2_GET16(addr,16,6,15); } |
| 732 | static inline UINT16 GET_CRAM_WORDADDR(UINT16 addr) { return X_RDBITS(addr,16,6,15); } |
| 786 | 733 | |
| 787 | 734 | UINT16 m_task_mpc[ALTO2_TASKS]; //!< per task micro program counter |
| 788 | 735 | UINT16 m_task_next2[ALTO2_TASKS]; //!< per task address modifier |
| r26301 | r26302 | |
| 796 | 743 | /** |
| 797 | 744 | * \brief current micro instruction's register selection |
| 798 | 745 | * The emulator F2s ACSOURCE and ACDEST modify this. |
| 799 | | * Note: S registers are addressed by the original RSEL[0-4], |
| 746 | * Note: The S registers are addressed by the original RSEL[0-4], |
| 800 | 747 | * even when the the emulator modifies this. |
| 801 | 748 | */ |
| 802 | 749 | UINT8 m_rsel; |
| 803 | | |
| 750 | UINT8 m_d_rsel; //!< decoded RSEL[0-4] |
| 751 | UINT8 m_d_aluf; //!< decoded ALUF[0-3] function |
| 752 | UINT8 m_d_bs; //!< decoded BS[0-2] bus source |
| 753 | UINT8 m_d_f1; //!< decoded F1[0-3] function |
| 754 | UINT8 m_d_f2; //!< decoded F2[0-3] function |
| 755 | UINT8 m_d_loadt; //!< decoded LOADT flag |
| 756 | UINT8 m_d_loadl; //!< decoded LOADL flag |
| 804 | 757 | UINT16 m_next; //!< current micro instruction's next |
| 805 | 758 | UINT16 m_next2; //!< next micro instruction's next |
| 806 | 759 | UINT16 m_r[ALTO2_REGS]; //!< R register file |
| r26301 | r26302 | |
| 1101 | 1054 | void bs_early_read_md(); //!< bus source: drive BUS from read memory data |
| 1102 | 1055 | void bs_early_mouse(); //!< bus source: drive bus by mouse |
| 1103 | 1056 | void bs_early_disp(); //!< bus source: drive bus by displacement (which?) |
| 1057 | void f1_early_block(); //!< F1 func: block active task |
| 1104 | 1058 | void f1_late_load_mar(); //!< F1 func: load memory address register |
| 1105 | 1059 | void f1_early_task(); //!< F1 func: task switch |
| 1106 | 1060 | void f1_late_l_lsh_1(); //!< F1 func: SHIFTER = left shift L once |
| r26301 | r26302 | |
| 1139 | 1093 | void init_ram(int task); //!< called by RAM related tasks |
| 1140 | 1094 | void exit_ram(); |
| 1141 | 1095 | |
| 1096 | # include "a2hw.h" |
| 1142 | 1097 | // ************************************************ |
| 1143 | | // memory mapped i/o stuff |
| 1144 | | // ************************************************ |
| 1145 | | /** |
| 1146 | | * @brief get printer paper ready bit |
| 1147 | | * Paper ready bit. 0 when the printer is ready for a paper scrolling operation. |
| 1148 | | */ |
| 1149 | | static inline UINT16 GET_PPRDY(UINT16 utilin) { return A2_GET16(utilin,16,0,0); } |
| 1150 | | |
| 1151 | | /** @brief put printer paper ready bit */ |
| 1152 | | static inline void PUT_PPRDY(UINT16& utilin, UINT16 val) { A2_PUT16(utilin,16,0,0,val); } |
| 1153 | | |
| 1154 | | /** |
| 1155 | | * @brief get printer check bit |
| 1156 | | * Printer check bit bit. Should the printer find itself in an abnormal state, |
| 1157 | | * it sets this bit to 0 |
| 1158 | | */ |
| 1159 | | static inline UINT16 GET_PCHECK(UINT16 utilin) { return A2_GET16(utilin,16,1,1); } |
| 1160 | | |
| 1161 | | /** @brief put printer check bit */ |
| 1162 | | static inline void PUT_PCHECK(UINT16& utilin, UINT16 val) { A2_PUT16(utilin,16,1,1,val); } |
| 1163 | | |
| 1164 | | /** @brief get unused bit 2 */ |
| 1165 | | static inline UINT16 GET_UNUSED_2(UINT16 utilin) { return A2_GET16(utilin,16,2,2); } |
| 1166 | | |
| 1167 | | /** @brief put unused bit 2 */ |
| 1168 | | static inline void PUT_UNUSED_2(UINT16& utilin, UINT16 val) { A2_PUT16(utilin,16,2,2,val); } |
| 1169 | | |
| 1170 | | /** |
| 1171 | | * @brief get printer daisy ready bit |
| 1172 | | * Daisy ready bit. 0 when the printer is ready to print a character. |
| 1173 | | */ |
| 1174 | | static inline UINT16 GET_PCHRDY(UINT16 utilin) { return A2_GET16(utilin,16,3,3); } |
| 1175 | | |
| 1176 | | /** @brief put printer daisy ready bit */ |
| 1177 | | static inline void PUT_PCHRDY(UINT16& utilin, UINT16 val) { A2_PUT16(utilin,16,3,3,val); } |
| 1178 | | |
| 1179 | | /** |
| 1180 | | * @brief get printer carriage ready bit |
| 1181 | | * Carriage ready bit. 0 when the printer is ready for horizontal positioning. |
| 1182 | | */ |
| 1183 | | static inline UINT16 GET_PCARRDY(UINT16 utilin) { return A2_GET16(utilin,16,4,4); } |
| 1184 | | |
| 1185 | | /** @brief put printer carriage ready bit */ |
| 1186 | | static inline void PUT_PCARRDY(UINT16& utilin, UINT16 val) { A2_PUT16(utilin,16,4,4,val); } |
| 1187 | | |
| 1188 | | /** |
| 1189 | | * @brief get printer ready bit |
| 1190 | | * Ready bit. Both this bit and the appropriate other ready bit (carriage, |
| 1191 | | * daisy, etc.) must be 0 before attempting any output operation. |
| 1192 | | */ |
| 1193 | | static inline UINT16 GET_PREADY(UINT16 utilin) { return A2_GET16(utilin,16,5,5); } |
| 1194 | | |
| 1195 | | /** @brief put printer ready bit */ |
| 1196 | | static inline void PUT_PREADY(UINT16& utilin, UINT16 val) { A2_PUT16(utilin,16,5,5,val); } |
| 1197 | | |
| 1198 | | /** |
| 1199 | | * @brief memory configuration switch |
| 1200 | | */ |
| 1201 | | static inline UINT16 GET_MEMCONFIG(UINT16 utilin) { return A2_GET16(utilin,16,6,6); } |
| 1202 | | |
| 1203 | | /** @brief put memory configuration switch */ |
| 1204 | | static inline void PUT_MEMCONFIG(UINT16& utilin, UINT16 val) { A2_PUT16(utilin,16,6,6,val); } |
| 1205 | | |
| 1206 | | /** @brief get unused bit 7 */ |
| 1207 | | static inline UINT16 GET_UNUSED_7(UINT16 utilin) { return A2_GET16(utilin,16,7,7); } |
| 1208 | | /** @brief put unused bit 7 */ |
| 1209 | | static inline void PUT_UNUSED_7(UINT16& utilin, UINT16 val) { A2_PUT16(utilin,16,7,7,val); } |
| 1210 | | |
| 1211 | | /** @brief get key set key 0 */ |
| 1212 | | static inline UINT16 GET_KEYSET_KEY0(UINT16 utilin) { return A2_GET16(utilin,16,8,8); } |
| 1213 | | /** @brief put key set key 0 */ |
| 1214 | | static inline void PUT_KEYSET_KEY0(UINT16& utilin, UINT16 val) { A2_PUT16(utilin,16,8,8,val); } |
| 1215 | | |
| 1216 | | /** @brief get key set key 1 */ |
| 1217 | | static inline UINT16 GET_KEYSET_KEY1(UINT16 utilin) { return A2_GET16(utilin,16,9,9); } |
| 1218 | | /** @brief put key set key 1 */ |
| 1219 | | static inline void PUT_KEYSET_KEY1(UINT16& utilin, UINT16 val) { A2_PUT16(utilin,16,9,9,val); } |
| 1220 | | |
| 1221 | | /** @brief get key set key 2 */ |
| 1222 | | static inline UINT16 GET_KEYSET_KEY2(UINT16 utilin) { return A2_GET16(utilin,16,10,10); } |
| 1223 | | /** @brief put key set key 2 */ |
| 1224 | | static inline void PUT_KEYSET_KEY2(UINT16& utilin, UINT16 val) { A2_PUT16(utilin,16,10,10,val); } |
| 1225 | | |
| 1226 | | /** @brief get key set key 3 */ |
| 1227 | | static inline UINT16 GET_KEYSET_KEY3(UINT16 utilin) { return A2_GET16(utilin,16,11,11); } |
| 1228 | | /** @brief put key set key 3 */ |
| 1229 | | static inline void PUT_KEYSET_KEY3(UINT16& utilin, UINT16 val) { A2_PUT16(utilin,16,11,11,val); } |
| 1230 | | |
| 1231 | | /** @brief get key set key 4 */ |
| 1232 | | static inline UINT16 GET_KEYSET_KEY4(UINT16 utilin) { return A2_GET16(utilin,16,12,12); } |
| 1233 | | /** @brief put key set key 4 */ |
| 1234 | | static inline void PUT_KEYSET_KEY4(UINT16& utilin, UINT16 val) { A2_PUT16(utilin,16,12,12,val); } |
| 1235 | | |
| 1236 | | /** @brief get mouse red button bit */ |
| 1237 | | static inline UINT16 GET_MOUSE_RED(UINT16 utilin) { return A2_GET16(utilin,16,13,13); } |
| 1238 | | /** @brief put mouse red button bit */ |
| 1239 | | static inline void PUT_MOUSE_RED(UINT16& utilin, UINT16 val) { A2_PUT16(utilin,16,13,13,val); } |
| 1240 | | |
| 1241 | | /** @brief get mouse blue button bit */ |
| 1242 | | static inline UINT16 GET_MOUSE_BLUE(UINT16 utilin) { return A2_GET16(utilin,16,14,14); } |
| 1243 | | /** @brief put mouse blue button bit */ |
| 1244 | | static inline void PUT_MOUSE_BLUE(UINT16& utilin, UINT16 val) { A2_PUT16(utilin,16,14,14,val); } |
| 1245 | | |
| 1246 | | /** @brief get mouse yellow button bit */ |
| 1247 | | static inline UINT16 GET_MOUSE_YELLOW(UINT16 utilin) { return A2_GET16(utilin,16,15,15); } |
| 1248 | | /** @brief put mouse yellow button bit */ |
| 1249 | | static inline void PUT_MOUSE_YELLOW(UINT16& utilin, UINT16 val) { A2_PUT16(utilin,16,15,15,val); } |
| 1250 | | |
| 1251 | | /** @brief put mouse bits */ |
| 1252 | | static inline void PUT_MOUSE(UINT16& utilin, UINT16 val) { A2_PUT16(utilin,16,13,15,val); } |
| 1253 | | |
| 1254 | | /** |
| 1255 | | * @brief printer paper strobe bit |
| 1256 | | * Paper strobe bit. Toggling this bit causes a paper scrolling operation. |
| 1257 | | */ |
| 1258 | | static inline UINT16 GET_PPPSTR(UINT16 utilout) { return A2_GET16(utilout,16,0,0); } |
| 1259 | | |
| 1260 | | /** |
| 1261 | | * @brief printer retstore bit |
| 1262 | | * Restore bit. Toggling this bit resets the printer (including clearing |
| 1263 | | * the "check" condition if present) and moves the carriage to the |
| 1264 | | * left margin. |
| 1265 | | */ |
| 1266 | | static inline UINT16 GET_PREST(UINT16 utilout) { return A2_GET16(utilout,16,1,1); } |
| 1267 | | |
| 1268 | | /** |
| 1269 | | * @brief printer ribbon bit |
| 1270 | | * Ribbon bit. When this bit is 1 the ribbon is up (in printing |
| 1271 | | * position); when 0, it is down. |
| 1272 | | */ |
| 1273 | | static inline UINT16 GET_PRIB(UINT16 utilout) { return A2_GET16(utilout,16,2,2); } |
| 1274 | | |
| 1275 | | /** |
| 1276 | | * @brief printer daisy strobe bit |
| 1277 | | * Daisy strobe bit. Toggling this bit causes a character to be printed. |
| 1278 | | */ |
| 1279 | | static inline UINT16 GET_PCHSTR(UINT16 utilout) { return A2_GET16(utilout,16,3,3); } |
| 1280 | | |
| 1281 | | /** |
| 1282 | | * @brief printer carriage strobe bit |
| 1283 | | * Carriage strobe bit. Toggling this bit causes a horizontal position operation. |
| 1284 | | */ |
| 1285 | | static inline UINT16 GET_PCARSTR(UINT16 utilout) { return A2_GET16(utilout,16,4,4); } |
| 1286 | | |
| 1287 | | /** |
| 1288 | | * @brief printer data |
| 1289 | | * Argument to various output operations: |
| 1290 | | * 1. Printing characters. When the daisy bit is toggled bits 9-15 of this field |
| 1291 | | * are interpreted as an ASCII character code to be printed (it should be noted |
| 1292 | | * that all codes less than 040 print as lower case "w"). |
| 1293 | | * 2. For paper and carriage operations the field is interpreted as a displacement |
| 1294 | | * (-1024 to +1023), in units of 1/48 inch for paper and 1/60 inch for carriage. |
| 1295 | | * Positive is down or to the right, negative up or to the left. The value is |
| 1296 | | * represented as sign-magnitude (i.e., bit 5 is 1 for negative numbers, 0 for |
| 1297 | | * positive; bits 6-15 are the absolute value of the number). |
| 1298 | | */ |
| 1299 | | static inline UINT16 GET_PDATA(UINT16 utilout) { return A2_GET16(utilout,16,5,15); } |
| 1300 | | |
| 1301 | | /** @brief miscellaneous hardware registers in the memory mapped I/O range */ |
| 1302 | | struct { |
| 1303 | | UINT16 eia; //!< the EIA port at 0177001 |
| 1304 | | UINT16 utilout; //!< the UTILOUT port at 0177016 (active-low outputs) */ |
| 1305 | | UINT16 xbus[4]; //!< the XBUS port at 0177020 to 0177023 |
| 1306 | | UINT16 utilin; //!< the UTILIN port at 0177030 to 0177033 (same value on all addresses) |
| 1307 | | } m_hw; |
| 1308 | | |
| 1309 | | DECLARE_READ16_MEMBER( utilin_r ); //!< read an UTILIN address |
| 1310 | | DECLARE_READ16_MEMBER( utilout_r ); //!< read the UTILOUT address |
| 1311 | | DECLARE_WRITE16_MEMBER( utilout_w ); //!< write the UTILOUT address |
| 1312 | | DECLARE_READ16_MEMBER( xbus_r ); //!< read an XBUS address |
| 1313 | | DECLARE_WRITE16_MEMBER( xbus_w ); //!< write an XBUS address (?) |
| 1314 | | void init_hw(); //!< initialize miscellaneous hardware |
| 1315 | | void exit_hw(); //!< deinitialize miscellaneous hardware |
| 1316 | | |
| 1317 | | // ************************************************ |
| 1318 | 1098 | // keyboard stuff |
| 1319 | 1099 | // ************************************************ |
| 1320 | 1100 | struct { |
branches/alto2/src/emu/cpu/alto2/a2hw.c
| r26301 | r26302 | |
| 10 | 10 | #include "alto2cpu.h" |
| 11 | 11 | |
| 12 | 12 | /** |
| 13 | * @brief read printer paper ready bit |
| 14 | * Paper ready bit. 0 when the printer is ready for a paper scrolling operation. |
| 15 | */ |
| 16 | READ16_MEMBER ( alto2_cpu_device::pprdy_r ) { return X_RDBITS(m_hw.utilin,16,0,0); } |
| 17 | |
| 18 | /** |
| 19 | * @brief read printer check bit |
| 20 | * Printer check bit bit. |
| 21 | * Should the printer find itself in an abnormal state, it sets this bit to 0 |
| 22 | */ |
| 23 | READ16_MEMBER ( alto2_cpu_device::pcheck_r ) { return X_RDBITS(m_hw.utilin,16,1,1); } |
| 24 | |
| 25 | /** |
| 26 | * @brief read unused bit 2 |
| 27 | */ |
| 28 | READ16_MEMBER ( alto2_cpu_device::unused2_r ) { return X_RDBITS(m_hw.utilin,16,2,2); } |
| 29 | |
| 30 | /** |
| 31 | * @brief read printer daisy ready bit |
| 32 | * Daisy ready bit. 0 when the printer is ready to print a character. |
| 33 | */ |
| 34 | READ16_MEMBER ( alto2_cpu_device::pchrdy_r ) { return X_RDBITS(m_hw.utilin,16,3,3); } |
| 35 | |
| 36 | /** |
| 37 | * @brief read printer carriage ready bit |
| 38 | * Carriage ready bit. 0 when the printer is ready for horizontal positioning. |
| 39 | */ |
| 40 | READ16_MEMBER ( alto2_cpu_device::parrdy_r ) { return X_RDBITS(m_hw.utilin,16,4,4); } |
| 41 | |
| 42 | /** |
| 43 | * @brief read printer ready bit |
| 44 | * Ready bit. Both this bit and the appropriate other ready bit (carriage, |
| 45 | * daisy, etc.) must be 0 before attempting any output operation. |
| 46 | */ |
| 47 | READ16_MEMBER ( alto2_cpu_device::pready_r ) { return X_RDBITS(m_hw.utilin,16,5,5); } |
| 48 | |
| 49 | /** |
| 50 | * @brief memory configuration switch |
| 51 | */ |
| 52 | READ16_MEMBER ( alto2_cpu_device::memconfig_r ) { return X_RDBITS(m_hw.utilin,16,6,6); } |
| 53 | |
| 54 | /** |
| 55 | * @brief get unused bit 7 |
| 56 | */ |
| 57 | READ16_MEMBER ( alto2_cpu_device::unused7_r ) { return X_RDBITS(m_hw.utilin,16,7,7); } |
| 58 | |
| 59 | /** |
| 60 | * @brief get key set key 0 |
| 61 | */ |
| 62 | READ16_MEMBER ( alto2_cpu_device::keyset_key0_r ) { return X_RDBITS(m_hw.utilin,16,8,8); } |
| 63 | |
| 64 | /** |
| 65 | * @brief get key set key 1 |
| 66 | */ |
| 67 | READ16_MEMBER ( alto2_cpu_device::keyset_key1_r ) { return X_RDBITS(m_hw.utilin,16,9,9); } |
| 68 | |
| 69 | /** |
| 70 | * @brief get key set key 2 |
| 71 | */ |
| 72 | READ16_MEMBER ( alto2_cpu_device::keyset_key2_r ) { return X_RDBITS(m_hw.utilin,16,10,10); } |
| 73 | |
| 74 | /** |
| 75 | * @brief get key set key 3 |
| 76 | */ |
| 77 | READ16_MEMBER ( alto2_cpu_device::keyset_key3_r ) { return X_RDBITS(m_hw.utilin,16,11,11); } |
| 78 | |
| 79 | /** |
| 80 | * @brief get key set key 4 |
| 81 | */ |
| 82 | READ16_MEMBER ( alto2_cpu_device::keyset_key4_r ) { return X_RDBITS(m_hw.utilin,16,12,12); } |
| 83 | |
| 84 | /** |
| 85 | * @brief get mouse red button bit |
| 86 | */ |
| 87 | READ16_MEMBER ( alto2_cpu_device::mouse_red_r ) { return X_RDBITS(m_hw.utilin,16,13,13); } |
| 88 | |
| 89 | /** |
| 90 | * @brief get mouse blue button bit |
| 91 | */ |
| 92 | READ16_MEMBER ( alto2_cpu_device::mouse_blue_r ) { return X_RDBITS(m_hw.utilin,16,14,14); } |
| 93 | |
| 94 | /** |
| 95 | * @brief get mouse yellow button bit |
| 96 | */ |
| 97 | READ16_MEMBER ( alto2_cpu_device::mouse_yellow_r ) { return X_RDBITS(m_hw.utilin,16,15,15); } |
| 98 | |
| 99 | /** |
| 100 | * @brief write printer paper ready bit |
| 101 | */ |
| 102 | WRITE16_MEMBER( alto2_cpu_device::pprdy_w ) { X_WRBITS(m_hw.utilin,16,0,0,data); } |
| 103 | |
| 104 | /** |
| 105 | * @brief write printer check bit |
| 106 | */ |
| 107 | WRITE16_MEMBER( alto2_cpu_device::pcheck_w ) { X_WRBITS(m_hw.utilin,16,1,1,data); } |
| 108 | |
| 109 | /** |
| 110 | * @brief read unused bit 2 |
| 111 | */ |
| 112 | WRITE16_MEMBER( alto2_cpu_device::unused2_w ) { X_WRBITS(m_hw.utilin,16,2,2,data); } |
| 113 | |
| 114 | /** |
| 115 | * @brief write printer daisy ready bit |
| 116 | */ |
| 117 | WRITE16_MEMBER( alto2_cpu_device::pchrdy_w ) { X_WRBITS(m_hw.utilin,16,3,3,data); } |
| 118 | |
| 119 | /** |
| 120 | * @brief write printer carriage ready bit |
| 121 | */ |
| 122 | WRITE16_MEMBER( alto2_cpu_device::parrdy_w ) { X_WRBITS(m_hw.utilin,16,4,4,data); } |
| 123 | |
| 124 | /** |
| 125 | * @brief write printer ready bit |
| 126 | */ |
| 127 | WRITE16_MEMBER( alto2_cpu_device::pready_w ) { X_WRBITS(m_hw.utilin,16,5,5,data); } |
| 128 | |
| 129 | /** |
| 130 | * @brief write memory configuration switch |
| 131 | */ |
| 132 | WRITE16_MEMBER( alto2_cpu_device::memconfig_w ) { X_WRBITS(m_hw.utilin,16,6,6,data); } |
| 133 | |
| 134 | /** |
| 135 | * @brief write unused bit 7 |
| 136 | */ |
| 137 | WRITE16_MEMBER( alto2_cpu_device::unused7_w ) { X_WRBITS(m_hw.utilin,16,7,7,data); } |
| 138 | |
| 139 | /** |
| 140 | * @brief write key set key 0 |
| 141 | */ |
| 142 | WRITE16_MEMBER( alto2_cpu_device::keyset_key0_w ) { X_WRBITS(m_hw.utilin,16,8,8,data); } |
| 143 | |
| 144 | /** |
| 145 | * @brief write key set key 1 |
| 146 | */ |
| 147 | WRITE16_MEMBER( alto2_cpu_device::keyset_key1_w ) { X_WRBITS(m_hw.utilin,16,9,9,data); } |
| 148 | |
| 149 | /** |
| 150 | * @brief write key set key 2 |
| 151 | */ |
| 152 | WRITE16_MEMBER( alto2_cpu_device::keyset_key2_w ) { X_WRBITS(m_hw.utilin,16,10,10,data); } |
| 153 | |
| 154 | /** |
| 155 | * @brief write key set key 3 |
| 156 | */ |
| 157 | WRITE16_MEMBER( alto2_cpu_device::keyset_key3_w ) { X_WRBITS(m_hw.utilin,16,11,11,data); } |
| 158 | |
| 159 | /** |
| 160 | * @brief write key set key 4 |
| 161 | */ |
| 162 | WRITE16_MEMBER( alto2_cpu_device::keyset_key4_w ) { X_WRBITS(m_hw.utilin,16,12,12,data); } |
| 163 | |
| 164 | /** |
| 165 | * @brief write mouse red button bit |
| 166 | */ |
| 167 | WRITE16_MEMBER( alto2_cpu_device::mouse_red_w ) { X_WRBITS(m_hw.utilin,16,13,13,data); } |
| 168 | |
| 169 | /** |
| 170 | * @brief write mouse blue button bit |
| 171 | */ |
| 172 | WRITE16_MEMBER( alto2_cpu_device::mouse_blue_w ) { X_WRBITS(m_hw.utilin,16,14,14,data); } |
| 173 | |
| 174 | /** |
| 175 | * @brief write mouse yellow button bit |
| 176 | */ |
| 177 | WRITE16_MEMBER( alto2_cpu_device::mouse_yellow_w ) { X_WRBITS(m_hw.utilin,16,15,15,data); } |
| 178 | |
| 179 | /** |
| 180 | * @brief write mouse buttons bits |
| 181 | */ |
| 182 | WRITE16_MEMBER( alto2_cpu_device::mouse_buttons_w ) { X_WRBITS(m_hw.utilin,16,13,15,data); } |
| 183 | |
| 184 | /** |
| 185 | * @brief printer paper strobe bit |
| 186 | * Paper strobe bit. Toggling this bit causes a paper scrolling operation. |
| 187 | */ |
| 188 | static inline UINT16 GET_PPPSTR(UINT16 utilout) { return X_RDBITS(utilout,16,0,0); } |
| 189 | |
| 190 | /** |
| 191 | * @brief printer retstore bit |
| 192 | * Restore bit. Toggling this bit resets the printer (including clearing |
| 193 | * the "check" condition if present) and moves the carriage to the |
| 194 | * left margin. |
| 195 | */ |
| 196 | static inline UINT16 GET_PREST(UINT16 utilout) { return X_RDBITS(utilout,16,1,1); } |
| 197 | |
| 198 | /** |
| 199 | * @brief printer ribbon bit |
| 200 | * Ribbon bit. When this bit is 1 the ribbon is up (in printing |
| 201 | * position); when 0, it is down. |
| 202 | */ |
| 203 | static inline UINT16 GET_PRIB(UINT16 utilout) { return X_RDBITS(utilout,16,2,2); } |
| 204 | |
| 205 | /** |
| 206 | * @brief printer daisy strobe bit |
| 207 | * Daisy strobe bit. Toggling this bit causes a character to be printed. |
| 208 | */ |
| 209 | static inline UINT16 GET_PCHSTR(UINT16 utilout) { return X_RDBITS(utilout,16,3,3); } |
| 210 | |
| 211 | /** |
| 212 | * @brief printer carriage strobe bit |
| 213 | * Carriage strobe bit. Toggling this bit causes a horizontal position operation. |
| 214 | */ |
| 215 | static inline UINT16 GET_PCARSTR(UINT16 utilout) { return X_RDBITS(utilout,16,4,4); } |
| 216 | |
| 217 | /** |
| 218 | * @brief printer data |
| 219 | * Argument to various output operations: |
| 220 | * 1. Printing characters. When the daisy bit is toggled bits 9-15 of this field |
| 221 | * are interpreted as an ASCII character code to be printed (it should be noted |
| 222 | * that all codes less than 040 print as lower case "w"). |
| 223 | * 2. For paper and carriage operations the field is interpreted as a displacement |
| 224 | * (-1024 to +1023), in units of 1/48 inch for paper and 1/60 inch for carriage. |
| 225 | * Positive is down or to the right, negative up or to the left. The value is |
| 226 | * represented as sign-magnitude (i.e., bit 5 is 1 for negative numbers, 0 for |
| 227 | * positive; bits 6-15 are the absolute value of the number). |
| 228 | */ |
| 229 | static inline UINT16 GET_PDATA(UINT16 utilout) { return X_RDBITS(utilout,16,5,15); } |
| 230 | |
| 231 | /** |
| 13 | 232 | * @brief read the UTILIN port |
| 14 | 233 | * |
| 15 | 234 | * @param addr memory mapped I/O address to be read |
branches/alto2/src/emu/cpu/alto2/a2mem.c
| r26301 | r26302 | |
| 9 | 9 | *****************************************************************************/ |
| 10 | 10 | #include "alto2cpu.h" |
| 11 | 11 | |
| 12 | | #define PUT_EVEN(dword,word) A2_PUT32(dword,32, 0,15,word) |
| 13 | | #define GET_EVEN(dword) A2_GET32(dword,32, 0,15) |
| 14 | | #define PUT_ODD(dword,word) A2_PUT32(dword,32,16,31,word) |
| 15 | | #define GET_ODD(dword) A2_GET32(dword,32,16,31) |
| 12 | #define PUT_EVEN(dword,word) X_WRBITS(dword,32, 0,15,word) |
| 13 | #define GET_EVEN(dword) X_RDBITS(dword,32, 0,15) |
| 14 | #define PUT_ODD(dword,word) X_WRBITS(dword,32,16,31,word) |
| 15 | #define GET_ODD(dword) X_RDBITS(dword,32,16,31) |
| 16 | 16 | |
| 17 | | #define GET_MESR_HAMMING(mesr) A2_GET16(mesr,16,0,5) |
| 18 | | #define PUT_MESR_HAMMING(mesr,val) A2_PUT16(mesr,16,0,5,val) |
| 19 | | #define GET_MESR_PERR(mesr) A2_GET16(mesr,16,6,6) |
| 20 | | #define PUT_MESR_PERR(mesr,val) A2_PUT16(mesr,16,6,6,val) |
| 21 | | #define GET_MESR_PARITY(mesr) A2_GET16(mesr,16,7,7) |
| 22 | | #define PUT_MESR_PARITY(mesr,val) A2_PUT16(mesr,16,7,7,val) |
| 23 | | #define GET_MESR_SYNDROME(mesr) A2_GET16(mesr,16,8,13) |
| 24 | | #define PUT_MESR_SYNDROME(mesr,val) A2_PUT16(mesr,16,8,13,val) |
| 25 | | #define GET_MESR_BANK(mesr) A2_GET16(mesr,16,14,15) |
| 26 | | #define PUT_MESR_BANK(mesr,val) A2_PUT16(mesr,16,14,15,val) |
| 17 | #define GET_MESR_HAMMING(mesr) X_RDBITS(mesr,16,0,5) |
| 18 | #define PUT_MESR_HAMMING(mesr,val) X_WRBITS(mesr,16,0,5,val) |
| 19 | #define GET_MESR_PERR(mesr) X_RDBITS(mesr,16,6,6) |
| 20 | #define PUT_MESR_PERR(mesr,val) X_WRBITS(mesr,16,6,6,val) |
| 21 | #define GET_MESR_PARITY(mesr) X_RDBITS(mesr,16,7,7) |
| 22 | #define PUT_MESR_PARITY(mesr,val) X_WRBITS(mesr,16,7,7,val) |
| 23 | #define GET_MESR_SYNDROME(mesr) X_RDBITS(mesr,16,8,13) |
| 24 | #define PUT_MESR_SYNDROME(mesr,val) X_WRBITS(mesr,16,8,13,val) |
| 25 | #define GET_MESR_BANK(mesr) X_RDBITS(mesr,16,14,15) |
| 26 | #define PUT_MESR_BANK(mesr,val) X_WRBITS(mesr,16,14,15,val) |
| 27 | 27 | |
| 28 | | #define GET_MECR_SPARE1(mecr,val) A2_GET16(mecr,16,0,3) |
| 29 | | #define PUT_MECR_SPARE1(mecr,val) A2_PUT16(mecr,16,0,3,val) |
| 30 | | #define GET_MECR_TEST_CODE(mecr) A2_GET16(mecr,16,4,10) |
| 31 | | #define PUT_MECR_TEST_CODE(mecr,val) A2_PUT16(mecr,16,4,10,val) |
| 32 | | #define GET_MECR_TEST_MODE(mecr) A2_GET16(mecr,16,11,11) |
| 33 | | #define PUT_MECR_TEST_MODE(mecr,val) A2_PUT16(mecr,16,11,11,val) |
| 34 | | #define GET_MECR_INT_SBERR(mecr) A2_GET16(mecr,16,12,12) |
| 35 | | #define PUT_MECR_INT_SBERR(mecr,val) A2_PUT16(mecr,16,12,12,val) |
| 36 | | #define GET_MECR_INT_DBERR(mecr) A2_GET16(mecr,16,13,13) |
| 37 | | #define PUT_MECR_INT_DBERR(mecr,val) A2_PUT16(mecr,16,13,13,val) |
| 38 | | #define GET_MECR_ERRCORR(mecr) A2_GET16(mecr,16,14,14) |
| 39 | | #define PUT_MECR_ERRCORR(mecr,val) A2_PUT16(mecr,16,14,14,val) |
| 40 | | #define GET_MECR_SPARE2(mecr) A2_GET16(mecr,16,15,15) |
| 41 | | #define PUT_MECR_SPARE2(mecr,val) A2_PUT16(mecr,16,15,15,val) |
| 28 | #define GET_MECR_SPARE1(mecr,val) X_RDBITS(mecr,16,0,3) |
| 29 | #define PUT_MECR_SPARE1(mecr,val) X_WRBITS(mecr,16,0,3,val) |
| 30 | #define GET_MECR_TEST_CODE(mecr) X_RDBITS(mecr,16,4,10) |
| 31 | #define PUT_MECR_TEST_CODE(mecr,val) X_WRBITS(mecr,16,4,10,val) |
| 32 | #define GET_MECR_TEST_MODE(mecr) X_RDBITS(mecr,16,11,11) |
| 33 | #define PUT_MECR_TEST_MODE(mecr,val) X_WRBITS(mecr,16,11,11,val) |
| 34 | #define GET_MECR_INT_SBERR(mecr) X_RDBITS(mecr,16,12,12) |
| 35 | #define PUT_MECR_INT_SBERR(mecr,val) X_WRBITS(mecr,16,12,12,val) |
| 36 | #define GET_MECR_INT_DBERR(mecr) X_RDBITS(mecr,16,13,13) |
| 37 | #define PUT_MECR_INT_DBERR(mecr,val) X_WRBITS(mecr,16,13,13,val) |
| 38 | #define GET_MECR_ERRCORR(mecr) X_RDBITS(mecr,16,14,14) |
| 39 | #define PUT_MECR_ERRCORR(mecr,val) X_WRBITS(mecr,16,14,14,val) |
| 40 | #define GET_MECR_SPARE2(mecr) X_RDBITS(mecr,16,15,15) |
| 41 | #define PUT_MECR_SPARE2(mecr,val) X_WRBITS(mecr,16,15,15,val) |
| 42 | 42 | |
| 43 | 43 | /** |
| 44 | 44 | * <PRE> |
| r26301 | r26302 | |
| 277 | 277 | /* a74: WD14 WD17 WD18 WD21 WD23 WD24 WD26 WD27 WD29 PCB --- */ |
| 278 | 278 | #define A74 (WD(14)|WD(17)|WD(18)|WD(21)|WD(23)|WD(24)|WD(26)|WD(27)|WD(29)) |
| 279 | 279 | |
| 280 | | #define H0(hpb) A2_GET8(hpb,8,0,0) //!< get Hamming code bit 0 from hpb data (really bit 32) |
| 281 | | #define H1(hpb) A2_GET8(hpb,8,1,1) //!< get Hamming code bit 1 from hpb data (really bit 33) |
| 282 | | #define H2(hpb) A2_GET8(hpb,8,2,2) //!< get Hamming code bit 2 from hpb data (really bit 34) |
| 283 | | #define H3(hpb) A2_GET8(hpb,8,3,3) //!< get Hamming code bit 3 from hpb data (really bit 35) |
| 284 | | #define H4(hpb) A2_GET8(hpb,8,4,4) //!< get Hamming code bit 4 from hpb data (really bit 36) |
| 285 | | #define H5(hpb) A2_GET8(hpb,8,5,5) //!< get Hamming code bit 5 from hpb data (really bit 37) |
| 286 | | #define RH(hpb) A2_GET8(hpb,8,0,5) //!< get Hamming code from hpb data (bits 32 to 37) |
| 287 | | #define RP(hpb) A2_BIT8(hpb,8,6) //!< get parity bit from hpb data (really bit 38) |
| 280 | #define H0(hpb) X_RDBITS(hpb,8,0,0) //!< get Hamming code bit 0 from hpb data (really bit 32) |
| 281 | #define H1(hpb) X_RDBITS(hpb,8,1,1) //!< get Hamming code bit 1 from hpb data (really bit 33) |
| 282 | #define H2(hpb) X_RDBITS(hpb,8,2,2) //!< get Hamming code bit 2 from hpb data (really bit 34) |
| 283 | #define H3(hpb) X_RDBITS(hpb,8,3,3) //!< get Hamming code bit 3 from hpb data (really bit 35) |
| 284 | #define H4(hpb) X_RDBITS(hpb,8,4,4) //!< get Hamming code bit 4 from hpb data (really bit 36) |
| 285 | #define H5(hpb) X_RDBITS(hpb,8,5,5) //!< get Hamming code bit 5 from hpb data (really bit 37) |
| 286 | #define RH(hpb) X_RDBITS(hpb,8,0,5) //!< get Hamming code from hpb data (bits 32 to 37) |
| 287 | #define RP(hpb) X_BIT(hpb,8,6) //!< get parity bit from hpb data (really bit 38) |
| 288 | 288 | |
| 289 | 289 | /** @brief return even parity of a (masked) 32 bit value */ |
| 290 | 290 | static __inline UINT8 parity_even(UINT32 val) |
| r26301 | r26302 | |
| 396 | 396 | hcpa ^ |
| 397 | 397 | hcpb ^ |
| 398 | 398 | h_0_2 ^ |
| 399 | | (A2_GET32(dw_data,32,0,0) ^ A2_GET32(dw_data,32,1,1)) ^ |
| 399 | (X_RDBITS(dw_data,32,0,0) ^ X_RDBITS(dw_data,32,1,1)) ^ |
| 400 | 400 | (dw_data & A54) ^ |
| 401 | 401 | RP(hpb) ^ |
| 402 | 402 | 1); |
| r26301 | r26302 | |
| 568 | 568 | WRITE16_MEMBER( alto2_cpu_device::mecr_w ) |
| 569 | 569 | { |
| 570 | 570 | m_mem.mecr = data ^ 0177777; |
| 571 | | A2_PUT16(m_mem.mecr,16, 0, 3,0); |
| 572 | | A2_PUT16(m_mem.mecr,16,15,15,0); |
| 571 | X_WRBITS(m_mem.mecr,16, 0, 3,0); |
| 572 | X_WRBITS(m_mem.mecr,16,15,15,0); |
| 573 | 573 | if (!space.debugger_access()) { |
| 574 | 574 | LOG((LOG_MEM,2," MECR write %07o\n", data)); |
| 575 | 575 | LOG((LOG_MEM,6," Test Hamming code : %#o\n", GET_MECR_TEST_CODE(m_mem.mecr))); |