branches/alto2/src/emu/cpu/alto2/a2ether.c
| r26291 | r26292 | |
| 436 | 436 | * Gates the contents of the FIFO to BUS[0-15], and increments |
| 437 | 437 | * the read pointer at the end of the cycle. |
| 438 | 438 | */ |
| 439 | | void alto2_cpu_device::bs_eidfct_0() |
| 439 | void alto2_cpu_device::bs_early_eidfct() |
| 440 | 440 | { |
| 441 | 441 | UINT16 r = m_eth.fifo[m_eth.fifo_rd]; |
| 442 | 442 | |
| r26291 | r26292 | |
| 451 | 451 | /** |
| 452 | 452 | * @brief f1_eth_block early: block the Ether task |
| 453 | 453 | */ |
| 454 | | void alto2_cpu_device::f1_eth_block_0() |
| 454 | void alto2_cpu_device::f1_early_eth_block() |
| 455 | 455 | { |
| 456 | 456 | LOG((LOG_ETH,2," BLOCK %s\n", task_name(m_task))); |
| 457 | 457 | m_task_wakeup &= ~(1 << task_ether); |
| r26291 | r26292 | |
| 463 | 463 | * Gates the contents of the FIFO to BUS[0-15], but does not |
| 464 | 464 | * increment the read pointer; |
| 465 | 465 | */ |
| 466 | | void alto2_cpu_device::f1_eilfct_0() |
| 466 | void alto2_cpu_device::f1_early_eilfct() |
| 467 | 467 | { |
| 468 | 468 | UINT16 r = m_eth.fifo[m_eth.fifo_rd]; |
| 469 | 469 | LOG((LOG_ETH,3, " ←EILFCT; %06o at FIFO[%02o]\n", r, m_eth.fifo_rd)); |
| r26291 | r26292 | |
| 483 | 483 | * ;(LOW TRUE) to Bus [10:15], reset interface. |
| 484 | 484 | * |
| 485 | 485 | */ |
| 486 | | void alto2_cpu_device::f1_epfct_0() |
| 486 | void alto2_cpu_device::f1_early_epfct() |
| 487 | 487 | { |
| 488 | 488 | UINT16 r = ~A2_GET16(m_eth.status,16,10,15) & 0177777; |
| 489 | 489 | |
| r26291 | r26292 | |
| 502 | 502 | * This function must be issued in the instruction after a TASK. |
| 503 | 503 | * The resulting wakeup is cleared when the Ether task next runs. |
| 504 | 504 | */ |
| 505 | | void alto2_cpu_device::f1_ewfct_1() |
| 505 | void alto2_cpu_device::f1_late_ewfct() |
| 506 | 506 | { |
| 507 | 507 | /* |
| 508 | 508 | * Set a flag in the CPU to handle the next task switch |
| r26291 | r26292 | |
| 517 | 517 | * Loads the FIFO from BUS[0-15], then increments the write |
| 518 | 518 | * pointer at the end of the cycle. |
| 519 | 519 | */ |
| 520 | | void alto2_cpu_device::f2_eodfct_1() |
| 520 | void alto2_cpu_device::f2_late_eodfct() |
| 521 | 521 | { |
| 522 | 522 | LOG((LOG_ETH,3, " EODFCT←; push %06o into FIFO[%02o]\n", m_bus, m_eth.fifo_wr)); |
| 523 | 523 | |
| r26291 | r26292 | |
| 543 | 543 | * or EEFCT has been issued, the interface will wait for silence |
| 544 | 544 | * on the Ether and begin transmitting. |
| 545 | 545 | */ |
| 546 | | void alto2_cpu_device::f2_eosfct_1() |
| 546 | void alto2_cpu_device::f2_late_eosfct() |
| 547 | 547 | { |
| 548 | 548 | LOG((LOG_ETH,3, " EOSFCT\n")); |
| 549 | 549 | PUT_ETH_WLF(m_eth.status, 0); |
| r26291 | r26292 | |
| 561 | 561 | * causing the Ethernet task to wakeup, dispatch on them and then |
| 562 | 562 | * reset them with EPFCT. |
| 563 | 563 | */ |
| 564 | | void alto2_cpu_device::f2_erbfct_1() |
| 564 | void alto2_cpu_device::f2_late_erbfct() |
| 565 | 565 | { |
| 566 | 566 | UINT16 r = 0; |
| 567 | 567 | A2_PUT16(r,10,6,6,GET_ETH_ICMD(m_eth.status)); |
| r26291 | r26292 | |
| 578 | 578 | * has been transferred to the FIFO. EEFCT disables further data |
| 579 | 579 | * wakeups. |
| 580 | 580 | */ |
| 581 | | void alto2_cpu_device::f2_eefct_1() |
| 581 | void alto2_cpu_device::f2_late_eefct() |
| 582 | 582 | { |
| 583 | 583 | /* start transmitting the packet */ |
| 584 | 584 | PUT_ETH_OBUSY(m_eth.status, 1); |
| r26291 | r26292 | |
| 599 | 599 | * with AC0[14-15] non-zero is issued, or if the transmitter or |
| 600 | 600 | * receiver is gone. ORs a 1 into NEXT[6] if a collision is detected. |
| 601 | 601 | */ |
| 602 | | void alto2_cpu_device::f2_ebfct_1() |
| 602 | void alto2_cpu_device::f2_late_ebfct() |
| 603 | 603 | { |
| 604 | 604 | UINT16 r = 0; |
| 605 | 605 | A2_PUT16(r,10,6,6, GET_ETH_COLL(m_eth.status)); |
| r26291 | r26292 | |
| 617 | 617 | * |
| 618 | 618 | * ORs a one into NEXT[7] if the FIFO is not empty. |
| 619 | 619 | */ |
| 620 | | void alto2_cpu_device::f2_ecbfct_1() |
| 620 | void alto2_cpu_device::f2_late_ecbfct() |
| 621 | 621 | { |
| 622 | 622 | UINT16 r = 0; |
| 623 | 623 | /* TODO: the BE' (buffer empty) signal is output D0 of PROM a49 */ |
| r26291 | r26292 | |
| 634 | 634 | * by a transition. When the interface has collected two words, |
| 635 | 635 | * it will begin generating data wakeups to the microcode. |
| 636 | 636 | */ |
| 637 | | void alto2_cpu_device::f2_eisfct_1() |
| 637 | void alto2_cpu_device::f2_late_eisfct() |
| 638 | 638 | { |
| 639 | 639 | LOG((LOG_ETH,3, " EISFCT\n")); |
| 640 | 640 | PUT_ETH_IBUSY(m_eth.status, 0); |
| r26291 | r26292 | |
| 658 | 658 | // intialize all ethernet variables |
| 659 | 659 | memset(&m_eth, 0, sizeof(m_eth)); |
| 660 | 660 | |
| 661 | | set_bs(task, bs_ether_eidfct, &alto2_cpu_device::bs_eidfct_0, 0); |
| 661 | set_bs(task, bs_ether_eidfct, &alto2_cpu_device::bs_early_eidfct, 0); |
| 662 | 662 | |
| 663 | | set_f1(task, f1_block, &alto2_cpu_device::f1_eth_block_0, 0); |
| 664 | | set_f1(task, f1_ether_eilfct, &alto2_cpu_device::f1_eilfct_0, 0); |
| 665 | | set_f1(task, f1_ether_epfct, &alto2_cpu_device::f1_epfct_0, 0); |
| 666 | | set_f1(task, f1_ether_ewfct, 0, &alto2_cpu_device::f1_ewfct_1); |
| 663 | set_f1(task, f1_block, &alto2_cpu_device::f1_early_eth_block, 0); |
| 664 | set_f1(task, f1_ether_eilfct, &alto2_cpu_device::f1_early_eilfct, 0); |
| 665 | set_f1(task, f1_ether_epfct, &alto2_cpu_device::f1_early_epfct, 0); |
| 666 | set_f1(task, f1_ether_ewfct, 0, &alto2_cpu_device::f1_late_ewfct); |
| 667 | 667 | |
| 668 | | set_f2(task, f2_ether_eodfct, 0, &alto2_cpu_device::f2_eodfct_1); |
| 669 | | set_f2(task, f2_ether_eosfct, 0, &alto2_cpu_device::f2_eosfct_1); |
| 670 | | set_f2(task, f2_ether_erbfct, 0, &alto2_cpu_device::f2_erbfct_1); |
| 671 | | set_f2(task, f2_ether_eefct, 0, &alto2_cpu_device::f2_eefct_1); |
| 672 | | set_f2(task, f2_ether_ebfct, 0, &alto2_cpu_device::f2_ebfct_1); |
| 673 | | set_f2(task, f2_ether_ecbfct, 0, &alto2_cpu_device::f2_ecbfct_1); |
| 674 | | set_f2(task, f2_ether_eisfct, 0, &alto2_cpu_device::f2_eisfct_1); |
| 668 | set_f2(task, f2_ether_eodfct, 0, &alto2_cpu_device::f2_late_eodfct); |
| 669 | set_f2(task, f2_ether_eosfct, 0, &alto2_cpu_device::f2_late_eosfct); |
| 670 | set_f2(task, f2_ether_erbfct, 0, &alto2_cpu_device::f2_late_erbfct); |
| 671 | set_f2(task, f2_ether_eefct, 0, &alto2_cpu_device::f2_late_eefct); |
| 672 | set_f2(task, f2_ether_ebfct, 0, &alto2_cpu_device::f2_late_ebfct); |
| 673 | set_f2(task, f2_ether_ecbfct, 0, &alto2_cpu_device::f2_late_ecbfct); |
| 674 | set_f2(task, f2_ether_eisfct, 0, &alto2_cpu_device::f2_late_eisfct); |
| 675 | 675 | |
| 676 | 676 | m_active_callback[task] = &alto2_cpu_device::activate_eth; |
| 677 | 677 | } |
branches/alto2/src/emu/cpu/alto2/alto2cpu.h
| r26291 | r26292 | |
| 1095 | 1095 | DECLARE_READ16_MEMBER( bank_reg_r ); //!< read bank register in memory mapped I/O range |
| 1096 | 1096 | DECLARE_WRITE16_MEMBER( bank_reg_w ); //!< write bank register in memory mapped I/O range |
| 1097 | 1097 | |
| 1098 | | void bs_read_r_0(); //!< bs_read_r early: drive bus by R register |
| 1099 | | void bs_load_r_0(); //!< bs_load_r early: load R places 0 on the BUS |
| 1100 | | void bs_load_r_1(); //!< bs_load_r late: load R from SHIFTER |
| 1101 | | void bs_read_md_0(); //!< bs_read_md early: drive BUS from read memory data |
| 1102 | | void bs_mouse_0(); //!< bs_mouse early: drive bus by mouse |
| 1103 | | void bs_disp_0(); //!< bs_disp early: drive bus by displacement (which?) |
| 1104 | | void f1_load_mar_1(); //!< f1_load_mar late: load memory address register |
| 1105 | | void f1_task_0(); //!< f1_task early: task switch |
| 1106 | | void f2_bus_eq_zero_1(); //!< f2_bus_eq_zero late: branch on bus equals zero |
| 1107 | | void f2_shifter_lt_zero_1(); //!< f2_shifter_lt_zero late: branch on shifter less than zero |
| 1108 | | void f2_shifter_eq_zero_1(); //!< f2_shifter_eq_zero late: branch on shifter equals zero |
| 1109 | | void f2_bus_1(); //!< f2_bus late: branch on bus bits BUS[6-15] |
| 1110 | | void f2_alucy_1(); //!< f2_alucy late: branch on latched ALU carry |
| 1111 | | void f2_load_md_1(); //!< f2_load_md late: load memory data |
| 1098 | void bs_early_read_r(); //!< bus source: drive bus by R register |
| 1099 | void bs_early_load_r(); //!< bus source: load R places 0 on the BUS |
| 1100 | void bs_late_load_r(); //!< bus source: load R from SHIFTER |
| 1101 | void bs_early_read_md(); //!< bus source: drive BUS from read memory data |
| 1102 | void bs_early_mouse(); //!< bus source: drive bus by mouse |
| 1103 | void bs_early_disp(); //!< bus source: drive bus by displacement (which?) |
| 1104 | void f1_late_load_mar(); //!< F1 func: load memory address register |
| 1105 | void f1_early_task(); //!< F1 func: task switch |
| 1106 | void f1_late_l_lsh_1(); //!< F1 func: SHIFTER = left shift L once |
| 1107 | void f1_late_l_rsh_1(); //!< F1 func: SHIFTER = right shift L once |
| 1108 | void f1_late_l_lcy_8(); //!< F1 func: SHIFTER = byte swap L |
| 1109 | void f2_late_bus_eq_zero(); //!< F2 func: branch on bus equals zero |
| 1110 | void f2_late_shifter_lt_zero(); //!< F2 func: branch on shifter less than zero |
| 1111 | void f2_late_shifter_eq_zero(); //!< F2 func: branch on shifter equals zero |
| 1112 | void f2_late_bus(); //!< F2 func: branch on bus bits BUS[6-15] |
| 1113 | void f2_late_alucy(); //!< F2 func: branch on latched ALU carry |
| 1114 | void f2_late_load_md(); //!< F2 func: load memory data |
| 1112 | 1115 | |
| 1113 | 1116 | UINT8* m_alu_a10; //!< ALU function to 74181 operation lookup PROM |
| 1117 | #if USE_ALU_74181 |
| 1114 | 1118 | UINT32 alu_74181(UINT32 a, UINT32 b, UINT8 smc); |
| 1115 | | |
| 1119 | #endif |
| 1116 | 1120 | void rdram(); //!< read the microcode ROM/RAM halfword |
| 1117 | 1121 | void wrtram(); //!< write the microcode RAM from M register and ALU |
| 1118 | 1122 | |
| 1119 | 1123 | // ************************************************ |
| 1120 | 1124 | // ram related stuff |
| 1121 | 1125 | // ************************************************ |
| 1122 | | void bs_read_sreg_0(); //!< bs_read_sreg early: drive bus by S register or M (MYL), if rsel is = 0 |
| 1123 | | void bs_load_sreg_0(); //!< bs_load_sreg early: load S register puts garbage on the bus |
| 1124 | | void bs_load_sreg_1(); //!< bs_load_sreg late: load S register from M |
| 1126 | void bs_early_read_sreg(); //!< bus source: drive bus by S register or M (MYL), if rsel is = 0 |
| 1127 | void bs_early_load_sreg(); //!< bus source: load S register puts garbage on the bus |
| 1128 | void bs_late_load_sreg(); //!< bus source: load S register from M |
| 1125 | 1129 | void branch_ROM(const char *from, int page); //!< branch to ROM page |
| 1126 | 1130 | void branch_RAM(const char *from, int page); //!< branch to RAM page |
| 1127 | | void f1_swmode_1(); //!< f1_swmode early: switch to micro program counter BUS[6-15] in other bank |
| 1128 | | void f1_wrtram_1(); //!< f1_wrtram late: start WRTRAM cycle |
| 1129 | | void f1_rdram_1(); //!< f1_rdram late: start RDRAM cycle |
| 1131 | void f1_late_swmode(); //!< F1 func: switch to micro program counter BUS[6-15] in other bank |
| 1132 | void f1_late_wrtram(); //!< F1 func: start WRTRAM cycle |
| 1133 | void f1_late_rdram(); //!< F1 func: start RDRAM cycle |
| 1130 | 1134 | #if (ALTO2_UCODE_RAM_PAGES == 3) |
| 1131 | | void f1_load_rmr_1(); //!< f1_load_rmr late: load the reset mode register |
| 1135 | void f1_late_load_rmr(); //!< F1 func: load the reset mode register |
| 1132 | 1136 | #else // ALTO2_UCODE_RAM_PAGES != 3 |
| 1133 | | void f1_load_srb_1(); //!< f1_load_srb late: load the S register bank from BUS[12-14] |
| 1137 | void f1_late_load_srb(); //!< F1 func: load the S register bank from BUS[12-14] |
| 1134 | 1138 | #endif |
| 1135 | 1139 | void init_ram(int task); //!< called by RAM related tasks |
| 1136 | 1140 | void exit_ram(); |
| r26291 | r26292 | |
| 1363 | 1367 | * sequence: 40 -> d0 -> b0 -> 20 |
| 1364 | 1368 | * A motion to the south will first toggle MY1, then MY2. |
| 1365 | 1369 | * sequence: 10 -> 70 -> e0 -> 80 |
| 1366 | | * |
| 1367 | | * This dump is from PROM madr.a32: |
| 1368 | | * 0000: 017,007,013,017,013,017,017,007,007,017,017,013,017,013,007,017, |
| 1369 | | * 0020: 003,015,005,003,005,003,003,015,015,003,003,005,003,005,015,003, |
| 1370 | | * 0040: 011,001,016,011,016,011,011,001,001,011,011,016,011,016,001,011, |
| 1371 | | * 0060: 017,007,013,017,013,017,017,007,007,017,017,013,017,013,007,017, |
| 1372 | | * 0100: 011,001,016,011,016,011,011,001,001,011,011,016,011,016,001,011, |
| 1373 | | * 0120: 017,007,013,017,013,017,017,007,007,017,017,013,017,013,007,017, |
| 1374 | | * 0140: 017,007,013,017,013,017,017,007,007,017,017,013,017,013,007,017, |
| 1375 | | * 0160: 003,015,005,003,005,003,003,015,015,003,003,005,003,005,015,003, |
| 1376 | | * 0200: 003,015,005,003,005,003,003,015,015,003,003,005,003,005,015,003, |
| 1377 | | * 0220: 017,007,013,017,013,017,017,007,007,017,017,013,017,013,007,017, |
| 1378 | | * 0240: 017,007,013,017,013,017,017,007,007,017,017,013,017,013,007,017, |
| 1379 | | * 0260: 011,001,016,011,016,011,011,001,001,011,011,016,011,016,001,011, |
| 1380 | | * 0300: 017,007,013,017,013,017,017,007,007,017,017,013,017,013,007,017, |
| 1381 | | * 0320: 011,001,016,011,016,011,011,001,001,011,011,016,011,016,001,011, |
| 1382 | | * 0340: 003,015,005,003,005,003,003,015,015,003,003,005,003,005,015,003, |
| 1383 | | * 0360: 017,007,013,017,013,017,017,007,007,017,017,013,017,013,007,017 |
| 1384 | 1370 | * </PRE> |
| 1385 | 1371 | */ |
| 1386 | 1372 | UINT8* m_madr_a32; |
| r26291 | r26292 | |
| 1477 | 1463 | void disk_bitclk(void *ptr, int arg); //!< function to update the disk controller with a new bitclk |
| 1478 | 1464 | #endif |
| 1479 | 1465 | void disk_block(int task); //!< called if one of the disk tasks (task_kwd or task_ksec) blocks |
| 1480 | | void bs_read_kstat_0(); //!< bs_read_kstat early: bus driven by disk status register KSTAT |
| 1481 | | void bs_read_kdata_0(); //!< bs_read_kdata early: bus driven by disk data register KDATA input |
| 1482 | | void f1_strobe_1(); //!< f1_strobe late: initiates a disk seek |
| 1483 | | void f1_load_kstat_1(); //!< f1_load_kstat late: load disk status register |
| 1484 | | void f1_load_kdata_1(); //!< f1_load_kdata late: load data out register, or the disk address register |
| 1485 | | void f1_increcno_1(); //!< f1_increcno late: advances shift registers holding KADR |
| 1486 | | void f1_clrstat_1(); //!< f1_clrstat late: reset all error latches |
| 1487 | | void f1_load_kcom_1(); //!< f1_load_kcom late: load the KCOM register from bus |
| 1488 | | void f1_load_kadr_1(); //!< f1_load_kadr late: load the KADR register from bus |
| 1489 | | void f2_init_1(); //!< f2_init late: branch on disk word task active and init |
| 1490 | | void f2_rwc_1(); //!< f2_rwc late: branch on read/write/check state of the current record |
| 1491 | | void f2_recno_1(); //!< f2_recno late: branch on the current record number by a lookup table |
| 1492 | | void f2_xfrdat_1(); //!< f2_xfrdat late: branch on the data transfer state |
| 1493 | | void f2_swrnrdy_1(); //!< f2_swrnrdy late: branch on the disk ready signal |
| 1494 | | void f2_nfer_1(); //!< f2_nfer late: branch on the disk fatal error condition |
| 1495 | | void f2_strobon_1(); //!< f2_strobon late: branch on the seek busy status |
| 1466 | void bs_early_read_kstat(); //!< bus source: bus driven by disk status register KSTAT |
| 1467 | void bs_early_read_kdata(); //!< bus source: bus driven by disk data register KDATA input |
| 1468 | void f1_late_strobe(); //!< F1 func: initiates a disk seek |
| 1469 | void f1_late_load_kstat(); //!< F1 func: load disk status register |
| 1470 | void f1_late_load_kdata(); //!< F1 func: load data out register, or the disk address register |
| 1471 | void f1_late_increcno(); //!< F1 func: advances shift registers holding KADR |
| 1472 | void f1_late_clrstat(); //!< F1 func: reset all error latches |
| 1473 | void f1_late_load_kcom(); //!< F1 func: load the KCOM register from bus |
| 1474 | void f1_late_load_kadr(); //!< F1 func: load the KADR register from bus |
| 1475 | void f2_late_init(); //!< F2 func: branch on disk word task active and init |
| 1476 | void f2_late_rwc(); //!< F2 func: branch on read/write/check state of the current record |
| 1477 | void f2_late_recno(); //!< F2 func: branch on the current record number by a lookup table |
| 1478 | void f2_late_xfrdat(); //!< F2 func: branch on the data transfer state |
| 1479 | void f2_late_swrnrdy(); //!< F2 func: branch on the disk ready signal |
| 1480 | void f2_late_nfer(); //!< f2_nfer late: branch on the disk fatal error condition |
| 1481 | void f2_late_strobon(); //!< f2_strobon late: branch on the seek busy status |
| 1496 | 1482 | void init_disk(); //!< initialize the disk context |
| 1497 | 1483 | void exit_disk(); //!< deinitialize the disk context |
| 1498 | 1484 | |
| r26291 | r26292 | |
| 1735 | 1721 | void display_state_machine(); |
| 1736 | 1722 | |
| 1737 | 1723 | //! branch on the evenfield flip-flop |
| 1738 | | void f2_evenfield_1(void); |
| 1724 | void f2_late_evenfield(void); |
| 1739 | 1725 | |
| 1740 | 1726 | //! initialize the display context |
| 1741 | 1727 | void init_disp(); |
| r26291 | r26292 | |
| 1874 | 1860 | UINT8 skip; //!< emulator skip |
| 1875 | 1861 | UINT8 cy; //!< emulator carry |
| 1876 | 1862 | } m_emu; |
| 1877 | | void bs_emu_disp_0(); //!< bs_emu_disp early: drive bus by IR[8-15], possibly sign extended |
| 1878 | | void f1_emu_block_0(); //!< f1_block early: block task |
| 1879 | | void f1_emu_load_rmr_1(); //!< f1_load_rmr late: load the reset mode register |
| 1880 | | void f1_emu_load_esrb_1(); //!< f1_load_esrb late: load the extended S register bank from BUS[12-14] |
| 1881 | | void f1_rsnf_0(); //!< f1_rsnf early: drive the bus from the Ethernet node ID |
| 1882 | | void f1_startf_0(); //!< f1_startf early: defines commands for for I/O hardware, including Ethernet |
| 1883 | | void f2_busodd_1(); //!< f2_busodd late: branch on odd bus |
| 1884 | | void f2_magic_1(); //!< f2_magic late: shift and use T |
| 1885 | | void f2_load_dns_0(); //!< f2_load_dns early: modify RESELECT with DstAC = (3 - IR[3-4]) |
| 1886 | | void f2_load_dns_1(); //!< f2_load_dns late: do novel shifts |
| 1887 | | void f2_acdest_0(); //!< f2_acdest early: modify RSELECT with DstAC = (3 - IR[3-4]) |
| 1863 | void bs_early_emu_disp(); //!< bus source: drive bus by IR[8-15], possibly sign extended |
| 1864 | void f1_early_emu_block(); //!< F1 func: block task |
| 1865 | void f1_late_emu_load_rmr(); //!< F1 func: load the reset mode register |
| 1866 | void f1_late_emu_load_esrb(); //!< F1 func: load the extended S register bank from BUS[12-14] |
| 1867 | void f1_early_rsnf(); //!< F1 func: drive the bus from the Ethernet node ID |
| 1868 | void f1_early_startf(); //!< F1 func: defines commands for for I/O hardware, including Ethernet |
| 1869 | void f2_late_busodd(); //!< F2 func: branch on odd bus |
| 1870 | void f2_late_magic(); //!< F2 func: shift and use T |
| 1871 | void f2_early_load_dns(); //!< F2 func: modify RESELECT with DstAC = (3 - IR[3-4]) |
| 1872 | void f2_late_load_dns(); //!< F2 func: do novel shifts |
| 1873 | void f2_early_acdest(); //!< F2 func: modify RSELECT with DstAC = (3 - IR[3-4]) |
| 1888 | 1874 | void bitblt_info(); //!< debug bitblt opcode |
| 1889 | | void f2_load_ir_1(); //!< f2_load_ir late: load instruction register IR and branch on IR[0,5-7] |
| 1890 | | void f2_idisp_1(); //!< f2_idisp late: branch on: arithmetic IR_SH, others PROM ctl2k_u3[IR[1-7]] |
| 1891 | | void f2_acsource_0(); //!< f2_acsource early: modify RSELECT with SrcAC = (3 - IR[1-2]) |
| 1892 | | void f2_acsource_1(); //!< f2_acsource late: branch on arithmetic IR_SH, others PROM ctl2k_u3[IR[1-7]] |
| 1875 | void f2_late_load_ir(); //!< F2 func: load instruction register IR and branch on IR[0,5-7] |
| 1876 | void f2_late_idisp(); //!< F2 func: branch on: arithmetic IR_SH, others PROM ctl2k_u3[IR[1-7]] |
| 1877 | void f2_early_acsource(); //!< F2 func: modify RSELECT with SrcAC = (3 - IR[1-2]) |
| 1878 | void f2_late_acsource(); //!< F2 func: branch on arithmetic IR_SH, others PROM ctl2k_u3[IR[1-7]] |
| 1893 | 1879 | void init_emu(int task); //!< 000 initialize emulator task |
| 1894 | 1880 | void exit_emu(); //!< deinitialize emulator task |
| 1895 | 1881 | |
| 1896 | 1882 | // ************************************************ |
| 1897 | 1883 | // ksec task |
| 1898 | 1884 | // ************************************************ |
| 1899 | | void f1_ksec_block_0(void); |
| 1885 | void f1_early_ksec_block(void); |
| 1900 | 1886 | void init_ksec(int task); //!< 004 initialize disk sector task |
| 1901 | 1887 | void exit_ksec(); |
| 1902 | 1888 | |
| r26291 | r26292 | |
| 1966 | 1952 | * D1 (11) BNE' (buffer next empty ?) |
| 1967 | 1953 | * D2 (10) BNNE' (buffer next next empty ?) |
| 1968 | 1954 | * D3 (9) BF' (buffer full) |
| 1969 | | * |
| 1970 | | * Data from enet.a49 after address line reversal: |
| 1971 | | * 000: 010 007 017 017 017 017 017 017 017 017 017 017 017 017 013 011 |
| 1972 | | * 020: 011 010 007 017 017 017 017 017 017 017 017 017 017 017 017 013 |
| 1973 | | * 040: 013 011 010 007 017 017 017 017 017 017 017 017 017 017 017 017 |
| 1974 | | * 060: 017 013 011 010 007 017 017 017 017 017 017 017 017 017 017 017 |
| 1975 | | * 100: 017 017 013 011 010 007 017 017 017 017 017 017 017 017 017 017 |
| 1976 | | * 120: 017 017 017 013 011 010 007 017 017 017 017 017 017 017 017 017 |
| 1977 | | * 140: 017 017 017 017 013 011 010 007 017 017 017 017 017 017 017 017 |
| 1978 | | * 160: 017 017 017 017 017 013 011 010 007 017 017 017 017 017 017 017 |
| 1979 | | * 200: 017 017 017 017 017 017 013 011 010 007 017 017 017 017 017 017 |
| 1980 | | * 220: 017 017 017 017 017 017 017 013 011 010 007 017 017 017 017 017 |
| 1981 | | * 240: 017 017 017 017 017 017 017 017 013 011 010 007 017 017 017 017 |
| 1982 | | * 260: 017 017 017 017 017 017 017 017 017 013 011 010 007 017 017 017 |
| 1983 | | * 300: 017 017 017 017 017 017 017 017 017 017 013 011 010 007 017 017 |
| 1984 | | * 320: 017 017 017 017 017 017 017 017 017 017 017 013 011 010 007 017 |
| 1985 | | * 340: 017 017 017 017 017 017 017 017 017 017 017 017 013 011 010 007 |
| 1986 | | * 360: 007 017 017 017 017 017 017 017 017 017 017 017 017 013 011 010 |
| 1987 | 1955 | */ |
| 1988 | 1956 | UINT8* m_ether_a49; |
| 1989 | 1957 | |
| r26291 | r26292 | |
| 2006 | 1974 | TIMER_CALLBACK_MEMBER( tx_packet ); //!< transmit data from the FIFO to <nirvana for now> |
| 2007 | 1975 | void eth_wakeup(); //!< check for the various reasons to wakeup the Ethernet task |
| 2008 | 1976 | void eth_startf(); //!< start input or output depending on m_bus |
| 2009 | | void bs_eidfct_0(); //!< bs_eidfct early: Ethernet input data function |
| 2010 | | void f1_eth_block_0(); //!< f1_eth_block early: block the Ether task |
| 2011 | | void f1_eilfct_0(); //!< f1_eilfct early: Ethernet input look function |
| 2012 | | void f1_epfct_0(); //!< f1_epfct early: Ethernet post function |
| 2013 | | void f1_ewfct_1(); //!< f1_ewfct late: Ethernet countdown wakeup function |
| 2014 | | void f2_eodfct_1(); //!< f2_eodfct late: Ethernet output data function |
| 2015 | | void f2_eosfct_1(); //!< f2_eosfct late: Ethernet output start function |
| 2016 | | void f2_erbfct_1(); //!< f2_erbfct late: Ethernet reset branch function |
| 2017 | | void f2_eefct_1(); //!< f2_eefct late: Ethernet end of transmission function |
| 2018 | | void f2_ebfct_1(); //!< f2_ebfct late: Ethernet branch function |
| 2019 | | void f2_ecbfct_1(); //!< f2_ecbfct late: Ethernet countdown branch function |
| 2020 | | void f2_eisfct_1(); //!< f2_eisfct late: Ethernet input start function |
| 1977 | void bs_early_eidfct(); //!< bus source: Ethernet input data function |
| 1978 | void f1_early_eth_block(); //!< F1 func: block the Ether task |
| 1979 | void f1_early_eilfct(); //!< F1 func: Ethernet input look function |
| 1980 | void f1_early_epfct(); //!< F1 func: Ethernet post function |
| 1981 | void f1_late_ewfct(); //!< F1 func: Ethernet countdown wakeup function |
| 1982 | void f2_late_eodfct(); //!< F2 func: Ethernet output data function |
| 1983 | void f2_late_eosfct(); //!< F2 func: Ethernet output start function |
| 1984 | void f2_late_erbfct(); //!< F2 func: Ethernet reset branch function |
| 1985 | void f2_late_eefct(); //!< F2 func: Ethernet end of transmission function |
| 1986 | void f2_late_ebfct(); //!< F2 func: Ethernet branch function |
| 1987 | void f2_late_ecbfct(); //!< F2 func: Ethernet countdown branch function |
| 1988 | void f2_late_eisfct(); //!< F2 func: Ethernet input start function |
| 2021 | 1989 | void activate_eth(); //!< called by the CPU when the Ethernet task becomes active |
| 2022 | 1990 | void init_ether(int task); //!< 007 initialize ethernet task |
| 2023 | 1991 | void exit_ether(); //!< deinitialize ethernet task |
| r26291 | r26292 | |
| 2025 | 1993 | // ************************************************ |
| 2026 | 1994 | // memory refresh task |
| 2027 | 1995 | // ************************************************ |
| 2028 | | void f1_mrt_block_0(); //!< f1_mrt_block early: block the display word task |
| 1996 | void f1_early_mrt_block(); //!< F1 func: block the display word task |
| 2029 | 1997 | void activate_mrt(); //!< called by the CPU when MRT becomes active |
| 2030 | 1998 | void init_mrt(int task); //!< 010 initialize memory refresh task |
| 2031 | 1999 | void exit_mrt(); //!< deinitialize memory refresh task |
| r26291 | r26292 | |
| 2033 | 2001 | // ************************************************ |
| 2034 | 2002 | // display word task |
| 2035 | 2003 | // ************************************************ |
| 2036 | | void f1_dwt_block_0(); //!< f1_dwt_block early: block the display word task |
| 2037 | | void f2_dwt_load_ddr_1(); //!< f2_dwt_load_ddr late: load the display data register |
| 2004 | void f1_early_dwt_block(); //!< F1 func: block the display word task |
| 2005 | void f2_dwt_load_ddr_1(); //!< F2 func: load the display data register |
| 2038 | 2006 | void init_dwt(int task); //!< 011 initialize display word task |
| 2039 | 2007 | void exit_dwt(); //!< deinitialize display word task |
| 2040 | 2008 | |
| 2041 | 2009 | // ************************************************ |
| 2042 | 2010 | // cursor task |
| 2043 | 2011 | // ************************************************ |
| 2044 | | void f1_curt_block_0(); //!< f1_curt_block early: disable the cursor task and set the curt_blocks flag |
| 2045 | | void f2_load_xpreg_1(); //!< f2_load_xpreg late: load the x position register from BUS[6-15] |
| 2046 | | void f2_load_csr_1(); //!< f2_load_csr late: load the cursor shift register from BUS[0-15] |
| 2012 | void f1_early_curt_block(); //!< f1_curt_block early: disable the cursor task and set the curt_blocks flag |
| 2013 | void f2_late_load_xpreg(); //!< f2_load_xpreg late: load the x position register from BUS[6-15] |
| 2014 | void f2_late_load_csr(); //!< f2_load_csr late: load the cursor shift register from BUS[0-15] |
| 2047 | 2015 | void activate_curt(); //!< curt_activate: called by the CPU when the cursor task becomes active |
| 2048 | 2016 | void init_curt(int task); //!< 012 initialize cursor task |
| 2049 | 2017 | void exit_curt(); //!< deinitialize cursor task |
| r26291 | r26292 | |
| 2051 | 2019 | // ************************************************ |
| 2052 | 2020 | // display horizontal task |
| 2053 | 2021 | // ************************************************ |
| 2054 | | void f1_dht_block_0(); //!< f1_dht_block early: disable the display word task |
| 2055 | | void f2_dht_setmode_1(); //!< f2_dht_setmode late: set the next scanline's mode inverse and half clock and branch |
| 2022 | void f1_early_dht_block(); //!< F1 func: disable the display word task |
| 2023 | void f2_late_dht_setmode(); //!< F2 func: set the next scanline's mode inverse and half clock and branch |
| 2056 | 2024 | void activate_dht(); //!< called by the CPU when the display horizontal task becomes active |
| 2057 | 2025 | void init_dht(int task); //!< 013 initialize display horizontal task |
| 2058 | 2026 | void exit_dht(); //!< deinitialize display horizontal task |
| r26291 | r26292 | |
| 2060 | 2028 | // ************************************************ |
| 2061 | 2029 | // display vertical task |
| 2062 | 2030 | // ************************************************ |
| 2063 | | void f1_dvt_block_0(); //!< f1_dvt_block early: disable the display word task |
| 2031 | void f1_early_dvt_block(); //!< F1 func: disable the display word task |
| 2064 | 2032 | void activate_dvt(); //!< called by the CPU when the display vertical task becomes active |
| 2065 | 2033 | void init_dvt(int task); //!< 014 initialize display vertical task |
| 2066 | 2034 | void exit_dvt(); //!< deinitialize display vertical task |
| r26291 | r26292 | |
| 2075 | 2043 | // ************************************************ |
| 2076 | 2044 | // disk word task |
| 2077 | 2045 | // ************************************************ |
| 2078 | | void f1_kwd_block_0(void); |
| 2046 | void f1_early_kwd_block(); //!< F1 func: disable the disk word task |
| 2079 | 2047 | void init_kwd(int task); //!< 016 initialize disk word task |
| 2080 | 2048 | void exit_kwd(); //!< deinitialize disk word task |
| 2081 | 2049 | }; |
branches/alto2/src/emu/cpu/alto2/a2kwd.c
| r26291 | r26292 | |
| 10 | 10 | #include "alto2cpu.h" |
| 11 | 11 | |
| 12 | 12 | //! f1_kwd_block early: block the disk word task |
| 13 | | void alto2_cpu_device::f1_kwd_block_0() |
| 13 | void alto2_cpu_device::f1_early_kwd_block() |
| 14 | 14 | { |
| 15 | 15 | LOG((LOG_KWD,2," BLOCK %s\n", task_name(m_task))); |
| 16 | 16 | disk_block(m_task); |
| r26291 | r26292 | |
| 19 | 19 | //! disk word task slot initialization |
| 20 | 20 | void alto2_cpu_device::init_kwd(int task) |
| 21 | 21 | { |
| 22 | | set_bs(task, bs_kwd_read_kstat, &alto2_cpu_device::bs_read_kstat_0, 0); |
| 23 | | set_bs(task, bs_kwd_read_kdata, &alto2_cpu_device::bs_read_kdata_0, 0); |
| 22 | set_bs(task, bs_kwd_read_kstat, &alto2_cpu_device::bs_early_read_kstat, 0); |
| 23 | set_bs(task, bs_kwd_read_kdata, &alto2_cpu_device::bs_early_read_kdata, 0); |
| 24 | 24 | |
| 25 | | set_f1(task, f1_block, &alto2_cpu_device::f1_kwd_block_0, 0); |
| 25 | set_f1(task, f1_block, &alto2_cpu_device::f1_early_kwd_block, 0); |
| 26 | 26 | |
| 27 | 27 | set_f1(task, f1_task_10, 0, 0); |
| 28 | | set_f1(task, f1_kwd_strobe, 0, &alto2_cpu_device::f1_strobe_1); |
| 29 | | set_f1(task, f1_kwd_load_kstat, 0, &alto2_cpu_device::f1_load_kstat_1); |
| 30 | | set_f1(task, f1_kwd_increcno, 0, &alto2_cpu_device::f1_increcno_1); |
| 31 | | set_f1(task, f1_kwd_clrstat, 0, &alto2_cpu_device::f1_clrstat_1); |
| 32 | | set_f1(task, f1_kwd_load_kcom, 0, &alto2_cpu_device::f1_load_kcom_1); |
| 33 | | set_f1(task, f1_kwd_load_kadr, 0, &alto2_cpu_device::f1_load_kadr_1); |
| 34 | | set_f1(task, f1_kwd_load_kdata, 0, &alto2_cpu_device::f1_load_kdata_1); |
| 28 | set_f1(task, f1_kwd_strobe, 0, &alto2_cpu_device::f1_late_strobe); |
| 29 | set_f1(task, f1_kwd_load_kstat, 0, &alto2_cpu_device::f1_late_load_kstat); |
| 30 | set_f1(task, f1_kwd_increcno, 0, &alto2_cpu_device::f1_late_increcno); |
| 31 | set_f1(task, f1_kwd_clrstat, 0, &alto2_cpu_device::f1_late_clrstat); |
| 32 | set_f1(task, f1_kwd_load_kcom, 0, &alto2_cpu_device::f1_late_load_kcom); |
| 33 | set_f1(task, f1_kwd_load_kadr, 0, &alto2_cpu_device::f1_late_load_kadr); |
| 34 | set_f1(task, f1_kwd_load_kdata, 0, &alto2_cpu_device::f1_late_load_kdata); |
| 35 | 35 | |
| 36 | | set_f2(task, f2_kwd_init, 0, &alto2_cpu_device::f2_init_1); |
| 37 | | set_f2(task, f2_kwd_rwc, 0, &alto2_cpu_device::f2_rwc_1); |
| 38 | | set_f2(task, f2_kwd_recno, 0, &alto2_cpu_device::f2_recno_1); |
| 39 | | set_f2(task, f2_kwd_xfrdat, 0, &alto2_cpu_device::f2_xfrdat_1); |
| 40 | | set_f2(task, f2_kwd_swrnrdy, 0, &alto2_cpu_device::f2_swrnrdy_1); |
| 41 | | set_f2(task, f2_kwd_nfer, 0, &alto2_cpu_device::f2_nfer_1); |
| 42 | | set_f2(task, f2_kwd_strobon, 0, &alto2_cpu_device::f2_strobon_1); |
| 36 | set_f2(task, f2_kwd_init, 0, &alto2_cpu_device::f2_late_init); |
| 37 | set_f2(task, f2_kwd_rwc, 0, &alto2_cpu_device::f2_late_rwc); |
| 38 | set_f2(task, f2_kwd_recno, 0, &alto2_cpu_device::f2_late_recno); |
| 39 | set_f2(task, f2_kwd_xfrdat, 0, &alto2_cpu_device::f2_late_xfrdat); |
| 40 | set_f2(task, f2_kwd_swrnrdy, 0, &alto2_cpu_device::f2_late_swrnrdy); |
| 41 | set_f2(task, f2_kwd_nfer, 0, &alto2_cpu_device::f2_late_nfer); |
| 42 | set_f2(task, f2_kwd_strobon, 0, &alto2_cpu_device::f2_late_strobon); |
| 43 | 43 | set_f2(task, f2_task_17, 0, 0); |
| 44 | 44 | } |
| 45 | 45 | |
branches/alto2/src/emu/cpu/alto2/a2ksec.c
| r26291 | r26292 | |
| 10 | 10 | #include "alto2cpu.h" |
| 11 | 11 | |
| 12 | 12 | //! f1_ksec_block early: block the disk sector task |
| 13 | | void alto2_cpu_device::f1_ksec_block_0() |
| 13 | void alto2_cpu_device::f1_early_ksec_block() |
| 14 | 14 | { |
| 15 | 15 | LOG((LOG_KSEC,2," BLOCK %s\n", task_name(m_task))); |
| 16 | 16 | disk_block(m_task); |
| r26291 | r26292 | |
| 19 | 19 | //! disk sector task slot initialization |
| 20 | 20 | void alto2_cpu_device::init_ksec(int task) |
| 21 | 21 | { |
| 22 | | set_bs(task, bs_ksec_read_kstat, &alto2_cpu_device::bs_read_kstat_0, 0); |
| 23 | | set_bs(task, bs_ksec_read_kdata, &alto2_cpu_device::bs_read_kdata_0, 0); |
| 22 | set_bs(task, bs_ksec_read_kstat, &alto2_cpu_device::bs_early_read_kstat, 0); |
| 23 | set_bs(task, bs_ksec_read_kdata, &alto2_cpu_device::bs_early_read_kdata, 0); |
| 24 | 24 | |
| 25 | | set_f1(task, f1_block, &alto2_cpu_device::f1_ksec_block_0, 0); |
| 25 | set_f1(task, f1_block, &alto2_cpu_device::f1_early_ksec_block, 0); |
| 26 | 26 | |
| 27 | 27 | set_f1(task, f1_task_10, 0, 0); |
| 28 | | set_f1(task, f1_ksec_strobe, 0, &alto2_cpu_device::f1_strobe_1); |
| 29 | | set_f1(task, f1_ksec_load_kstat, 0, &alto2_cpu_device::f1_load_kstat_1); |
| 30 | | set_f1(task, f1_ksec_increcno, 0, &alto2_cpu_device::f1_increcno_1); |
| 31 | | set_f1(task, f1_ksec_clrstat, 0, &alto2_cpu_device::f1_clrstat_1); |
| 32 | | set_f1(task, f1_ksec_load_kcom, 0, &alto2_cpu_device::f1_load_kcom_1); |
| 33 | | set_f1(task, f1_ksec_load_kadr, 0, &alto2_cpu_device::f1_load_kadr_1); |
| 34 | | set_f1(task, f1_ksec_load_kdata, 0, &alto2_cpu_device::f1_load_kdata_1); |
| 28 | set_f1(task, f1_ksec_strobe, 0, &alto2_cpu_device::f1_late_strobe); |
| 29 | set_f1(task, f1_ksec_load_kstat, 0, &alto2_cpu_device::f1_late_load_kstat); |
| 30 | set_f1(task, f1_ksec_increcno, 0, &alto2_cpu_device::f1_late_increcno); |
| 31 | set_f1(task, f1_ksec_clrstat, 0, &alto2_cpu_device::f1_late_clrstat); |
| 32 | set_f1(task, f1_ksec_load_kcom, 0, &alto2_cpu_device::f1_late_load_kcom); |
| 33 | set_f1(task, f1_ksec_load_kadr, 0, &alto2_cpu_device::f1_late_load_kadr); |
| 34 | set_f1(task, f1_ksec_load_kdata, 0, &alto2_cpu_device::f1_late_load_kdata); |
| 35 | 35 | |
| 36 | | set_f2(task, f2_ksec_init, 0, &alto2_cpu_device::f2_init_1); |
| 37 | | set_f2(task, f2_ksec_rwc, 0, &alto2_cpu_device::f2_rwc_1); |
| 38 | | set_f2(task, f2_ksec_recno, 0, &alto2_cpu_device::f2_recno_1); |
| 39 | | set_f2(task, f2_ksec_xfrdat, 0, &alto2_cpu_device::f2_xfrdat_1); |
| 40 | | set_f2(task, f2_ksec_swrnrdy, 0, &alto2_cpu_device::f2_swrnrdy_1); |
| 41 | | set_f2(task, f2_ksec_nfer, 0, &alto2_cpu_device::f2_nfer_1); |
| 42 | | set_f2(task, f2_ksec_strobon, 0, &alto2_cpu_device::f2_strobon_1); |
| 36 | set_f2(task, f2_ksec_init, 0, &alto2_cpu_device::f2_late_init); |
| 37 | set_f2(task, f2_ksec_rwc, 0, &alto2_cpu_device::f2_late_rwc); |
| 38 | set_f2(task, f2_ksec_recno, 0, &alto2_cpu_device::f2_late_recno); |
| 39 | set_f2(task, f2_ksec_xfrdat, 0, &alto2_cpu_device::f2_late_xfrdat); |
| 40 | set_f2(task, f2_ksec_swrnrdy, 0, &alto2_cpu_device::f2_late_swrnrdy); |
| 41 | set_f2(task, f2_ksec_nfer, 0, &alto2_cpu_device::f2_late_nfer); |
| 42 | set_f2(task, f2_ksec_strobon, 0, &alto2_cpu_device::f2_late_strobon); |
| 43 | 43 | set_f2(task, f2_task_17, 0, 0); |
| 44 | 44 | |
| 45 | 45 | m_task_wakeup |= 1 << task; |
branches/alto2/src/emu/cpu/alto2/a2emu.c
| r26291 | r26292 | |
| 262 | 262 | * then the DISP field is sign-extended and put on the bus. |
| 263 | 263 | * |
| 264 | 264 | */ |
| 265 | | void alto2_cpu_device::bs_emu_disp_0() |
| 265 | void alto2_cpu_device::bs_early_emu_disp() |
| 266 | 266 | { |
| 267 | 267 | UINT16 r = IR_DISP(m_emu.ir); |
| 268 | 268 | if (IR_X(m_emu.ir)) { |
| r26291 | r26292 | |
| 277 | 277 | * |
| 278 | 278 | * The task request for the active task is cleared |
| 279 | 279 | */ |
| 280 | | void alto2_cpu_device::f1_emu_block_0() |
| 280 | void alto2_cpu_device::f1_early_emu_block() |
| 281 | 281 | { |
| 282 | 282 | #if 0 |
| 283 | 283 | CPU_CLR_TASK_WAKEUP(m_task); |
| r26291 | r26292 | |
| 300 | 300 | /** |
| 301 | 301 | * @brief f1_load_rmr late: load the reset mode register |
| 302 | 302 | */ |
| 303 | | void alto2_cpu_device::f1_emu_load_rmr_1() |
| 303 | void alto2_cpu_device::f1_late_emu_load_rmr() |
| 304 | 304 | { |
| 305 | 305 | LOG((LOG_EMU,2," RMR←; BUS (%#o)\n", m_bus)); |
| 306 | 306 | m_reset_mode = m_bus; |
| r26291 | r26292 | |
| 309 | 309 | /** |
| 310 | 310 | * @brief f1_load_esrb late: load the extended S register bank from BUS[12-14] |
| 311 | 311 | */ |
| 312 | | void alto2_cpu_device::f1_emu_load_esrb_1() |
| 312 | void alto2_cpu_device::f1_late_emu_load_esrb() |
| 313 | 313 | { |
| 314 | 314 | LOG((LOG_EMU,2," ESRB←; BUS[12-14] (%#o)\n", m_bus)); |
| 315 | 315 | m_s_reg_bank[m_task] = A2_GET16(m_bus,16,12,14); |
| r26291 | r26292 | |
| 321 | 321 | * TODO: move this to the Ethernet code? It's really a emulator |
| 322 | 322 | * specific function that is decoded by the Ethernet card. |
| 323 | 323 | */ |
| 324 | | void alto2_cpu_device::f1_rsnf_0() |
| 324 | void alto2_cpu_device::f1_early_rsnf() |
| 325 | 325 | { |
| 326 | 326 | UINT16 r = 0177400 | m_ether_id; |
| 327 | 327 | LOG((LOG_EMU,2," ←RSNF; (%#o)\n", r)); |
| r26291 | r26292 | |
| 355 | 355 | * TODO: move this to the Ethernet code? It's really a emulator |
| 356 | 356 | * specific function that is decoded by the Ethernet card. |
| 357 | 357 | */ |
| 358 | | void alto2_cpu_device::f1_startf_0() |
| 358 | void alto2_cpu_device::f1_early_startf() |
| 359 | 359 | { |
| 360 | 360 | LOG((LOG_EMU,2," STARTF (BUS is %06o)\n", m_bus)); |
| 361 | 361 | /* TODO: what do we do here? reset the CPU on bit 0? */ |
| r26291 | r26292 | |
| 370 | 370 | /** |
| 371 | 371 | * @brief f2_busodd late: branch on odd bus |
| 372 | 372 | */ |
| 373 | | void alto2_cpu_device::f2_busodd_1() |
| 373 | void alto2_cpu_device::f2_late_busodd() |
| 374 | 374 | { |
| 375 | 375 | UINT16 r = m_bus & 1; |
| 376 | 376 | LOG((LOG_EMU,2," BUSODD; %sbranch (%#o|%#o)\n", r ? "" : "no ", m_next2, r)); |
| r26291 | r26292 | |
| 381 | 381 | /** |
| 382 | 382 | * @brief f2_magic late: shift and use T |
| 383 | 383 | */ |
| 384 | | void alto2_cpu_device::f2_magic_1() |
| 384 | void alto2_cpu_device::f2_late_magic() |
| 385 | 385 | { |
| 386 | 386 | int XC; |
| 387 | 387 | switch (MIR_F1(m_mir)) { |
| r26291 | r26292 | |
| 407 | 407 | /** |
| 408 | 408 | * @brief dns early: modify RESELECT with DstAC = (3 - IR[3-4]) |
| 409 | 409 | */ |
| 410 | | void alto2_cpu_device::f2_load_dns_0() |
| 410 | void alto2_cpu_device::f2_early_load_dns() |
| 411 | 411 | { |
| 412 | 412 | #if USE_SCHEMATICS_RSEL |
| 413 | 413 | A2_PUT8(m_rsel, 5, 3, 3, RA3(f2_emu_load_dns, m_emu.ir, m_rsel)); |
| r26291 | r26292 | |
| 424 | 424 | * <PRE> |
| 425 | 425 | * New emulator carry is selected by instruction register |
| 426 | 426 | * bits CY = IR[10-11]. R register and emulator carry are |
| 427 | | * loaded only if NL = IR[12] is 0. |
| 427 | * loaded only if NL = IR[12] is 0 (NL = no load). |
| 428 | 428 | * SKIP is set according to SK = IR[13-15]. |
| 429 | 429 | * |
| 430 | 430 | * CARRY = !m_emu.cy |
| r26291 | r26292 | |
| 446 | 446 | * = (((NEWCARRY ^ 1) & IR14) | (SHZERO & IR13)) ^ IR15 |
| 447 | 447 | * </PRE> |
| 448 | 448 | */ |
| 449 | | void alto2_cpu_device::f2_load_dns_1() |
| 449 | void alto2_cpu_device::f2_late_load_dns() |
| 450 | 450 | { |
| 451 | | UINT8 IR10 = A2_BIT32(m_emu.ir,16,10); |
| 452 | | UINT8 IR11 = A2_BIT32(m_emu.ir,16,11); |
| 453 | | UINT8 IR12 = A2_BIT32(m_emu.ir,16,12); |
| 454 | | UINT8 IR13 = A2_BIT32(m_emu.ir,16,13); |
| 455 | | UINT8 IR14 = A2_BIT32(m_emu.ir,16,14); |
| 456 | | UINT8 IR15 = A2_BIT32(m_emu.ir,16,15); |
| 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); |
| 457 | 457 | UINT8 exorB = IR11 ^ IR10; |
| 458 | 458 | UINT8 CARRY = m_emu.cy ^ 1; |
| 459 | 459 | UINT8 ORA = (exorB | CARRY) ^ 1; |
| r26291 | r26292 | |
| 498 | 498 | /** |
| 499 | 499 | * @brief f2_acdest early: modify RSELECT with DstAC = (3 - IR[3-4]) |
| 500 | 500 | */ |
| 501 | | void alto2_cpu_device::f2_acdest_0() |
| 501 | void alto2_cpu_device::f2_early_acdest() |
| 502 | 502 | { |
| 503 | 503 | #if USE_SCHEMATICS_RSEL |
| 504 | 504 | ALTO2_PUT(m_rsel, 5, 3, 3, RA3(f2_emu_acdest, m_emu.ir, m_rsel)); |
| r26291 | r26292 | |
| 556 | 556 | * |
| 557 | 557 | * Loading the IR clears the skip latch. |
| 558 | 558 | */ |
| 559 | | void alto2_cpu_device::f2_load_ir_1() |
| 559 | void alto2_cpu_device::f2_late_load_ir() |
| 560 | 560 | { |
| 561 | 561 | UINT16 r = (A2_BIT16(m_bus,16,0) << 3) | A2_GET16(m_bus,16,5,7); |
| 562 | 562 | |
| r26291 | r26292 | |
| 621 | 621 | /** |
| 622 | 622 | * @brief f2_idisp late: branch on: arithmetic IR_SH, others PROM ctl2k_u3[IR[1-7]] |
| 623 | 623 | */ |
| 624 | | void alto2_cpu_device::f2_idisp_1() |
| 624 | void alto2_cpu_device::f2_late_idisp() |
| 625 | 625 | { |
| 626 | 626 | UINT16 r; |
| 627 | 627 | |
| r26291 | r26292 | |
| 641 | 641 | /** |
| 642 | 642 | * @brief f2_acsource early: modify RSELECT with SrcAC = (3 - IR[1-2]) |
| 643 | 643 | */ |
| 644 | | void alto2_cpu_device::f2_acsource_0() |
| 644 | void alto2_cpu_device::f2_early_acsource() |
| 645 | 645 | { |
| 646 | 646 | #if USE_SCHEMATICS_RSEL |
| 647 | 647 | A2_PUT8(m_rsel, 5, 3, 3, RA3(f2_emu_acsource, m_emu.ir, m_rsel)); |
| r26291 | r26292 | |
| 655 | 655 | /** |
| 656 | 656 | * @brief f2_acsource late: branch on: arithmetic IR_SH, others PROM ctl2k_u3[IR[1-7]] |
| 657 | 657 | */ |
| 658 | | void alto2_cpu_device::f2_acsource_1() |
| 658 | void alto2_cpu_device::f2_late_acsource() |
| 659 | 659 | { |
| 660 | 660 | UINT16 r; |
| 661 | 661 | |
| r26291 | r26292 | |
| 676 | 676 | { |
| 677 | 677 | init_ram(task); |
| 678 | 678 | |
| 679 | | set_bs(task, bs_emu_read_sreg, &alto2_cpu_device::bs_read_sreg_0, 0); |
| 680 | | set_bs(task, bs_emu_load_sreg, &alto2_cpu_device::bs_load_sreg_0, &alto2_cpu_device::bs_load_sreg_1); |
| 681 | | set_bs(task, bs_disp, &alto2_cpu_device::bs_emu_disp_0, 0); |
| 679 | set_bs(task, bs_emu_read_sreg, &alto2_cpu_device::bs_early_read_sreg, 0); |
| 680 | set_bs(task, bs_emu_load_sreg, &alto2_cpu_device::bs_early_load_sreg, &alto2_cpu_device::bs_late_load_sreg); |
| 681 | set_bs(task, bs_disp, &alto2_cpu_device::bs_early_emu_disp, 0); |
| 682 | 682 | |
| 683 | | set_f1(task, f1_block, &alto2_cpu_device::f1_emu_block_0, 0); // catch the emulator task trying to block (wrong branch) |
| 684 | | set_f1(task, f1_emu_swmode, 0, &alto2_cpu_device::f1_swmode_1); |
| 685 | | set_f1(task, f1_emu_wrtram, 0, &alto2_cpu_device::f1_wrtram_1); |
| 686 | | set_f1(task, f1_emu_rdram, 0, &alto2_cpu_device::f1_rdram_1); |
| 687 | | set_f1(task, f1_emu_load_rmr, 0, &alto2_cpu_device::f1_emu_load_rmr_1); |
| 683 | set_f1(task, f1_block, &alto2_cpu_device::f1_early_emu_block, 0); // catch the emulator task trying to block (wrong branch) |
| 684 | set_f1(task, f1_emu_swmode, 0, &alto2_cpu_device::f1_late_swmode); |
| 685 | set_f1(task, f1_emu_wrtram, 0, &alto2_cpu_device::f1_late_wrtram); |
| 686 | set_f1(task, f1_emu_rdram, 0, &alto2_cpu_device::f1_late_rdram); |
| 687 | set_f1(task, f1_emu_load_rmr, 0, &alto2_cpu_device::f1_late_emu_load_rmr); |
| 688 | 688 | /* F1 014 is undefined (?) */ |
| 689 | | set_f1(task, f1_task_14, 0, &alto2_cpu_device::f1_load_srb_1); |
| 690 | | set_f1(task, f1_emu_load_esrb, 0, &alto2_cpu_device::f1_emu_load_esrb_1); |
| 691 | | set_f1(task, f1_emu_rsnf, &alto2_cpu_device::f1_rsnf_0, 0); |
| 692 | | set_f1(task, f1_emu_startf, &alto2_cpu_device::f1_startf_0, 0); |
| 689 | set_f1(task, f1_task_14, 0, &alto2_cpu_device::f1_late_load_srb); |
| 690 | set_f1(task, f1_emu_load_esrb, 0, &alto2_cpu_device::f1_late_emu_load_esrb); |
| 691 | set_f1(task, f1_emu_rsnf, &alto2_cpu_device::f1_early_rsnf, 0); |
| 692 | set_f1(task, f1_emu_startf, &alto2_cpu_device::f1_early_startf, 0); |
| 693 | 693 | |
| 694 | | set_f2(task, f2_emu_busodd, 0, &alto2_cpu_device::f2_busodd_1); |
| 695 | | #if 0 |
| 696 | | set_f2(task, f2_emu_magic, 0, &alto2_cpu_device::f2_magic_1); |
| 697 | | #else |
| 698 | | set_f2(task, f2_emu_magic, 0, 0); |
| 699 | | #endif |
| 700 | | set_f2(task, f2_emu_load_dns, &alto2_cpu_device::f2_load_dns_0, &alto2_cpu_device::f2_load_dns_1); |
| 701 | | set_f2(task, f2_emu_acdest, &alto2_cpu_device::f2_acdest_0, 0); |
| 702 | | set_f2(task, f2_emu_load_ir, 0, &alto2_cpu_device::f2_load_ir_1); |
| 703 | | set_f2(task, f2_emu_idisp, 0, &alto2_cpu_device::f2_idisp_1); |
| 704 | | set_f2(task, f2_emu_acsource, &alto2_cpu_device::f2_acsource_0, &alto2_cpu_device::f2_acsource_1); |
| 694 | set_f2(task, f2_emu_busodd, 0, &alto2_cpu_device::f2_late_busodd); |
| 695 | set_f2(task, f2_emu_magic, 0, &alto2_cpu_device::f2_late_magic); |
| 696 | set_f2(task, f2_emu_load_dns, &alto2_cpu_device::f2_early_load_dns, &alto2_cpu_device::f2_late_load_dns); |
| 697 | set_f2(task, f2_emu_acdest, &alto2_cpu_device::f2_early_acdest, 0); |
| 698 | set_f2(task, f2_emu_load_ir, 0, &alto2_cpu_device::f2_late_load_ir); |
| 699 | set_f2(task, f2_emu_idisp, 0, &alto2_cpu_device::f2_late_idisp); |
| 700 | set_f2(task, f2_emu_acsource, &alto2_cpu_device::f2_early_acsource, &alto2_cpu_device::f2_late_acsource); |
| 705 | 701 | } |
| 706 | 702 | |
| 707 | 703 | void alto2_cpu_device::exit_emu() |
branches/alto2/src/emu/cpu/alto2/a2disp.c
| r26291 | r26292 | |
| 29 | 29 | * Only two bits of a38 are used: |
| 30 | 30 | * O1 (002) = STOPWAKE' |
| 31 | 31 | * O3 (010) = MBEMPTY' |
| 32 | | * |
| 33 | | * This dump is from PROM displ.a38: |
| 34 | | * 0000: 003,013,015,013,015,013,017,013,015,013,017,013,015,013,017,013, |
| 35 | | * 0020: 013,003,013,015,013,015,013,017,013,015,013,017,013,015,013,017, |
| 36 | | * 0040: 013,015,003,013,013,017,015,013,013,017,015,013,013,017,015,013, |
| 37 | | * 0060: 015,013,013,003,017,013,013,015,017,013,013,015,017,013,013,015, |
| 38 | | * 0100: 013,017,015,013,003,013,015,013,013,017,015,013,015,013,017,013, |
| 39 | | * 0120: 017,013,013,015,013,003,013,015,017,013,013,015,013,015,013,017, |
| 40 | | * 0140: 013,015,013,017,013,015,003,013,013,015,013,017,013,017,015,013, |
| 41 | | * 0160: 015,013,017,013,015,013,013,003,015,013,017,013,017,013,013,015, |
| 42 | | * 0200: 013,017,015,013,015,013,017,013,003,013,015,013,015,013,017,013, |
| 43 | | * 0220: 017,013,013,015,013,015,013,017,013,003,013,015,013,015,013,017, |
| 44 | | * 0240: 013,015,013,017,013,017,015,013,013,015,003,013,013,017,015,013, |
| 45 | | * 0260: 015,013,017,013,017,013,013,015,015,013,013,003,017,013,013,015, |
| 46 | | * 0300: 013,017,015,013,013,017,015,013,013,017,015,013,003,013,015,013, |
| 47 | | * 0320: 017,013,013,015,017,013,013,015,017,013,013,015,013,003,013,015, |
| 48 | | * 0340: 013,015,013,017,013,015,013,017,013,015,013,017,013,015,003,013, |
| 49 | | * 0360: 015,013,017,013,015,013,017,013,015,013,017,013,015,013,013,003 |
| 50 | 32 | * </PRE> |
| 51 | 33 | */ |
| 52 | 34 | |
| r26291 | r26292 | |
| 75 | 57 | * |
| 76 | 58 | * The display_state_machine() is called at a rate of pixelclock/24. |
| 77 | 59 | * |
| 78 | | * This dump is from PROM displ.a63: |
| 79 | | * 0000: 0007,0013,0015,0021,0024,0030,0034,0040, |
| 80 | | * 0010: 0044,0050,0054,0060,0064,0070,0074,0200, |
| 81 | | * 0020: 0004,0010,0014,0020,0024,0030,0034,0040, |
| 82 | | * 0030: 0044,0050,0054,0060,0064,0070,0175,0203 |
| 83 | | * |
| 84 | 60 | * Decoded states of this PROM: |
| 85 | 61 | * |
| 86 | 62 | * STATE PROM binary HBLANK HSYNC NEXT SCANEND HLCGATE |
| r26291 | r26292 | |
| 130 | 106 | * Q2 is VSYNC for the even field (with H1024=1) |
| 131 | 107 | * Q3 is VBLANK for the odd field (with H1024=0) |
| 132 | 108 | * Q4 is VBLANK for the even field (with H1024=1) |
| 133 | | * |
| 134 | | * This dump is from PROM displ.a66: |
| 135 | | * 0000: 013,013,013,013,013,012,012,012,012,012,012,012,012,013,013,013, |
| 136 | | * 0020: 013,013,013,013,013,013,013,013,013,013,013,013,013,013,013,013, |
| 137 | | * 0040: 013,013,013,013,013,013,013,013,013,013,013,013,013,013,013,013, |
| 138 | | * 0060: 013,013,013,013,013,013,013,013,013,013,013,013,013,013,013,013, |
| 139 | | * 0100: 013,013,013,013,017,017,017,017,017,017,017,017,017,017,017,017, |
| 140 | | * 0120: 017,017,017,017,017,017,017,017,017,017,017,017,017,017,017,017, |
| 141 | | * 0140: 017,017,017,017,017,017,017,017,017,017,017,017,017,017,017,017, |
| 142 | | * 0160: 017,017,017,017,017,017,017,017,017,017,017,017,017,017,017,017, |
| 143 | | * 0200: 017,017,017,017,017,017,017,017,017,017,017,017,017,017,017,017, |
| 144 | | * 0220: 017,017,017,017,017,017,007,007,007,007,005,005,005,005,005,005, |
| 145 | | * 0240: 005,005,007,007,007,007,007,007,007,007,007,007,007,007,007,007, |
| 146 | | * 0260: 007,007,007,007,007,007,007,007,007,007,007,007,007,007,007,007, |
| 147 | | * 0300: 007,007,007,007,007,007,007,007,007,007,007,007,007,007,007,007, |
| 148 | | * 0320: 007,007,007,007,007,007,007,007,017,017,017,017,017,017,017,017, |
| 149 | | * 0340: 017,017,017,017,017,017,017,017,017,017,017,017,017,017,017,017, |
| 150 | | * 0360: 017,017,017,017,017,017,017,017,017,017,017,017,017,017,017,017 |
| 151 | 109 | * </PRE> |
| 152 | 110 | */ |
| 153 | 111 | |
| r26291 | r26292 | |
| 358 | 316 | |
| 359 | 317 | if (A66_VBLANK_HI(a66, HLC1024)) { |
| 360 | 318 | /* VBLANK: remember hlc */ |
| 361 | | m_dsp.vblank = m_dsp.hlc | HLC1024; |
| 319 | m_dsp.vblank = m_dsp.hlc & ~1; |
| 362 | 320 | |
| 363 | 321 | LOG((LOG_DISPL,1, " VBLANK")); |
| 364 | 322 | |
| r26291 | r26292 | |
| 475 | 433 | * |
| 476 | 434 | * NEXT(09) = even field ? 1 : 0 |
| 477 | 435 | */ |
| 478 | | void alto2_cpu_device::f2_evenfield_1() |
| 436 | void alto2_cpu_device::f2_late_evenfield() |
| 479 | 437 | { |
| 480 | 438 | UINT16 r = HLC1024 ^ 1; |
| 481 | 439 | LOG((LOG_DISPL,2," evenfield branch on HLC1024 (%#o | %#o)\n", m_next2, r)); |
branches/alto2/src/emu/cpu/alto2/alto2cpu.c
| r26291 | r26292 | |
| 1679 | 1679 | /** |
| 1680 | 1680 | * @brief bs_read_r early: drive bus by R register |
| 1681 | 1681 | */ |
| 1682 | | void alto2_cpu_device::bs_read_r_0() |
| 1682 | void alto2_cpu_device::bs_early_read_r() |
| 1683 | 1683 | { |
| 1684 | 1684 | UINT16 r = m_r[m_rsel]; |
| 1685 | 1685 | LOG((LOG_CPU,2," ←R%02o; %s (%#o)\n", m_rsel, r_name(m_rsel), r)); |
| r26291 | r26292 | |
| 1689 | 1689 | /** |
| 1690 | 1690 | * @brief bs_load_r early: load R places 0 on the BUS |
| 1691 | 1691 | */ |
| 1692 | | void alto2_cpu_device::bs_load_r_0() |
| 1692 | void alto2_cpu_device::bs_early_load_r() |
| 1693 | 1693 | { |
| 1694 | 1694 | UINT16 r = 0; |
| 1695 | 1695 | LOG((LOG_CPU,2," R%02o←; %s (BUS&=0)\n", m_rsel, r_name(m_rsel))); |
| r26291 | r26292 | |
| 1699 | 1699 | /** |
| 1700 | 1700 | * @brief bs_load_r late: load R from SHIFTER |
| 1701 | 1701 | */ |
| 1702 | | void alto2_cpu_device::bs_load_r_1() |
| 1702 | void alto2_cpu_device::bs_late_load_r() |
| 1703 | 1703 | { |
| 1704 | 1704 | if (MIR_F2(m_mir) != f2_emu_load_dns) { |
| 1705 | 1705 | m_r[m_rsel] = m_shifter; |
| r26291 | r26292 | |
| 1719 | 1719 | /** |
| 1720 | 1720 | * @brief bs_read_md early: drive BUS from read memory data |
| 1721 | 1721 | */ |
| 1722 | | void alto2_cpu_device::bs_read_md_0() |
| 1722 | void alto2_cpu_device::bs_early_read_md() |
| 1723 | 1723 | { |
| 1724 | 1724 | #if ALTO2_DEBUG |
| 1725 | 1725 | UINT32 mar = m_mem.mar; |
| r26291 | r26292 | |
| 1732 | 1732 | /** |
| 1733 | 1733 | * @brief bs_mouse early: drive bus by mouse |
| 1734 | 1734 | */ |
| 1735 | | void alto2_cpu_device::bs_mouse_0() |
| 1735 | void alto2_cpu_device::bs_early_mouse() |
| 1736 | 1736 | { |
| 1737 | 1737 | UINT16 r = mouse_read(); |
| 1738 | 1738 | LOG((LOG_CPU,2," ←MOUSE; BUS&=MOUSE (%#o)\n", r)); |
| r26291 | r26292 | |
| 1742 | 1742 | /** |
| 1743 | 1743 | * @brief bs_disp early: drive bus by displacement (which?) |
| 1744 | 1744 | */ |
| 1745 | | void alto2_cpu_device::bs_disp_0() |
| 1745 | void alto2_cpu_device::bs_early_disp() |
| 1746 | 1746 | { |
| 1747 | 1747 | UINT16 r = 0177777; |
| 1748 | 1748 | LOG((LOG_CPU,0,"BS ←DISP not handled by task %s mpc:%04x\n", task_name(m_task), m_mpc)); |
| r26291 | r26292 | |
| 1756 | 1756 | * Load memory address register from the ALU output; |
| 1757 | 1757 | * start main memory reference (see section 2.3). |
| 1758 | 1758 | */ |
| 1759 | | void alto2_cpu_device::f1_load_mar_1() |
| 1759 | void alto2_cpu_device::f1_late_load_mar() |
| 1760 | 1760 | { |
| 1761 | 1761 | UINT8 bank = m_bank_reg[m_task]; |
| 1762 | 1762 | UINT32 msb; |
| r26291 | r26292 | |
| 1966 | 1966 | * 0 (GND) 10 I0 Q2:1 Q1:1 Q0:1 GS:0 EO:1 x x x x |
| 1967 | 1967 | * </PRE> |
| 1968 | 1968 | */ |
| 1969 | | void alto2_cpu_device::f1_task_0() |
| 1969 | void alto2_cpu_device::f1_early_task() |
| 1970 | 1970 | { |
| 1971 | 1971 | #if USE_PRIO_F9318 |
| 1972 | 1972 | /* Doesn't work yet */ |
| r26291 | r26292 | |
| 2035 | 2035 | LOG((LOG_CPU,2, " no switch\n")); |
| 2036 | 2036 | } |
| 2037 | 2037 | #else /* USE_PRIO_F9318 */ |
| 2038 | | int i; |
| 2039 | | |
| 2040 | 2038 | LOG((LOG_CPU,2, " TASK %02o:%s", m_task, task_name(m_task))); |
| 2041 | | for (i = 15; i >= 0; i--) { |
| 2039 | for (int i = 15; i >= 0; i--) { |
| 2042 | 2040 | if (m_task_wakeup & (1 << i)) { |
| 2043 | 2041 | m_next2_task = i; |
| 2044 | 2042 | if (m_next2_task != m_next_task) { |
| r26291 | r26292 | |
| 2066 | 2064 | } |
| 2067 | 2065 | #endif |
| 2068 | 2066 | |
| 2067 | void alto2_cpu_device::f1_late_l_lsh_1() |
| 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; |
| 2082 | LOG((LOG_CPU,2," SHIFTER ←L LSH 1 (%#o := %#o<<1)\n", m_shifter, m_l)); |
| 2083 | } |
| 2084 | |
| 2085 | void alto2_cpu_device::f1_late_l_rsh_1() |
| 2086 | { |
| 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 | m_shifter = m_l >> 1; |
| 2101 | LOG((LOG_CPU,2," SHIFTER ←L RSH 1 (%#o := %#o>>1)\n", m_shifter, m_l)); |
| 2102 | } |
| 2103 | |
| 2104 | void alto2_cpu_device::f1_late_l_lcy_8() |
| 2105 | { |
| 2106 | m_shifter = ((m_l >> 8) | (m_l << 8)) & 0177777; |
| 2107 | LOG((LOG_CPU,2," SHIFTER ←L LCY 8 (%#o := bswap %#o)\n", m_shifter, m_l)); |
| 2108 | } |
| 2109 | |
| 2069 | 2110 | /** |
| 2070 | 2111 | * @brief f2_bus_eq_zero late: branch on bus equals zero |
| 2071 | 2112 | */ |
| 2072 | | void alto2_cpu_device::f2_bus_eq_zero_1() |
| 2113 | void alto2_cpu_device::f2_late_bus_eq_zero() |
| 2073 | 2114 | { |
| 2074 | 2115 | UINT16 r = m_bus == 0 ? 1 : 0; |
| 2075 | 2116 | LOG((LOG_CPU,2, " BUS=0; %sbranch (%#o|%#o)\n", r ? "" : "no ", m_next2, r)); |
| r26291 | r26292 | |
| 2079 | 2120 | /** |
| 2080 | 2121 | * @brief f2_shifter_lt_zero late: branch on shifter less than zero |
| 2081 | 2122 | */ |
| 2082 | | void alto2_cpu_device::f2_shifter_lt_zero_1() |
| 2123 | void alto2_cpu_device::f2_late_shifter_lt_zero() |
| 2083 | 2124 | { |
| 2084 | 2125 | UINT16 r = (m_shifter & 0100000) ? 1 : 0; |
| 2085 | 2126 | LOG((LOG_CPU,2, " SH<0; %sbranch (%#o|%#o)\n", r ? "" : "no ", m_next2, r)); |
| r26291 | r26292 | |
| 2089 | 2130 | /** |
| 2090 | 2131 | * @brief f2_shifter_eq_zero late: branch on shifter equals zero |
| 2091 | 2132 | */ |
| 2092 | | void alto2_cpu_device::f2_shifter_eq_zero_1() |
| 2133 | void alto2_cpu_device::f2_late_shifter_eq_zero() |
| 2093 | 2134 | { |
| 2094 | 2135 | UINT16 r = m_shifter == 0 ? 1 : 0; |
| 2095 | 2136 | LOG((LOG_CPU,2, " SH=0; %sbranch (%#o|%#o)\n", r ? "" : "no ", m_next2, r)); |
| r26291 | r26292 | |
| 2099 | 2140 | /** |
| 2100 | 2141 | * @brief f2_bus late: branch on bus bits BUS[6-15] |
| 2101 | 2142 | */ |
| 2102 | | void alto2_cpu_device::f2_bus_1() |
| 2143 | void alto2_cpu_device::f2_late_bus() |
| 2103 | 2144 | { |
| 2104 | 2145 | UINT16 r = A2_GET16(m_bus,16,6,15); |
| 2105 | 2146 | LOG((LOG_CPU,2, " BUS; %sbranch (%#o|%#o)\n", r ? "" : "no ", m_next2, r)); |
| r26291 | r26292 | |
| 2109 | 2150 | /** |
| 2110 | 2151 | * @brief f2_alucy late: branch on latched ALU carry |
| 2111 | 2152 | */ |
| 2112 | | void alto2_cpu_device::f2_alucy_1() |
| 2153 | void alto2_cpu_device::f2_late_alucy() |
| 2113 | 2154 | { |
| 2114 | 2155 | UINT16 r = m_laluc0; |
| 2115 | 2156 | LOG((LOG_CPU,2, " ALUCY; %sbranch (%#o|%#o)\n", r ? "" : "no ", m_next2, r)); |
| r26291 | r26292 | |
| 2121 | 2162 | * |
| 2122 | 2163 | * Deliver BUS data to memory. |
| 2123 | 2164 | */ |
| 2124 | | void alto2_cpu_device::f2_load_md_1() |
| 2165 | void alto2_cpu_device::f2_late_load_md() |
| 2125 | 2166 | { |
| 2126 | 2167 | #if ALTO2_DEBUG |
| 2127 | 2168 | UINT16 mar = m_mem.mar; |
| r26291 | r26292 | |
| 2694 | 2735 | rdram(); |
| 2695 | 2736 | |
| 2696 | 2737 | /* |
| 2697 | | * The constant memory is gated to the bus by F1 = 7, F2 = 7, or BS >= 4 |
| 2738 | * The constant memory is gated to the bus by F1 == f1_const, F2 == f2_const, or BS >= 4 |
| 2698 | 2739 | */ |
| 2699 | | if (!do_bs || bs >= 4) { |
| 2740 | if (!do_bs || bs >= bs_task_4) { |
| 2700 | 2741 | int addr = 8 * m_rsel + bs; |
| 2701 | | // There is something going wrong with using: |
| 2702 | | // m_const->read_word(m_const->address_to_byte(addr)); |
| 2703 | | // because for addr=0160 it returns const[0161] instead of const[0160] |
| 2704 | | // For now fall back to reading the const data from the byte array |
| 2705 | 2742 | UINT16 data = m_const_data[2*addr+0] | (m_const_data[2*addr+1] << 8); |
| 2706 | 2743 | m_bus &= data; |
| 2707 | 2744 | LOG((LOG_CPU,2," %#o; BUS &= %#o CONST[%03o]\n", m_bus, data, addr)); |
| r26291 | r26292 | |
| 2709 | 2746 | |
| 2710 | 2747 | /* |
| 2711 | 2748 | * early f2 has to be done before early bs, because the |
| 2712 | | * emulator f2 acsource or acdest may change rsel |
| 2749 | * emulator f2 acsource or acdest may change m_rsel |
| 2713 | 2750 | */ |
| 2714 | 2751 | ((*this).*m_f2[0][m_task][f2])(); |
| 2715 | 2752 | |
| r26291 | r26292 | |
| 2955 | 2992 | if (m_wrtram_flag) |
| 2956 | 2993 | wrtram(); |
| 2957 | 2994 | |
| 2958 | | switch (f1) { |
| 2959 | | case f1_l_lsh_1: |
| 2960 | | if (m_task == task_emu) { |
| 2961 | | if (f2 == f2_emu_magic) { |
| 2962 | | m_shifter = ((m_l << 1) | (m_t >> 15)) & 0177777; |
| 2963 | | LOG((LOG_CPU,2," SHIFTER ←L MLSH 1 (%#o := %#o<<1|%#o)\n", m_shifter, m_l, m_t >> 15)); |
| 2964 | | break; |
| 2965 | | } |
| 2966 | | if (f2 == f2_emu_load_dns) { |
| 2967 | | /* shifter is done in F2 */ |
| 2968 | | break; |
| 2969 | | } |
| 2970 | | } |
| 2971 | | m_shifter = (m_l << 1) & 0177777; |
| 2972 | | LOG((LOG_CPU,2," SHIFTER ←L LSH 1 (%#o := %#o<<1)\n", m_shifter, m_l)); |
| 2973 | | break; |
| 2995 | // shifter passes L, if F1 is not one of L LSH 1, L RSH 1 or L LCY 8 |
| 2996 | m_shifter = m_l; |
| 2974 | 2997 | |
| 2975 | | case f1_l_rsh_1: |
| 2976 | | if (m_task == task_emu) { |
| 2977 | | if (f2 == f2_emu_magic) { |
| 2978 | | m_shifter = ((m_l >> 1) | (m_t << 15)) & 0177777; |
| 2979 | | LOG((LOG_CPU,2," SHIFTER ←L MRSH 1 (%#o := %#o>>1|%#o)\n", m_shifter, m_l, (m_t << 15) & 0100000)); |
| 2980 | | break; |
| 2981 | | } |
| 2982 | | if (f2 == f2_emu_load_dns) { |
| 2983 | | /* shifter is done in F2 */ |
| 2984 | | break; |
| 2985 | | } |
| 2986 | | } |
| 2987 | | m_shifter = m_l >> 1; |
| 2988 | | LOG((LOG_CPU,2," SHIFTER ←L RSH 1 (%#o := %#o>>1)\n", m_shifter, m_l)); |
| 2989 | | break; |
| 2990 | | |
| 2991 | | case f1_l_lcy_8: |
| 2992 | | m_shifter = ((m_l >> 8) | (m_l << 8)) & 0177777; |
| 2993 | | LOG((LOG_CPU,2," SHIFTER ←L LCY 8 (%#o := bswap %#o)\n", m_shifter, m_l)); |
| 2994 | | break; |
| 2995 | | |
| 2996 | | default: |
| 2997 | | /* shifter passes L, if F1 is not one of L LSH 1, L RSH 1 or L LCY 8 */ |
| 2998 | | m_shifter = m_l; |
| 2999 | | } |
| 3000 | | |
| 3001 | | /* late F1 is done now, if any */ |
| 2998 | /* late F1 is done now */ |
| 3002 | 2999 | ((*this).*m_f1[1][m_task][f1])(); |
| 3003 | 3000 | |
| 3004 | | /* late F2 is done now, if any */ |
| 3001 | /* late F2 is done now */ |
| 3005 | 3002 | ((*this).*m_f2[1][m_task][f2])(); |
| 3006 | 3003 | |
| 3007 | 3004 | /* late BS is done now, if no constant was put on the bus */ |
| 3008 | 3005 | if (do_bs) |
| 3009 | 3006 | ((*this).*m_bs[1][m_task][bs])(); |
| 3010 | 3007 | |
| 3011 | | /* |
| 3012 | | * update L register and LALUC0, and also M register, |
| 3013 | | * if a RAM related task is active |
| 3014 | | */ |
| 3008 | // update L register and LALUC0, and also M register, if a RAM related task is active |
| 3015 | 3009 | if (MIR_L(m_mir)) { |
| 3016 | | /* load L from ALU */ |
| 3017 | | m_l = m_alu; |
| 3010 | m_l = m_alu; // load L from ALU |
| 3018 | 3011 | if (flags & ALUM2) { |
| 3019 | 3012 | m_laluc0 = m_aluc0; |
| 3020 | 3013 | LOG((LOG_CPU,2, " L← ALU (%#o); LALUC0← ALUC0 (%o)\n", m_alu, m_aluc0)); |
| r26291 | r26292 | |
| 3023 | 3016 | LOG((LOG_CPU,2, " L← ALU (%#o); LALUC0← %o\n", m_alu, 0)); |
| 3024 | 3017 | } |
| 3025 | 3018 | if (m_ram_related[m_task]) { |
| 3026 | | /* load M from ALU, if 'GOODTASK' */ |
| 3027 | | m_m = m_alu; |
| 3028 | | /* also writes to S[bank][0], which can't be read */ |
| 3029 | | m_s[m_s_reg_bank[m_task]][0] = m_alu; |
| 3019 | m_m = m_alu; // load M from ALU, if 'GOODTASK' |
| 3020 | m_s[m_s_reg_bank[m_task]][0] = m_alu; // also writes to S[bank][0], which can't be read |
| 3030 | 3021 | LOG((LOG_CPU,2, " M← ALU (%#o)\n", m_alu)); |
| 3031 | 3022 | } |
| 3032 | 3023 | } |
| 3033 | 3024 | |
| 3034 | | /* update T register, if LOADT is set */ |
| 3025 | // update T register, if LOADT is set |
| 3035 | 3026 | if (MIR_T(m_mir)) { |
| 3036 | 3027 | m_cram_addr = m_alu; |
| 3037 | 3028 | if (flags & TSELECT) { |
| 3029 | m_t = m_alu; // T source is ALU |
| 3038 | 3030 | LOG((LOG_CPU,2, " T← ALU (%#o)\n", m_alu)); |
| 3039 | | m_t = m_alu; |
| 3040 | 3031 | } else { |
| 3032 | m_t = m_bus; // T source is BUS |
| 3041 | 3033 | LOG((LOG_CPU,2, " T← BUS (%#o)\n", m_bus)); |
| 3042 | | m_t = m_bus; |
| 3043 | 3034 | } |
| 3044 | 3035 | } |
| 3045 | 3036 | |
| r26291 | r26292 | |
| 3049 | 3040 | /* one more microinstruction */ |
| 3050 | 3041 | m_next_task = m_next2_task; |
| 3051 | 3042 | } else { |
| 3052 | | /* save this task's mpc */ |
| 3043 | /* save this task's mpc and next2 */ |
| 3053 | 3044 | m_task_mpc[m_task] = m_next; |
| 3054 | 3045 | m_task_next2[m_task] = m_next2; |
| 3055 | 3046 | m_task = m_next_task; |
| 3056 | 3047 | LOG((LOG_CPU,1, "task switch to %02o:%s (cycle %lld)\n", m_task, task_name(m_task), cycle())); |
| 3057 | | /* get new task's mpc */ |
| 3058 | | m_next = m_task_mpc[m_task]; |
| 3059 | | /* get address modifier after task switch (?) */ |
| 3060 | | m_next2 = m_task_next2[m_task]; |
| 3048 | m_next = m_task_mpc[m_task]; // get new task's mpc |
| 3049 | m_next2 = m_task_next2[m_task]; // get address modifier after task switch (needed?) |
| 3061 | 3050 | |
| 3062 | | /* |
| 3063 | | * let the task know it becomes active now |
| 3064 | | * and (most probably) reset the wakeup |
| 3065 | | */ |
| 3051 | // let the task know it becomes active now and (most probably) reset the wakeup |
| 3066 | 3052 | ((*this).*m_active_callback[m_task])(); |
| 3067 | 3053 | } |
| 3068 | 3054 | } |
| r26291 | r26292 | |
| 3090 | 3076 | if (0 == (m_reset_mode & (1 << task))) |
| 3091 | 3077 | m_task_mpc[task] |= ALTO2_UCODE_RAM_BASE; |
| 3092 | 3078 | |
| 3093 | | set_bs(task, bs_read_r, &alto2_cpu_device::bs_read_r_0, 0); |
| 3094 | | set_bs(task, bs_load_r, &alto2_cpu_device::bs_load_r_0, &alto2_cpu_device::bs_load_r_1); |
| 3079 | set_bs(task, bs_read_r, &alto2_cpu_device::bs_early_read_r, 0); |
| 3080 | set_bs(task, bs_load_r, &alto2_cpu_device::bs_early_load_r, &alto2_cpu_device::bs_late_load_r); |
| 3095 | 3081 | set_bs(task, bs_no_source, 0, 0); |
| 3096 | 3082 | set_bs(task, bs_task_3, &alto2_cpu_device::fn_bs_bad_0, &alto2_cpu_device::fn_bs_bad_1); // task specific |
| 3097 | 3083 | set_bs(task, bs_task_4, &alto2_cpu_device::fn_bs_bad_0, &alto2_cpu_device::fn_bs_bad_1); // task specific |
| 3098 | | set_bs(task, bs_read_md, &alto2_cpu_device::bs_read_md_0, 0); |
| 3099 | | set_bs(task, bs_mouse, &alto2_cpu_device::bs_mouse_0, 0); |
| 3100 | | set_bs(task, bs_disp, &alto2_cpu_device::bs_disp_0, 0); |
| 3084 | set_bs(task, bs_read_md, &alto2_cpu_device::bs_early_read_md, 0); |
| 3085 | set_bs(task, bs_mouse, &alto2_cpu_device::bs_early_mouse, 0); |
| 3086 | set_bs(task, bs_disp, &alto2_cpu_device::bs_early_disp, 0); |
| 3101 | 3087 | |
| 3102 | 3088 | set_f1(task, f1_nop, 0, 0); |
| 3103 | | set_f1(task, f1_load_mar, 0, &alto2_cpu_device::f1_load_mar_1); |
| 3104 | | set_f1(task, f1_task, &alto2_cpu_device::f1_task_0, 0); |
| 3089 | set_f1(task, f1_load_mar, 0, &alto2_cpu_device::f1_late_load_mar); |
| 3090 | set_f1(task, f1_task, &alto2_cpu_device::f1_early_task, 0); |
| 3105 | 3091 | set_f1(task, f1_block, &alto2_cpu_device::fn_f1_bad_0, &alto2_cpu_device::fn_f1_bad_1); // not all tasks have the f1_block |
| 3106 | | set_f1(task, f1_l_lsh_1, 0, 0); // inlined in execute() |
| 3107 | | set_f1(task, f1_l_rsh_1, 0, 0); // inlined in execute() |
| 3108 | | set_f1(task, f1_l_lcy_8, 0, 0); // inlined in execute() |
| 3092 | set_f1(task, f1_l_lsh_1, 0, &alto2_cpu_device::f1_late_l_lsh_1); |
| 3093 | set_f1(task, f1_l_rsh_1, 0, &alto2_cpu_device::f1_late_l_rsh_1); |
| 3094 | set_f1(task, f1_l_lcy_8, 0, &alto2_cpu_device::f1_late_l_lcy_8); |
| 3109 | 3095 | set_f1(task, f1_const, 0, 0); |
| 3110 | 3096 | set_f1(task, f1_task_10, &alto2_cpu_device::fn_f1_bad_0, &alto2_cpu_device::fn_f1_bad_1); // f1_task_10 to f1_task_17 are task specific |
| 3111 | 3097 | set_f1(task, f1_task_11, &alto2_cpu_device::fn_f1_bad_0, &alto2_cpu_device::fn_f1_bad_1); // f1_task_10 to f1_task_17 are task specific |
| r26291 | r26292 | |
| 3117 | 3103 | set_f1(task, f1_task_17, &alto2_cpu_device::fn_f1_bad_0, &alto2_cpu_device::fn_f1_bad_1); // f1_task_10 to f1_task_17 are task specific |
| 3118 | 3104 | |
| 3119 | 3105 | set_f2(task, f2_nop, 0, 0); |
| 3120 | | set_f2(task, f2_bus_eq_zero, 0, &alto2_cpu_device::f2_bus_eq_zero_1); |
| 3121 | | set_f2(task, f2_shifter_lt_zero,0, &alto2_cpu_device::f2_shifter_lt_zero_1); |
| 3122 | | set_f2(task, f2_shifter_eq_zero,0, &alto2_cpu_device::f2_shifter_eq_zero_1); |
| 3123 | | set_f2(task, f2_bus, 0, &alto2_cpu_device::f2_bus_1); |
| 3124 | | set_f2(task, f2_alucy, 0, &alto2_cpu_device::f2_alucy_1); |
| 3125 | | set_f2(task, f2_load_md, 0, &alto2_cpu_device::f2_load_md_1); |
| 3106 | set_f2(task, f2_bus_eq_zero, 0, &alto2_cpu_device::f2_late_bus_eq_zero); |
| 3107 | set_f2(task, f2_shifter_lt_zero,0, &alto2_cpu_device::f2_late_shifter_lt_zero); |
| 3108 | set_f2(task, f2_shifter_eq_zero,0, &alto2_cpu_device::f2_late_shifter_eq_zero); |
| 3109 | set_f2(task, f2_bus, 0, &alto2_cpu_device::f2_late_bus); |
| 3110 | set_f2(task, f2_alucy, 0, &alto2_cpu_device::f2_late_alucy); |
| 3111 | set_f2(task, f2_load_md, 0, &alto2_cpu_device::f2_late_load_md); |
| 3126 | 3112 | set_f2(task, f2_const, 0, 0); |
| 3127 | 3113 | set_f2(task, f2_task_10, &alto2_cpu_device::fn_f2_bad_0, &alto2_cpu_device::fn_f2_bad_1); // f2_task_10 to f2_task_17 are task specific |
| 3128 | 3114 | set_f2(task, f2_task_11, &alto2_cpu_device::fn_f2_bad_0, &alto2_cpu_device::fn_f2_bad_1); // f2_task_10 to f2_task_17 are task specific |