alto2: remove member function pointers

There was little to no advantage in calling the various subdevice
bs, f1 and f2 early/late functions through function pointers.
The original idea was to make this configurable, which it isn't.

The hardware, or schematics, define the functions and they are
(almost entirely) static anyway.

By removing the function pointers and inlining the appropriate calls
into switch/case statements there's a speed improvement of ~ 2.5x here,
seen while the diablo bitclk is not running.
This commit is contained in:
jbu 2016-08-08 16:54:17 +02:00
parent 463212cf1b
commit 2df48cca2a
14 changed files with 477 additions and 237 deletions

View File

@ -67,10 +67,6 @@ void alto2_cpu_device::activate_curt()
/** @brief initialize the cursor task F1 and F2 functions */
void alto2_cpu_device::init_curt(int task)
{
set_f1(task, f1_block, &alto2_cpu_device::f1_early_curt_block, nullptr);
set_f2(task, f2_curt_load_xpreg, nullptr, &alto2_cpu_device::f2_late_load_xpreg);
set_f2(task, f2_curt_load_csr, nullptr, &alto2_cpu_device::f2_late_load_csr);
m_active_callback[task] = &alto2_cpu_device::activate_curt;
}
void alto2_cpu_device::exit_curt()

View File

@ -95,10 +95,6 @@ void alto2_cpu_device::activate_dht()
*/
void alto2_cpu_device::init_dht(int task)
{
set_f1(task, f1_block, &alto2_cpu_device::f1_early_dht_block, nullptr);
set_f2(task, f2_dht_evenfield, nullptr, &alto2_cpu_device::f2_late_evenfield);
set_f2(task, f2_dht_setmode, nullptr, &alto2_cpu_device::f2_late_dht_setmode);
m_active_callback[task] = &alto2_cpu_device::activate_dht;
}
void alto2_cpu_device::exit_dht()

View File

@ -53,9 +53,6 @@ void alto2_cpu_device::activate_dvt()
*/
void alto2_cpu_device::init_dvt(int task)
{
set_f1(task, f1_block, &alto2_cpu_device::f1_early_dvt_block, nullptr);
set_f2(task, f2_dvt_evenfield, nullptr, &alto2_cpu_device::f2_late_evenfield);
m_active_callback[task] = &alto2_cpu_device::activate_dvt;
}
void alto2_cpu_device::exit_dvt()

View File

@ -75,8 +75,6 @@ void alto2_cpu_device::f2_late_dwt_load_ddr()
void alto2_cpu_device::init_dwt(int task)
{
set_f1(task, f1_block, &alto2_cpu_device::f1_early_dwt_block, nullptr);
set_f2(task, f2_dwt_load_ddr, nullptr, &alto2_cpu_device::f2_late_dwt_load_ddr);
}
void alto2_cpu_device::exit_dwt()

View File

@ -656,28 +656,6 @@ void alto2_cpu_device::init_emu(int task)
save_item(NAME(m_emu.cy));
init_ram(task);
set_bs(task, bs_emu_read_sreg, &alto2_cpu_device::bs_early_read_sreg, nullptr);
set_bs(task, bs_emu_load_sreg, &alto2_cpu_device::bs_early_load_sreg, &alto2_cpu_device::bs_late_load_sreg);
set_bs(task, bs_disp, &alto2_cpu_device::bs_early_emu_disp, nullptr);
set_f1(task, f1_block, &alto2_cpu_device::f1_early_emu_block, nullptr); // catch the emulator task trying to block (wrong branch)
set_f1(task, f1_emu_swmode, nullptr, &alto2_cpu_device::f1_late_swmode);
set_f1(task, f1_emu_wrtram, nullptr, &alto2_cpu_device::f1_late_wrtram);
set_f1(task, f1_emu_rdram, nullptr, &alto2_cpu_device::f1_late_rdram);
set_f1(task, f1_emu_load_rmr, nullptr, &alto2_cpu_device::f1_late_emu_load_rmr);
set_f1(task, f1_task_14, nullptr, nullptr); // F1 014 is undefined (?)
set_f1(task, f1_emu_load_esrb, nullptr, &alto2_cpu_device::f1_late_emu_load_esrb);
set_f1(task, f1_emu_rsnf, &alto2_cpu_device::f1_early_rsnf, nullptr);
set_f1(task, f1_emu_startf, &alto2_cpu_device::f1_early_startf, nullptr);
set_f2(task, f2_emu_busodd, nullptr, &alto2_cpu_device::f2_late_busodd);
set_f2(task, f2_emu_magic, nullptr, &alto2_cpu_device::f2_late_magic);
set_f2(task, f2_emu_load_dns, &alto2_cpu_device::f2_early_load_dns, &alto2_cpu_device::f2_late_load_dns);
set_f2(task, f2_emu_acdest, &alto2_cpu_device::f2_early_acdest, nullptr);
set_f2(task, f2_emu_load_ir, nullptr, &alto2_cpu_device::f2_late_load_ir);
set_f2(task, f2_emu_idisp, nullptr, &alto2_cpu_device::f2_late_idisp);
set_f2(task, f2_emu_acsource, &alto2_cpu_device::f2_early_acsource, &alto2_cpu_device::f2_late_acsource);
}
void alto2_cpu_device::exit_emu()

View File

@ -1321,23 +1321,6 @@ void alto2_cpu_device::init_ether(int task)
m_ether_a42 = prom_load(machine(), &pl_enet_a42, memregion("ether_a42")->base());
m_ether_a49 = prom_load(machine(), &pl_enet_a49, memregion("ether_a49")->base());
set_bs(task, bs_ether_eidfct, &alto2_cpu_device::bs_early_eidfct, nullptr);
set_f1(task, f1_block, &alto2_cpu_device::f1_early_eth_block, nullptr);
set_f1(task, f1_ether_eilfct, &alto2_cpu_device::f1_early_eilfct, nullptr);
set_f1(task, f1_ether_epfct, &alto2_cpu_device::f1_early_epfct, nullptr);
set_f1(task, f1_ether_ewfct, nullptr, &alto2_cpu_device::f1_late_ewfct);
set_f2(task, f2_ether_eodfct, nullptr, &alto2_cpu_device::f2_late_eodfct);
set_f2(task, f2_ether_eosfct, nullptr, &alto2_cpu_device::f2_late_eosfct);
set_f2(task, f2_ether_erbfct, nullptr, &alto2_cpu_device::f2_late_erbfct);
set_f2(task, f2_ether_eefct, nullptr, &alto2_cpu_device::f2_late_eefct);
set_f2(task, f2_ether_ebfct, nullptr, &alto2_cpu_device::f2_late_ebfct);
set_f2(task, f2_ether_ecbfct, nullptr, &alto2_cpu_device::f2_late_ecbfct);
set_f2(task, f2_ether_eisfct, nullptr, &alto2_cpu_device::f2_late_eisfct);
m_active_callback[task] = &alto2_cpu_device::activate_eth;
m_eth.rx_packet = std::make_unique<UINT16[]>(sizeof(UINT16)*ALTO2_ETHER_PACKET_SIZE);
m_eth.tx_packet = std::make_unique<UINT16[]>(sizeof(UINT16)*ALTO2_ETHER_PACKET_SIZE);

View File

@ -17,29 +17,6 @@ void alto2_cpu_device::f1_early_ksec_block()
//! disk sector task slot initialization
void alto2_cpu_device::init_ksec(int task)
{
set_bs(task, bs_ksec_read_kstat, &alto2_cpu_device::bs_early_read_kstat, nullptr);
set_bs(task, bs_ksec_read_kdata, &alto2_cpu_device::bs_early_read_kdata, nullptr);
set_f1(task, f1_block, &alto2_cpu_device::f1_early_ksec_block, nullptr);
set_f1(task, f1_task_10, nullptr, nullptr);
set_f1(task, f1_ksec_strobe, nullptr, &alto2_cpu_device::f1_late_strobe);
set_f1(task, f1_ksec_load_kstat, nullptr, &alto2_cpu_device::f1_late_load_kstat);
set_f1(task, f1_ksec_increcno, nullptr, &alto2_cpu_device::f1_late_increcno);
set_f1(task, f1_ksec_clrstat, nullptr, &alto2_cpu_device::f1_late_clrstat);
set_f1(task, f1_ksec_load_kcom, nullptr, &alto2_cpu_device::f1_late_load_kcom);
set_f1(task, f1_ksec_load_kadr, nullptr, &alto2_cpu_device::f1_late_load_kadr);
set_f1(task, f1_ksec_load_kdata, nullptr, &alto2_cpu_device::f1_late_load_kdata);
set_f2(task, f2_ksec_init, nullptr, &alto2_cpu_device::f2_late_init);
set_f2(task, f2_ksec_rwc, nullptr, &alto2_cpu_device::f2_late_rwc);
set_f2(task, f2_ksec_recno, nullptr, &alto2_cpu_device::f2_late_recno);
set_f2(task, f2_ksec_xfrdat, nullptr, &alto2_cpu_device::f2_late_xfrdat);
set_f2(task, f2_ksec_swrnrdy, nullptr, &alto2_cpu_device::f2_late_swrnrdy);
set_f2(task, f2_ksec_nfer, nullptr, &alto2_cpu_device::f2_late_nfer);
set_f2(task, f2_ksec_strobon, nullptr, &alto2_cpu_device::f2_late_strobon);
set_f2(task, f2_task_17, nullptr, nullptr);
m_task_wakeup |= 1 << task;
}

View File

@ -17,28 +17,6 @@ void alto2_cpu_device::f1_early_kwd_block()
//! disk word task slot initialization
void alto2_cpu_device::init_kwd(int task)
{
set_bs(task, bs_kwd_read_kstat, &alto2_cpu_device::bs_early_read_kstat, nullptr);
set_bs(task, bs_kwd_read_kdata, &alto2_cpu_device::bs_early_read_kdata, nullptr);
set_f1(task, f1_block, &alto2_cpu_device::f1_early_kwd_block, nullptr);
set_f1(task, f1_task_10, nullptr, nullptr);
set_f1(task, f1_kwd_strobe, nullptr, &alto2_cpu_device::f1_late_strobe);
set_f1(task, f1_kwd_load_kstat, nullptr, &alto2_cpu_device::f1_late_load_kstat);
set_f1(task, f1_kwd_increcno, nullptr, &alto2_cpu_device::f1_late_increcno);
set_f1(task, f1_kwd_clrstat, nullptr, &alto2_cpu_device::f1_late_clrstat);
set_f1(task, f1_kwd_load_kcom, nullptr, &alto2_cpu_device::f1_late_load_kcom);
set_f1(task, f1_kwd_load_kadr, nullptr, &alto2_cpu_device::f1_late_load_kadr);
set_f1(task, f1_kwd_load_kdata, nullptr, &alto2_cpu_device::f1_late_load_kdata);
set_f2(task, f2_kwd_init, nullptr, &alto2_cpu_device::f2_late_init);
set_f2(task, f2_kwd_rwc, nullptr, &alto2_cpu_device::f2_late_rwc);
set_f2(task, f2_kwd_recno, nullptr, &alto2_cpu_device::f2_late_recno);
set_f2(task, f2_kwd_xfrdat, nullptr, &alto2_cpu_device::f2_late_xfrdat);
set_f2(task, f2_kwd_swrnrdy, nullptr, &alto2_cpu_device::f2_late_swrnrdy);
set_f2(task, f2_kwd_nfer, nullptr, &alto2_cpu_device::f2_late_nfer);
set_f2(task, f2_kwd_strobon, nullptr, &alto2_cpu_device::f2_late_strobon);
set_f2(task, f2_task_17, nullptr, nullptr);
}
void alto2_cpu_device::exit_kwd()

View File

@ -29,9 +29,6 @@ void alto2_cpu_device::activate_mrt()
//! memory refresh task slots initialization
void alto2_cpu_device::init_mrt(int task)
{
set_f1(task, f1_block, &alto2_cpu_device::f1_early_mrt_block, nullptr);
/* auto block */
m_active_callback[task] = &alto2_cpu_device::activate_mrt;
}
void alto2_cpu_device::exit_mrt()

View File

@ -16,7 +16,6 @@ void alto2_cpu_device::activate_part()
//! parity task slots initialization
void alto2_cpu_device::init_part(int task)
{
m_active_callback[task] = &alto2_cpu_device::activate_part;
}
void alto2_cpu_device::exit_part()

View File

@ -117,21 +117,14 @@ void alto2_cpu_device::wrtram()
{
UINT32 bank = GET_CRAM_BANKSEL(m_cram_addr);
UINT32 wordaddr = GET_CRAM_WORDADDR(m_cram_addr);
UINT32 value = ((m_m << 16) | m_alu) ^ ALTO2_UCODE_INVERTED;
UINT32 value = ((m_myl << 16) | m_alu) ^ ALTO2_UCODE_INVERTED;
UINT32 addr = bank * ALTO2_UCODE_PAGE_SIZE + wordaddr; // write RAM 0,1,2
LOG((this,LOG_CPU,0," wrtram: RAM%d [%04o] upper:%06o lower:%06o", bank, wordaddr, m_m, m_alu));
LOG((this,LOG_CPU,0," wrtram: RAM%d [%04o] upper:%06o lower:%06o", bank, wordaddr, m_myl, m_alu));
#if DEBUG_WRTRAM
char buff[128];
UINT8 oprom[4];
oprom[0] = m_m / 256;
oprom[1] = m_m % 256;
oprom[2] = m_m / 256;
oprom[3] = m_m % 256;
disasm_disassemble(buff, addr, oprom, oprom, 0);
printf("WR CRAM_BANKSEL=%d RAM%d [%04o] upper:%06o lower:%06o *** %s\n",
GET_CRAM_BANKSEL(m_cram_addr), bank, wordaddr, m_m, m_alu, buff);
printf("WR CRAM_BANKSEL=%d RAM%d [%04o] upper:%06o lower:%06o\n",
GET_CRAM_BANKSEL(m_cram_addr), bank, wordaddr, m_myl, m_alu);
#endif
m_wrtram_flag = false;
@ -158,7 +151,7 @@ void alto2_cpu_device::bs_early_read_sreg()
r = m_s[bank][rsel()];
LOG((this,LOG_RAM,2," <-S%02o; bus &= S[%o][%02o] (%#o)\n", rsel(), bank, rsel(), r));
} else {
r = m_m;
r = m_myl;
LOG((this,LOG_RAM,2," <-S%02o; bus &= M (%#o)\n", rsel(), r));
}
m_bus &= r;
@ -180,8 +173,8 @@ void alto2_cpu_device::bs_early_load_sreg()
void alto2_cpu_device::bs_late_load_sreg()
{
UINT8 bank = m_s_reg_bank[m_task];
m_s[bank][rsel()] = m_m;
LOG((this,LOG_RAM,2," S%02o<- S[%o][%02o] := %#o\n", rsel(), bank, rsel(), m_m));
m_s[bank][rsel()] = m_myl;
LOG((this,LOG_RAM,2," S%02o<- S[%o][%02o] := %#o\n", rsel(), bank, rsel(), m_myl));
}
/**
@ -410,18 +403,6 @@ void alto2_cpu_device::f1_late_load_srb()
void alto2_cpu_device::init_ram(int task)
{
m_ram_related[task] = true;
set_bs(task, bs_ram_read_slocation, &alto2_cpu_device::bs_early_read_sreg, nullptr);
set_bs(task, bs_ram_load_slocation, &alto2_cpu_device::bs_early_load_sreg, &alto2_cpu_device::bs_late_load_sreg);
set_f1(task, f1_ram_swmode, nullptr, &alto2_cpu_device::f1_late_swmode);
set_f1(task, f1_ram_wrtram, nullptr, &alto2_cpu_device::f1_late_wrtram);
set_f1(task, f1_ram_rdram, nullptr, &alto2_cpu_device::f1_late_rdram);
#if (ALTO2_UCODE_RAM_PAGES == 3)
set_f1(task, f1_ram_load_rmr, 0, &alto2_cpu_device::f1_late_load_rmr);
#else // ALTO2_UCODE_RAM_PAGES != 3
set_f1(task, f1_ram_load_srb, nullptr, &alto2_cpu_device::f1_late_load_srb);
#endif
}
void alto2_cpu_device::exit_ram()
@ -433,6 +414,6 @@ void alto2_cpu_device::reset_ram()
{
m_rdram_flag = false;
m_wrtram_flag = false;
m_m = 0;
m_myl = 0;
memset(m_s, 0, sizeof(m_s));
}

View File

@ -19,12 +19,12 @@
*/
static UINT32 ones_u32(UINT32 val)
{
val -= ((val >> 1) & 0x55555555);
val = (((val >> 2) & 0x33333333) + (val & 0x33333333));
val = (((val >> 4) + val) & 0x0f0f0f0f);
val += (val >> 8);
val += (val >> 16);
return (val & 0x0000003f);
val -= ((val >> 1) & 0x55555555);
val = (((val >> 2) & 0x33333333) + (val & 0x33333333));
val = (((val >> 4) + val) & 0x0f0f0f0f);
val += (val >> 8);
val += (val >> 16);
return val & 0x3f;
}
/**

View File

@ -144,7 +144,7 @@ alto2_cpu_device::alto2_cpu_device(const machine_config& mconfig, const char* ta
m_l(0),
m_shifter(0),
m_laluc0(0),
m_m(0),
m_myl(0),
m_cram_addr(0),
m_task_wakeup(0),
m_reset_mode(0xffff),
@ -188,12 +188,8 @@ alto2_cpu_device::alto2_cpu_device(const machine_config& mconfig, const char* ta
memset(m_task_next2, 0x00, sizeof(m_task_next2));
memset(m_r, 0x00, sizeof(m_r));
memset(m_s, 0x00, sizeof(m_s));
memset(m_active_callback, 0x00, sizeof(m_active_callback));
memset(m_s_reg_bank, 0x00, sizeof(m_s_reg_bank));
memset(m_bank_reg, 0x00, sizeof(m_bank_reg));
memset(m_bs, 0x00, sizeof(m_bs));
memset(m_f1, 0x00, sizeof(m_f1));
memset(m_f2, 0x00, sizeof(m_f2));
memset(m_ram_related, 0x00, sizeof(m_ram_related));
memset(m_drive, 0x00, sizeof(m_drive));
memset(m_sysclka0, 0x00, sizeof(m_sysclka0));
@ -863,7 +859,7 @@ void alto2_cpu_device::device_start()
save_item(NAME(m_l));
save_item(NAME(m_shifter));
save_item(NAME(m_laluc0));
save_item(NAME(m_m));
save_item(NAME(m_myl));
save_item(NAME(m_cram_addr));
save_item(NAME(m_task_wakeup));
save_item(NAME(m_reset_mode));
@ -897,7 +893,7 @@ void alto2_cpu_device::device_start()
state_add( A2_L, "L", m_l).formatstr("%06O");
state_add( A2_SHIFTER, "SHIFTER", m_shifter).formatstr("%06O");
state_add( A2_LALUC0, "LALUC0", m_laluc0).mask(1);
state_add( A2_M, "M", m_m).formatstr("%06O");
state_add( A2_M, "M", m_myl).formatstr("%06O");
state_add_divider(-1);
state_add( A2_AC3, "AC(3)", m_r[000]).formatstr("%06O");
state_add( A2_AC2, "AC(2)", m_r[001]).formatstr("%06O");
@ -1281,42 +1277,42 @@ void alto2_cpu_device::watch_write(UINT32 addr, UINT32 data)
#endif
/** @brief fatal exit on unitialized dynamic phase BUS source */
void alto2_cpu_device::fn_bs_bad_0()
void alto2_cpu_device::bs_early_bad()
{
fatal(9,"fatal: bad early bus source pointer for task %s, mpc:%05o bs:%s\n",
task_name(m_task), m_mpc, bs_name(bs()));
}
/** @brief fatal exit on unitialized latching phase BUS source */
void alto2_cpu_device::fn_bs_bad_1()
void alto2_cpu_device::bs_late_bad()
{
fatal(9,"fatal: bad late bus source pointer for task %s, mpc:%05o bs: %s\n",
task_name(m_task), m_mpc, bs_name(bs()));
}
/** @brief fatal exit on unitialized dynamic phase F1 function */
void alto2_cpu_device::fn_f1_bad_0()
void alto2_cpu_device::f1_early_bad()
{
fatal(9,"fatal: bad early f1 function pointer for task %s, mpc:%05o f1: %s\n",
task_name(m_task), m_mpc, f1_name(f1()));
}
/** @brief fatal exit on unitialized latching phase F1 function */
void alto2_cpu_device::fn_f1_bad_1()
void alto2_cpu_device::f1_late_bad()
{
fatal(9,"fatal: bad late f1 function pointer for task %s, mpc:%05o f1: %s\n",
task_name(m_task), m_mpc, f1_name(f1()));
}
/** @brief fatal exit on unitialized dynamic phase F2 function */
void alto2_cpu_device::fn_f2_bad_0()
void alto2_cpu_device::f2_early_bad()
{
fatal(9,"fatal: bad early f2 function pointer for task %s, mpc:%05o f2: %s\n",
task_name(m_task), m_mpc, f2_name(f2()));
}
/** @brief fatal exit on unitialized latching phase F2 function */
void alto2_cpu_device::fn_f2_bad_1()
void alto2_cpu_device::f2_late_bad()
{
fatal(9,"fatal: bad late f2 function pointer for task %s, mpc:%05o f2: %s\n",
task_name(m_task), m_mpc, f2_name(f2()));
@ -2335,14 +2331,170 @@ void alto2_cpu_device::execute_run()
* because the emulator task F2 acsource or acdest may
* change the m_rsel
*/
((*this).*m_f2[0][m_task][f2()])();
switch (f2()) {
case f2_task_12: // f2 12 task specific
switch (m_task) {
case task_emu: // emulator task
f2_early_load_dns();
break;
}
break;
case f2_task_13: // f2 13 task specific
switch (m_task) {
case task_emu: // emulator task
f2_early_acdest();
break;
}
break;
case f2_task_16: // f2 16 task specific
switch (m_task) {
case task_emu: // emulator task
f2_early_acsource();
break;
}
break;
}
// early BS function can be done now
if (do_bs)
((*this).*m_bs[0][m_task][bs()])();
if (do_bs) {
switch (bs()) {
case bs_read_r: // BUS source is R register
bs_early_read_r();
break;
case bs_load_r: // load R register from BUS
bs_early_load_r();
break;
case bs_task_3: // BUS source is task specific
switch (m_task) {
case task_emu: // emulator task
bs_early_read_sreg();
break;
case task_ksec: // disk sector task
case task_kwd: // disk word task
bs_early_read_kstat();
break;
case task_ether: // ethernet task
bs_early_eidfct();
break;
case task_mrt: // memory refresh task
case task_dwt: // display word task
case task_curt: // cursor task
case task_dht: // display horizontal task
case task_dvt: // display vertical task
case task_part: // parity task
break;
default:
bs_early_bad();
}
break;
case bs_task_4: // BUS source is task specific
switch (m_task) {
case task_emu: // emulator task
bs_early_load_sreg();
break;
case task_ksec: // disk sector task
case task_kwd: // disk word task
bs_early_read_kdata();
break;
case task_ether: // ethernet task
case task_mrt: // memory refresh task
case task_dwt: // display word task
case task_curt: // cursor task
case task_dht: // display horizontal task
case task_dvt: // display vertical task
case task_part: // parity task
break;
default:
bs_early_bad();
}
break;
case bs_read_md: // BUS source is memory data
bs_early_read_md();
break;
case bs_mouse: // BUS source is mouse data
bs_early_mouse();
break;
case bs_disp: // BUS source displacement (emulator task)
switch (m_task) {
case task_emu: // emulator task
bs_early_emu_disp();
break;
default:
bs_early_disp();
}
break;
}
}
// early F1 function
((*this).*m_f1[0][m_task][f1()])();
switch (f1()) {
case f1_task: // f1 02 task switch
f1_early_task();
break;
case f1_block: // f1 03 task block
switch (m_task) {
case task_emu: // emulator task
f1_early_emu_block();
break;
case task_ksec: // disk sector task
f1_early_ksec_block();
break;
case task_ether: // ethernet task
f1_early_eth_block();
break;
case task_mrt: // memory refresh task
f1_early_mrt_block();
break;
case task_dwt: // display word task
f1_early_dwt_block();
break;
case task_curt: // cursor task
f1_early_curt_block();
break;
case task_dht: // display horizontal task
f1_early_dht_block();
break;
case task_dvt: // display vertical task
f1_early_dvt_block();
break;
case task_part: // parity task
f1_early_block();
break;
case task_kwd: // disk word task
f1_early_kwd_block();
break;
}
break;
case f1_task_13: // f1 13 task specific
switch (m_task) {
case task_ether: // ethernet task
f1_early_eilfct();
break;
}
break;
case f1_task_14: // f1 14 task specific
switch (m_task) {
case task_ether: // ethernet task
f1_early_epfct();
break;
}
break;
case f1_task_16: // f1 16 task specific
switch (m_task) {
case task_emu: // emulator task
f1_early_rsnf();
break;
}
break;
case f1_task_17: // f1 17 task specific
switch (m_task) {
case task_emu: // emulator task
f1_early_startf();
break;
}
break;
}
/**
* The ALU a10 PROM address lines are
@ -2367,14 +2519,255 @@ void alto2_cpu_device::execute_run()
m_shifter = m_l;
// late F1 function call now
((*this).*m_f1[1][m_task][f1()])();
switch (f1()) {
case f1_load_mar: // f1 01 load memory address register
f1_late_load_mar();
break;
case f1_l_lsh_1: // f1 04 left shift L once
f1_late_l_lsh_1();
break;
case f1_l_rsh_1: // f1 05 right shift L once
f1_late_l_rsh_1();
break;
case f1_l_lcy_8: // f1 06 cycle L 8 times
f1_late_l_lcy_8();
break;
case f1_task_10: // f1 10 task specific
switch (m_task) {
case task_emu: // emulator task
f1_late_swmode();
break;
}
break;
case f1_task_11: // f1 11 task specific
switch (m_task) {
case task_emu: // emulator task
f1_late_wrtram();
break;
case task_ksec: // disk sector task
case task_kwd: // disk word task
f1_late_strobe();
break;
}
break;
case f1_task_12: // f1 12 task specific
switch (m_task) {
case task_emu: // emulator task
f1_late_rdram();
break;
case task_ksec: // disk sector task
case task_kwd: // disk word task
f1_late_load_kstat();
break;
}
break;
case f1_task_13: // f1 13 task specific
switch (m_task) {
case task_emu: // emulator task
#if (ALTO2_UCODE_RAM_PAGES == 3)
f1_late_load_rmr();
#else
f1_late_load_srb();
#endif
break;
case task_ksec: // disk sector task
case task_kwd: // disk word task
f1_late_increcno();
break;
}
break;
case f1_task_14: // f1 14 task specific
switch (m_task) {
case task_ksec: // disk sector task
case task_kwd: // disk word task
f1_late_clrstat();
break;
}
break;
case f1_task_15: // f1 15 task specific
switch (m_task) {
case task_emu: // emulator task
f1_late_emu_load_esrb();
break;
case task_ksec: // disk sector task
case task_kwd: // disk word task
f1_late_load_kcom();
break;
case task_ether: // ethernet task
f1_late_ewfct();
break;
}
break;
case f1_task_16: // f1 16 task specific
switch (m_task) {
case task_ksec: // disk sector task
case task_kwd: // disk word task
f1_late_load_kadr();
break;
}
break;
case f1_task_17: // f1 17 task specific
switch (m_task) {
case task_ksec: // disk sector task
case task_kwd: // disk word task
f1_late_load_kdata();
break;
}
break;
}
// late F2 function call now
((*this).*m_f2[1][m_task][f2()])();
switch (f2()) {
case f2_bus_eq_zero: // f2 01 branch on bus equals 0
f2_late_bus_eq_zero();
break;
case f2_shifter_lt_zero: // f2 02 branch on shifter less than 0
f2_late_shifter_lt_zero();
break;
case f2_shifter_eq_zero: // f2 03 branch on shifter equals 0
f2_late_shifter_eq_zero();
break;
case f2_bus: // f2 04 branch on BUS[6-15]
f2_late_bus();
break;
case f2_alucy: // f2 05 branch on (latched) ALU carry
f2_late_alucy();
break;
case f2_load_md: // f2 06 load memory data
f2_late_load_md();
break;
case f2_task_10: // f2 10 task specific
switch (m_task) {
case task_emu: // emulator task
f2_late_busodd();
break;
case task_ksec: // disk sector task
case task_kwd: // disk word task
f2_late_init();
break;
case task_ether: // ethernet task
f2_late_eodfct();
break;
case task_dwt: // display word task
f2_late_dwt_load_ddr();
break;
case task_curt: // cursor task
f2_late_load_xpreg();
break;
case task_dht: // display horizontal task
f2_late_evenfield();
break;
case task_dvt: // display vertical task
f2_late_evenfield();
break;
}
break;
case f2_task_11: // f2 11 task specific
switch (m_task) {
case task_emu: // emulator task
f2_late_magic();
break;
case task_ksec: // disk sector task
case task_kwd: // disk word task
f2_late_rwc();
break;
case task_ether: // ethernet task
f2_late_eosfct();
break;
case task_curt: // cursor task
f2_late_load_csr();
break;
case task_dht: // display horizontal task
f2_late_dht_setmode();
break;
}
break;
case f2_task_12: // f2 12 task specific
switch (m_task) {
case task_emu: // emulator task
f2_late_load_dns();
break;
case task_ksec: // disk sector task
case task_kwd: // disk word task
f2_late_recno();
break;
case task_ether: // ethernet task
f2_late_erbfct();
break;
}
break;
case f2_task_13: // f2 13 task specific
switch (m_task) {
case task_ksec: // disk sector task
case task_kwd: // disk word task
f2_late_xfrdat();
break;
case task_ether: // ethernet task
f2_late_eefct();
break;
}
break;
case f2_task_14: // f2 14 task specific
switch (m_task) {
case task_emu: // emulator task
f2_late_load_ir();
break;
case task_ksec: // disk sector task
case task_kwd: // disk word task
f2_late_swrnrdy();
break;
case task_ether: // ethernet task
f2_late_ebfct();
break;
}
break;
case f2_task_15: // f2 15 task specific
switch (m_task) {
case task_emu: // emulator task
f2_late_idisp();
break;
case task_ksec: // disk sector task
case task_kwd: // disk word task
f2_late_nfer();
break;
case task_ether: // ethernet task
f2_late_ecbfct();
break;
}
break;
case f2_task_16: // f2 16 task specific
switch (m_task) {
case task_emu: // emulator task
f2_late_acsource();
break;
case task_ksec: // disk sector task
case task_kwd: // disk word task
f2_late_strobon();
break;
case task_ether: // ethernet task
f2_late_eisfct();
break;
}
break;
}
// late BS function call now, if no constant was put on the bus
if (do_bs)
((*this).*m_bs[1][m_task][bs()])();
if (do_bs) {
switch (bs()) {
case bs_load_r: // load R register from BUS
bs_late_load_r();
break;
case bs_task_4: // BUS source is task specific
switch (m_task) {
case task_emu: // emulator task
bs_late_load_sreg();
break;
}
break;
}
}
// update T register, if LOADT is set
if (loadt()) {
@ -2400,7 +2793,7 @@ void alto2_cpu_device::execute_run()
}
// update M (MYL) register, if a RAM related task is active
if (m_ram_related[m_task]) {
m_m = m_alu; // load M from ALU, if 'GOODTASK'
m_myl = m_alu; // load M from ALU, if 'GOODTASK'
m_s[m_s_reg_bank[m_task]][0] = m_alu; // also writes to S[bank][0], which can't be read
LOG((this,LOG_CPU,2, " M<- ALU (%#o)\n", m_alu));
}
@ -2422,7 +2815,34 @@ void alto2_cpu_device::execute_run()
m_next2 = m_task_next2[m_task]; // get address modifier after task switch (needed?)
// let the task know it becomes active now and (most probably) reset the wakeup
((*this).*m_active_callback[m_task])();
switch (m_task) {
case task_emu: // emulator task
break;
case task_ksec: // disk sector task
break;
case task_ether: // ethernet task
activate_eth();
break;
case task_mrt: // memory refresh task
activate_mrt();
break;
case task_dwt: // display word task
break;
case task_curt: // cursor task
activate_curt();
break;
case task_dht: // display horizontal task
activate_dht();
break;
case task_dvt: // display vertical task
activate_dvt();
break;
case task_part: // parity task
activate_part();
break;
case task_kwd: // disk word task
break;
}
}
}
@ -2449,7 +2869,7 @@ void alto2_cpu_device::execute_run()
if (m_unload_time < 0)
unload_word();
}
if (m_bitclk_time >= 0) {
/**
* Subtract the microcycle time from the bitclk time accu.
@ -2479,52 +2899,8 @@ void alto2_cpu_device::hard_reset()
for (int task = 0; task < ALTO2_TASKS; task++) {
// every task starts at mpc = task number, in either ROM0 or RAM0
m_task_mpc[task] = (m_ctl2k_u38[task] >> 4) ^ 017;
m_active_callback[task] = &alto2_cpu_device::noop;
if (0 == (m_reset_mode & (1 << task)))
m_task_mpc[task] |= ALTO2_UCODE_RAM_BASE;
set_bs(task, bs_read_r, &alto2_cpu_device::bs_early_read_r, nullptr);
set_bs(task, bs_load_r, &alto2_cpu_device::bs_early_load_r, &alto2_cpu_device::bs_late_load_r);
set_bs(task, bs_no_source, nullptr, nullptr);
set_bs(task, bs_task_3, &alto2_cpu_device::fn_bs_bad_0, &alto2_cpu_device::fn_bs_bad_1); // task specific
set_bs(task, bs_task_4, &alto2_cpu_device::fn_bs_bad_0, &alto2_cpu_device::fn_bs_bad_1); // task specific
set_bs(task, bs_read_md, &alto2_cpu_device::bs_early_read_md, nullptr);
set_bs(task, bs_mouse, &alto2_cpu_device::bs_early_mouse, nullptr);
set_bs(task, bs_disp, &alto2_cpu_device::bs_early_disp, nullptr);
set_f1(task, f1_nop, nullptr, nullptr);
set_f1(task, f1_load_mar, nullptr, &alto2_cpu_device::f1_late_load_mar);
set_f1(task, f1_task, &alto2_cpu_device::f1_early_task, nullptr);
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
set_f1(task, f1_l_lsh_1, nullptr, &alto2_cpu_device::f1_late_l_lsh_1);
set_f1(task, f1_l_rsh_1, nullptr, &alto2_cpu_device::f1_late_l_rsh_1);
set_f1(task, f1_l_lcy_8, nullptr, &alto2_cpu_device::f1_late_l_lcy_8);
set_f1(task, f1_const, nullptr, nullptr);
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
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
set_f1(task, f1_task_12, &alto2_cpu_device::fn_f1_bad_0, &alto2_cpu_device::fn_f1_bad_1); // f1_task_10 to f1_task_17 are task specific
set_f1(task, f1_task_13, &alto2_cpu_device::fn_f1_bad_0, &alto2_cpu_device::fn_f1_bad_1); // f1_task_10 to f1_task_17 are task specific
set_f1(task, f1_task_14, &alto2_cpu_device::fn_f1_bad_0, &alto2_cpu_device::fn_f1_bad_1); // f1_task_10 to f1_task_17 are task specific
set_f1(task, f1_task_15, &alto2_cpu_device::fn_f1_bad_0, &alto2_cpu_device::fn_f1_bad_1); // f1_task_10 to f1_task_17 are task specific
set_f1(task, f1_task_16, &alto2_cpu_device::fn_f1_bad_0, &alto2_cpu_device::fn_f1_bad_1); // f1_task_10 to f1_task_17 are task specific
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
set_f2(task, f2_nop, nullptr, nullptr);
set_f2(task, f2_bus_eq_zero, nullptr, &alto2_cpu_device::f2_late_bus_eq_zero);
set_f2(task, f2_shifter_lt_zero,nullptr, &alto2_cpu_device::f2_late_shifter_lt_zero);
set_f2(task, f2_shifter_eq_zero,nullptr, &alto2_cpu_device::f2_late_shifter_eq_zero);
set_f2(task, f2_bus, nullptr, &alto2_cpu_device::f2_late_bus);
set_f2(task, f2_alucy, nullptr, &alto2_cpu_device::f2_late_alucy);
set_f2(task, f2_load_md, nullptr, &alto2_cpu_device::f2_late_load_md);
set_f2(task, f2_const, nullptr, nullptr);
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
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
set_f2(task, f2_task_12, &alto2_cpu_device::fn_f2_bad_0, &alto2_cpu_device::fn_f2_bad_1); // f2_task_10 to f2_task_17 are task specific
set_f2(task, f2_task_13, &alto2_cpu_device::fn_f2_bad_0, &alto2_cpu_device::fn_f2_bad_1); // f2_task_10 to f2_task_17 are task specific
set_f2(task, f2_task_14, &alto2_cpu_device::fn_f2_bad_0, &alto2_cpu_device::fn_f2_bad_1); // f2_task_10 to f2_task_17 are task specific
set_f2(task, f2_task_15, &alto2_cpu_device::fn_f2_bad_0, &alto2_cpu_device::fn_f2_bad_1); // f2_task_10 to f2_task_17 are task specific
set_f2(task, f2_task_16, &alto2_cpu_device::fn_f2_bad_0, &alto2_cpu_device::fn_f2_bad_1); // f2_task_10 to f2_task_17 are task specific
set_f2(task, f2_task_17, &alto2_cpu_device::fn_f2_bad_0, &alto2_cpu_device::fn_f2_bad_1); // f2_task_10 to f2_task_17 are task specific
}
init_memory();
@ -2546,6 +2922,8 @@ void alto2_cpu_device::hard_reset()
init_kwd();
m_dsp_time = 0; // reset the display state timing
m_unload_time = 0; // reset the word unload timing accu
m_bitclk_time = 0; // reset the bitclk timing accu
m_task = task_emu; // start with task 0 (emulator)
m_task_wakeup |= 1 << task_emu; // set wakeup flag
}

View File

@ -42,14 +42,17 @@ enum {
};
#ifndef ALTO2_DEBUG
#define ALTO2_DEBUG 1 //!< define to 1 to enable logerror() output
//! Define to 1 to enable logerror() output.
#define ALTO2_DEBUG 1
#endif
#ifndef ALTO2_CRAM_CONFIG
#define ALTO2_CRAM_CONFIG 2 //!< use default CROM/CRAM configuration 2
//! Use default CROM/CRAM configuration 2.
#define ALTO2_CRAM_CONFIG 2
#endif
#define USE_PRIO_F9318 0 //!< define to 1 to use the F9318 priority encoder code (broken)
//!< Define to 1 to use the F9318 priority encoder code (broken).
#define USE_PRIO_F9318 0
#define ALTO2_TASKS 16 //!< 16 task slots
#define ALTO2_REGS 32 //!< 32 16-bit words in the R register file
@ -61,7 +64,7 @@ enum {
#define ALTO2_CONST_SIZE 256 //!< number words in the constant ROM
//! inverted bits in the micro instruction 32 bit word
//! Inverted bits in the micro instruction 32 bit word.
#define ALTO2_UCODE_INVERTED ((1 << 10) | (1 << 15) | (1 << 19))
/********************************************************************************
@ -278,8 +281,6 @@ private:
speaker_sound_device* m_speaker;
typedef void (alto2_cpu_device::*a2func)();
//! task numbers
enum {
task_emu, //!< emulator task
@ -575,10 +576,9 @@ private:
UINT16 m_l; //!< L register
UINT16 m_shifter; //!< shifter output
UINT16 m_laluc0; //!< the latched ALU carry output
UINT16 m_m; //!< M register of RAM related tasks (MYL latch in the schematics)
UINT16 m_myl; //!< M register of RAM related tasks (MYL latch in the schematics)
UINT16 m_cram_addr; //!< constant RAM address
UINT16 m_task_wakeup; //!< task wakeup: bit 1<<n set if task n requesting service
a2func m_active_callback[ALTO2_TASKS]; //!< task activation callbacks
UINT16 m_reset_mode; //!< reset mode register: bit 1<<n set if task n starts in ROM
bool m_rdram_flag; //!< set by rdram, action happens on next cycle
@ -861,27 +861,6 @@ private:
//! no operating function to put in the m_bs, m_f1 and m_f2 slots
void noop() {}
//! per task bus source function pointers, early (0) and late (1)
a2func m_bs[2][ALTO2_TASKS][ALTO2_BUSSRC];
void set_bs(UINT8 task, UINT8 fn, a2func f0, a2func f1) {
m_bs[0][task][fn] = f0 ? f0 : &alto2_cpu_device::noop;
m_bs[1][task][fn] = f1 ? f1 : &alto2_cpu_device::noop;
}
//! per task f1 function pointers, early (0) and late (1)
a2func m_f1[2][ALTO2_TASKS][ALTO2_F1MAX];
void set_f1(UINT8 task, UINT8 fn, a2func f0, a2func f1) {
m_f1[0][task][fn] = f0 ? f0 : &alto2_cpu_device::noop;
m_f1[1][task][fn] = f1 ? f1 : &alto2_cpu_device::noop;
}
//! per task f2 function pointers, early (0) and late (1)
a2func m_f2[2][ALTO2_TASKS][ALTO2_F2MAX];
void set_f2(UINT8 task, UINT8 fn, a2func f0, a2func f1) {
m_f2[0][task][fn] = f0 ? f0 : &alto2_cpu_device::noop;
m_f2[1][task][fn] = f1 ? f1 : &alto2_cpu_device::noop;
}
bool m_ram_related[ALTO2_TASKS]; //!< set when task is RAM related
UINT64 m_cycle; //!< number of cycles executed in the current slice
@ -892,14 +871,14 @@ private:
void hard_reset(); //!< reset the various registers
void soft_reset(); //!< soft reset
void fn_bs_bad_0(); //! bs dummy early function
void fn_bs_bad_1(); //! bs dummy late function
void bs_early_bad(); //! bs dummy early function
void bs_late_bad(); //! bs dummy late function
void fn_f1_bad_0(); //! f1 dummy early function
void fn_f1_bad_1(); //! f1 dummy late function
void f1_early_bad(); //! f1 dummy early function
void f1_late_bad(); //! f1 dummy late function
void fn_f2_bad_0(); //! f2 dummy early function
void fn_f2_bad_1(); //! f2 dummy late function
void f2_early_bad(); //! f2 dummy early function
void f2_late_bad(); //! f2 dummy late function
DECLARE_READ16_MEMBER( noop_r ); //!< read open bus (0177777)
DECLARE_WRITE16_MEMBER( noop_w ); //!< write open bus
@ -913,18 +892,21 @@ private:
void bs_early_read_md(); //!< bus source: drive BUS from read memory data
void bs_early_mouse(); //!< bus source: drive bus by mouse
void bs_early_disp(); //!< bus source: drive bus by displacement (which?)
void f1_early_block(); //!< F1 func: block active task
void f1_late_load_mar(); //!< F1 func: load memory address register
void f1_early_task(); //!< F1 func: task switch
void f1_late_l_lsh_1(); //!< F1 func: SHIFTER = left shift L once
void f1_late_l_rsh_1(); //!< F1 func: SHIFTER = right shift L once
void f1_late_l_lcy_8(); //!< F1 func: SHIFTER = byte swap L
void f2_late_bus_eq_zero(); //!< F2 func: branch on bus equals zero
void f2_late_shifter_lt_zero(); //!< F2 func: branch on shifter less than zero
void f2_late_shifter_eq_zero(); //!< F2 func: branch on shifter equals zero
void f2_late_bus(); //!< F2 func: branch on bus bits BUS[6-15]
void f2_late_alucy(); //!< F2 func: branch on latched ALU carry
void f2_late_load_md(); //!< F2 func: load memory data
UINT32 alu_74181(UINT32 a, UINT32 b, UINT8 smc);
void rdram(); //!< read the microcode ROM/RAM halfword