summaryrefslogtreecommitdiffstatshomepage
path: root/src/mess/machine/macadb.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/mess/machine/macadb.c')
-rw-r--r--src/mess/machine/macadb.c1430
1 files changed, 0 insertions, 1430 deletions
diff --git a/src/mess/machine/macadb.c b/src/mess/machine/macadb.c
deleted file mode 100644
index 76a8a010b57..00000000000
--- a/src/mess/machine/macadb.c
+++ /dev/null
@@ -1,1430 +0,0 @@
-// license:BSD-3-Clause
-// copyright-holders:R. Belmont
-/***************************************************************************
-
- macadb.c - handles various aspects of ADB on the Mac.
-
-***************************************************************************/
-
-#include "emu.h"
-#include "includes/mac.h"
-
-#define LOG_ADB 0
-#define LOG_ADB_MCU_CMD 0
-#define LOG_ADB_TALK_LISTEN 0
-
-// ADB states
-#define ADB_STATE_NEW_COMMAND (0)
-#define ADB_STATE_XFER_EVEN (1)
-#define ADB_STATE_XFER_ODD (2)
-#define ADB_STATE_IDLE (3)
-#define ADB_STATE_NOTINIT (4)
-
-// ADB commands
-#define ADB_CMD_RESET (0)
-#define ADB_CMD_FLUSH (1)
-
-// ADB line states
-enum
-{
- // receive states
- LST_IDLE = 0,
- LST_ATTENTION,
- LST_BIT0,
- LST_BIT1,
- LST_BIT2,
- LST_BIT3,
- LST_BIT4,
- LST_BIT5,
- LST_BIT6,
- LST_BIT7,
- LST_TSTOP,
- LST_WAITT1T,
- LST_RCVSTARTBIT,
- LST_SRQNODATA,
-
- // send states
- LST_TSTOPSTART,
- LST_TSTOPSTARTa,
- LST_STARTBIT,
- LST_SENDBIT0,
- LST_SENDBIT0a,
- LST_SENDBIT1,
- LST_SENDBIT1a,
- LST_SENDBIT2,
- LST_SENDBIT2a,
- LST_SENDBIT3,
- LST_SENDBIT3a,
- LST_SENDBIT4,
- LST_SENDBIT4a,
- LST_SENDBIT5,
- LST_SENDBIT5a,
- LST_SENDBIT6,
- LST_SENDBIT6a,
- LST_SENDBIT7,
- LST_SENDBIT7a,
- LST_SENDSTOP,
- LST_SENDSTOPa
-};
-
-/* *************************************************************************
- * High-level ADB primitives used by all lower-level implementations
- * *************************************************************************/
-
-#if LOG_ADB
-static const char *const adb_statenames[4] = { "NEW", "EVEN", "ODD", "IDLE" };
-#endif
-
-int mac_state::adb_pollkbd(int update)
-{
- int i, j, keybuf, report, codes[2], result;
- ioport_port *ports[6] = { m_key0, m_key1, m_key2, m_key3, m_key4, m_key5 };
-
- codes[0] = codes[1] = 0xff; // key up
- report = result = 0;
-
- for (i = 0; i < 6; i++)
- {
- keybuf = ports[i]->read();
-
- // any changes in this row?
- if ((keybuf != m_key_matrix[i]) && (report < 2))
- {
- // check each column bit
- for (j=0; j<16; j++)
- {
- if (((keybuf ^ m_key_matrix[i]) >> j) & 1)
- {
- // update m_key_matrix
- if (update)
- {
- m_key_matrix[i] = (m_key_matrix[i] & ~ (1 << j)) | (keybuf & (1 << j));
- }
-
- codes[report] = (i<<4)|j;
-
- // key up?
- if (!(keybuf & (1 << j)))
- {
- codes[report] |= 0x80;
- }
-
- // update modifier state
- if (update)
- {
- if (((i<<4)|j) == 0x39)
- {
- if (codes[report] & 0x80)
- {
- m_adb_modifiers &= ~0x20;
- }
- else
- {
- m_adb_modifiers |= 0x20;
- }
- }
- if (((i<<4)|j) == 0x36)
- {
- if (codes[report] & 0x80)
- {
- m_adb_modifiers &= ~0x8;
- }
- else
- {
- m_adb_modifiers |= 0x08;
- }
- }
- if (((i<<4)|j) == 0x38)
- {
- if (codes[report] & 0x80)
- {
- m_adb_modifiers &= ~0x4;
- }
- else
- {
- m_adb_modifiers |= 0x04;
- }
- }
- if (((i<<4)|j) == 0x3a)
- {
- if (codes[report] & 0x80)
- {
- m_adb_modifiers &= ~0x2;
- }
- else
- {
- m_adb_modifiers |= 0x02;
- }
- }
- if (((i<<4)|j) == 0x37)
- {
- if (codes[report] & 0x80)
- {
- m_adb_modifiers &= ~0x1;
- }
- else
- {
- m_adb_modifiers |= 0x01;
- }
- }
- }
-
- // we run out of keys we can track?
- report++;
- if (report == 2)
- {
- break;
- }
- }
- }
-
- // we run out of keys we can track?
- if (report == 2)
- {
- break;
- }
- }
- }
-
-// printf("ADB keyboard: update %d keys %02x %02x\n", update, codes[0], codes[1]);
-
- // figure out if there was a change
- if ((m_adb_currentkeys[0] != codes[0]) || (m_adb_currentkeys[1] != codes[1]))
- {
- result = 1;
-
- // if we want to update the current read, do so
- if (update)
- {
- if(m_adb_currentkeys[0] != codes[0]) {
- m_adb_keybuf[m_adb_keybuf_end] = codes[0];
- m_adb_keybuf_end = (m_adb_keybuf_end+1) % kADBKeyBufSize;
- }
- if(m_adb_currentkeys[1] != codes[1]) {
- m_adb_keybuf[m_adb_keybuf_end] = codes[1];
- m_adb_keybuf_end = (m_adb_keybuf_end+1) % kADBKeyBufSize;
- }
- m_adb_currentkeys[0] = codes[0];
- m_adb_currentkeys[1] = codes[1];
- }
- }
-
- return result;
-}
-
-int mac_state::adb_pollmouse()
-{
- int NewX, NewY, NewButton;
-
- if (!m_adb_mouse_initialized)
- {
- return 0;
- }
-
- NewButton = m_mouse0->read() & 0x01;
- NewX = m_mouse2->read();
- NewY = m_mouse1->read();
-
- if ((NewX != m_adb_lastmousex) || (NewY != m_adb_lastmousey) || (NewButton != m_adb_lastbutton))
- {
- return 1;
- }
-
- return 0;
-}
-
-void mac_state::adb_accummouse( UINT8 *MouseX, UINT8 *MouseY )
-{
- int MouseCountX = 0, MouseCountY = 0;
- int NewX, NewY;
-
- NewX = ioport("MOUSE2")->read();
- NewY = ioport("MOUSE1")->read();
-
- /* see if it moved in the x coord */
- if (NewX != m_adb_lastmousex)
- {
- int diff = NewX - m_adb_lastmousex;
-
- /* check for wrap */
- if (diff > 0x80)
- diff = 0x100-diff;
- if (diff < -0x80)
- diff = -0x100-diff;
-
- MouseCountX += diff;
- m_adb_lastmousex = NewX;
- }
-
- /* see if it moved in the y coord */
- if (NewY != m_adb_lastmousey)
- {
- int diff = NewY - m_adb_lastmousey;
-
- /* check for wrap */
- if (diff > 0x80)
- diff = 0x100-diff;
- if (diff < -0x80)
- diff = -0x100-diff;
-
- MouseCountY += diff;
- m_adb_lastmousey = NewY;
- }
-
- m_adb_lastbutton = m_mouse0->read() & 0x01;
-
- *MouseX = (UINT8)MouseCountX;
- *MouseY = (UINT8)MouseCountY;
-}
-
-void mac_state::adb_talk()
-{
- int addr, reg;
-
- addr = (m_adb_command>>4);
- reg = (m_adb_command & 3);
-
-// printf("Mac sent %x (cmd %d addr %d reg %d mr %d kr %d)\n", mac->m_adb_command, (mac->m_adb_command>>2)&3, addr, reg, m_adb_mouseaddr, m_adb_keybaddr);
-
- if (m_adb_waiting_cmd)
- {
- switch ((m_adb_command>>2)&3)
- {
- case 0:
- case 1:
- switch (reg)
- {
- case ADB_CMD_RESET:
- #if LOG_ADB || LOG_ADB_TALK_LISTEN
- printf("ADB RESET: reg %x address %x\n", reg, addr);
- #endif
- m_adb_direction = 0;
- m_adb_send = 0;
- break;
-
- case ADB_CMD_FLUSH:
- #if LOG_ADB || LOG_ADB_TALK_LISTEN
- printf("ADB FLUSH: reg %x address %x\n", reg, addr);
- #endif
-
- m_adb_direction = 0;
- m_adb_send = 0;
- break;
-
- default: // reserved/unused
- break;
- }
- break;
-
- case 2: // listen
- m_adb_datasize = 0;
- if ((addr == m_adb_keybaddr) || (addr == m_adb_mouseaddr))
- {
- #if LOG_ADB || LOG_ADB_TALK_LISTEN
- printf("ADB LISTEN: reg %x address %x\n", reg, addr);
- #endif
- m_adb_direction = 1; // input from Mac
- m_adb_command = 0;
- m_adb_listenreg = reg;
- m_adb_listenaddr = addr;
- if ((ADB_IS_EGRET) || (ADB_IS_CUDA))
- {
- m_adb_stream_ptr = 0;
- memset(m_adb_buffer, 0, sizeof(m_adb_buffer));
- }
- }
- else
- {
- #if LOG_ADB || LOG_ADB_TALK_LISTEN
- printf("ADB LISTEN to unknown device, timing out\n");
- #endif
- m_adb_direction = 0;
- }
- break;
-
- case 3: // talk
- #if LOG_ADB || LOG_ADB_TALK_LISTEN
- printf("ADB TALK: reg %x address %x (K %x M %x)\n", reg, addr, m_adb_keybaddr, m_adb_mouseaddr);
- #endif
-
- // keep track of what device the Mac last TALKed to
- m_adb_last_talk = addr;
-
- m_adb_direction = 0; // output to Mac
- if (addr == m_adb_mouseaddr)
- {
- UINT8 mouseX, mouseY;
-
- #if LOG_ADB || LOG_ADB_TALK_LISTEN
- printf("Talking to mouse, register %x\n", reg);
- #endif
-
- switch (reg)
- {
- // read mouse
- case 0:
- if (m_adb_srq_switch)
- {
- m_adb_srq_switch = 0;
- mouseX = mouseY = 0;
- }
- else
- {
- this->adb_accummouse(&mouseX, &mouseY);
- }
- m_adb_buffer[0] = (m_adb_lastbutton & 0x01) ? 0x00 : 0x80;
- m_adb_buffer[0] |= mouseX & 0x7f;
- m_adb_buffer[1] = mouseY & 0x7f;
- m_adb_datasize = 2;
- break;
-
- // get ID/handler
- case 3:
- m_adb_buffer[0] = 0x60 | (m_adb_mouseaddr&0xf); // SRQ enable, no exceptional event
- m_adb_buffer[1] = 0x01; // handler 1
- m_adb_datasize = 2;
-
- m_adb_mouse_initialized = 1;
- break;
-
- default:
- break;
- }
-
- if (adb_pollkbd(0))
- {
- m_adb_srqflag = true;
- }
- }
- else if (addr == m_adb_keybaddr)
- {
- int kbd_has_data = 1;
- #if LOG_ADB || LOG_ADB_TALK_LISTEN
- printf("Talking to keyboard, register %x\n", reg);
- #endif
-
- switch (reg)
- {
- // read keyboard
- case 0:
- if (m_adb_srq_switch)
- {
- m_adb_srq_switch = 0;
- }
- else
- {
- kbd_has_data = this->adb_pollkbd(1);
- }
-
-/* if (m_adb_currentkeys[0] != 0xff)
- {
- printf("Keys[0] = %02x\n", m_adb_currentkeys[0]);
- }
- if (m_adb_currentkeys[1] != 0xff)
- {
- printf("Keys[1] = %02x\n", m_adb_currentkeys[1]);
- }*/
-
- if(kbd_has_data)
- {
- if(m_adb_keybuf_start == m_adb_keybuf_end)
- {
- // printf("%s: buffer empty\n", __func__);
- m_adb_buffer[0] = 0xff;
- m_adb_buffer[1] = 0xff;
- }
- else
- {
- m_adb_buffer[1] = m_adb_keybuf[m_adb_keybuf_start];
- m_adb_keybuf_start = (m_adb_keybuf_start+1) % kADBKeyBufSize;
- if(m_adb_keybuf_start != m_adb_keybuf_end)
- {
- m_adb_buffer[0] = m_adb_keybuf[m_adb_keybuf_start];
- m_adb_keybuf_start = (m_adb_keybuf_start+1) % kADBKeyBufSize;
- }
- else
- {
- m_adb_buffer[0] = 0xff;
- }
- }
- m_adb_datasize = 2;
- }
- break;
-
- // read modifier keys
- case 2:
- {
- this->adb_pollkbd(1);
- m_adb_buffer[0] = m_adb_modifiers;
- m_adb_buffer[1] = 0xff;
- m_adb_datasize = 2;
- }
- break;
-
- // get ID/handler
- case 3:
- m_adb_buffer[0] = 0x60 | (m_adb_keybaddr&0xf); // SRQ enable, no exceptional event
- m_adb_buffer[1] = 0x01; // handler 1
- m_adb_datasize = 2;
-
- m_adb_keybinitialized = 1;
- break;
-
- default:
- break;
- }
-
- if (adb_pollmouse())
- {
- m_adb_srqflag = true;
- }
- }
- else
- {
- #if LOG_ADB || LOG_ADB_TALK_LISTEN
- printf("ADB: talking to unconnected device %d (K %d M %d)\n", addr, m_adb_keybaddr, m_adb_mouseaddr);
- #endif
- m_adb_buffer[0] = m_adb_buffer[1] = 0;
- m_adb_datasize = 0;
-
- if ((adb_pollkbd(0)) || (adb_pollmouse()))
- {
- m_adb_srqflag = true;
- }
- }
- break;
- }
-
- m_adb_waiting_cmd = 0;
- }
- else
- {
- #if LOG_ADB || LOG_ADB_TALK_LISTEN
- printf("Got LISTEN data %02x %02x for device %x reg %x\n", m_adb_command, m_adb_buffer[1], m_adb_listenaddr, m_adb_listenreg);
- #endif
-
- m_adb_direction = 0;
-
- if (m_adb_listenaddr == m_adb_mouseaddr)
- {
- if ((m_adb_listenreg == 3) && (m_adb_command > 0) && (m_adb_command < 16))
- {
- #if LOG_ADB || LOG_ADB_TALK_LISTEN
- printf("MOUSE: moving to address %x\n", m_adb_command);
- #endif
- m_adb_mouseaddr = m_adb_command&0x0f;
- }
- }
- else if (m_adb_listenaddr == m_adb_keybaddr)
- {
- if ((m_adb_listenreg == 3) && (m_adb_command > 0) && (m_adb_command < 16))
- {
- #if LOG_ADB || LOG_ADB_TALK_LISTEN
- printf("KEYBOARD: moving to address %x\n", m_adb_command);
- #endif
- m_adb_keybaddr = m_adb_command&0x0f;
- }
- }
- }
-}
-
-TIMER_CALLBACK(mac_adb_tick)
-{
- mac_state *mac = machine.driver_data<mac_state>();
-
- if ((ADB_IS_EGRET_NONCLASS) || (ADB_IS_CUDA_NONCLASS))
- {
- switch (mac->m_adb_linestate)
- {
- case LST_SRQNODATA:
- mac->set_adb_line(ASSERT_LINE);
- mac->m_adb_linestate = LST_IDLE;
- break;
-
- case LST_TSTOPSTART:
- mac->set_adb_line(ASSERT_LINE);
- mac->m_adb_timer->adjust(attotime::from_ticks(57, 1000000));
- mac->m_adb_linestate++;
- break;
-
- case LST_TSTOPSTARTa:
- mac->set_adb_line(CLEAR_LINE);
- mac->m_adb_timer->adjust(attotime::from_ticks(57, 1000000));
- mac->m_adb_linestate++;
- break;
-
- case LST_STARTBIT:
- mac->set_adb_line(ASSERT_LINE);
- mac->m_adb_timer->adjust(attotime::from_ticks(105, 1000000));
- mac->m_adb_linestate++;
- break;
-
- case LST_SENDBIT0:
- case LST_SENDBIT1:
- case LST_SENDBIT2:
- case LST_SENDBIT3:
- case LST_SENDBIT4:
- case LST_SENDBIT5:
- case LST_SENDBIT6:
- case LST_SENDBIT7:
- mac->set_adb_line(CLEAR_LINE);
- if (mac->m_adb_buffer[mac->m_adb_stream_ptr] & 0x80)
- {
-// printf("1 ");
- mac->m_adb_timer->adjust(attotime::from_ticks(57, 1000000));
- }
- else
- {
-// printf("0 ");
- mac->m_adb_timer->adjust(attotime::from_ticks(105, 1000000));
- }
- mac->m_adb_linestate++;
- break;
-
- case LST_SENDBIT0a:
- case LST_SENDBIT1a:
- case LST_SENDBIT2a:
- case LST_SENDBIT3a:
- case LST_SENDBIT4a:
- case LST_SENDBIT5a:
- case LST_SENDBIT6a:
- mac->set_adb_line(ASSERT_LINE);
- if (mac->m_adb_buffer[mac->m_adb_stream_ptr] & 0x80)
- {
- mac->m_adb_timer->adjust(attotime::from_ticks(105, 1000000));
- }
- else
- {
- mac->m_adb_timer->adjust(attotime::from_ticks(57, 1000000));
- }
- mac->m_adb_buffer[mac->m_adb_stream_ptr] <<= 1;
- mac->m_adb_linestate++;
- break;
-
- case LST_SENDBIT7a:
- mac->set_adb_line(ASSERT_LINE);
- if (mac->m_adb_buffer[mac->m_adb_stream_ptr] & 0x80)
- {
-// printf(" ");
- mac->m_adb_timer->adjust(attotime::from_ticks(105, 1000000));
- }
- else
- {
-// printf(" ");
- mac->m_adb_timer->adjust(attotime::from_ticks(57, 1000000));
- }
-
- mac->m_adb_stream_ptr++;
- if (mac->m_adb_stream_ptr == mac->m_adb_datasize)
- {
- mac->m_adb_linestate++;
- }
- else
- {
- mac->m_adb_linestate = LST_SENDBIT0;
- }
- break;
-
- case LST_SENDSTOP:
- mac->set_adb_line(CLEAR_LINE);
- mac->m_adb_timer->adjust(attotime::from_ticks((57*2), 1000000));
- mac->m_adb_linestate++;
- break;
-
- case LST_SENDSTOPa:
- mac->set_adb_line(ASSERT_LINE);
- mac->m_adb_timer->adjust(attotime::never);
- mac->m_adb_linestate = LST_IDLE;
- break;
- }
- }
- else
- {
- // do one clock transition on CB1 to advance the VIA shifter
- mac->m_adb_extclock ^= 1;
- mac->m_via1->write_cb1(mac->m_adb_extclock);
-
- if (mac->m_adb_direction)
- {
- mac->m_adb_command <<= 1;
- }
- else
- {
- mac->m_via1->write_cb2((mac->m_adb_send & 0x80)>>7);
- mac->m_adb_send <<= 1;
- }
-
- mac->m_adb_extclock ^= 1;
- mac->m_via1->write_cb1(mac->m_adb_extclock);
-
- mac->m_adb_timer_ticks--;
- if (!mac->m_adb_timer_ticks)
- {
- mac->m_adb_timer->adjust(attotime::never);
-
- if ((mac->m_adb_direction) && (ADB_IS_BITBANG))
- {
- mac->adb_talk();
- if((mac->m_adb_last_talk == 2) && mac->m_adb_datasize) {
- mac->m_adb_timer_ticks = 8;
- mac->m_adb_timer->adjust(attotime(0, ATTOSECONDS_IN_USEC(100)));
- }
- }
- }
- else
- {
- mac->m_adb_timer->adjust(attotime(0, ATTOSECONDS_IN_USEC(200)));
- }
- }
-}
-
-void mac_state::mac_adb_newaction(int state)
-{
- if (state != m_adb_state)
- {
- #if LOG_ADB
- printf("New ADB state: %s\n", adb_statenames[state]);
- #endif
-
- m_adb_state = state;
- m_adb_timer_ticks = 8;
-
- switch (state)
- {
- case ADB_STATE_NEW_COMMAND:
- m_adb_command = m_adb_send = 0;
- m_adb_direction = 1; // Mac is shifting us a command
- m_adb_waiting_cmd = 1; // we're going to get a command
- m_adb_irq_pending = 0;
- m_adb_timer->adjust(attotime(0, ATTOSECONDS_IN_USEC(100)));
- break;
-
- case ADB_STATE_XFER_EVEN:
- case ADB_STATE_XFER_ODD:
- if (m_adb_datasize > 0)
- {
- int i;
-
- // is something trying to send to the Mac?
- if (m_adb_direction == 0)
- {
- // set up the byte
- m_adb_send = m_adb_buffer[0];
- m_adb_datasize--;
-
- // move down the rest of the buffer, if any
- for (i = 0; i < m_adb_datasize; i++)
- {
- m_adb_buffer[i] = m_adb_buffer[i+1];
- }
- }
-
- }
- else
- {
- m_adb_send = 0;
- m_adb_irq_pending = 1;
- }
-
- m_adb_timer->adjust(attotime(0, ATTOSECONDS_IN_USEC(100)));
- break;
-
- case ADB_STATE_IDLE:
- m_adb_irq_pending = 0;
- break;
- }
- }
-}
-
-TIMER_CALLBACK(mac_pmu_tick)
-{
- mac_state *mac = machine.driver_data<mac_state>();
-
- // state 10 means this is in response to an ADB command
- if (mac->m_pm_state == 10)
- {
- #if LOG_ADB
- printf("PM: was state 10, chunk-chunking CB1\n");
- #endif
- mac->m_pm_state = 0;
-
- // tick CB1, which should cause a PMU interrupt on PMU machines
- mac->m_adb_extclock ^= 1;
- mac->m_via1->write_cb1(mac->m_adb_extclock);
- mac->m_adb_extclock ^= 1;
- mac->m_via1->write_cb1(mac->m_adb_extclock);
- }
- else
- {
- #if LOG_ADB
- printf("PM: timer tick, lowering ACK\n");
- #endif
- mac->m_pm_ack &= ~2; // lower ACK to handshake next step
- }
-}
-
-void mac_state::pmu_one_byte_reply(UINT8 result)
-{
- m_pm_out[0] = m_pm_out[1] = 1; // length
- m_pm_out[2] = result;
- m_pm_slen = 3;
- m_pmu_send_timer->adjust(attotime(0, ATTOSECONDS_IN_USEC(200)));
-}
-
-void mac_state::pmu_three_byte_reply(UINT8 result1, UINT8 result2, UINT8 result3)
-{
- m_pm_out[0] = m_pm_out[1] = 3; // length
- m_pm_out[2] = result1;
- m_pm_out[3] = result2;
- m_pm_out[4] = result3;
- m_pm_slen = 5;
- m_pmu_send_timer->adjust(attotime(0, ATTOSECONDS_IN_USEC(200)));
-}
-
-void mac_state::pmu_exec()
-{
- m_pm_sptr = 0; // clear send pointer
- m_pm_slen = 0; // and send length
- m_pm_dptr = 0; // and receive pointer
-
-// printf("PMU: Command %02x\n", mac->m_pm_cmd[0]);
- switch (m_pm_cmd[0])
- {
- case 0x10: // subsystem power and clock ctrl
- break;
-
- case 0x20: // send ADB command (PMU must issue an IRQ on completion)
- #if 0
- printf("PMU: Send ADB %02x %02x cmd %02x flag %02x data %02x %02x\n",
- m_pm_cmd[0], // 0x20
- m_pm_cmd[1], // ???
- m_pm_cmd[2], // adb flags (2 for autopoll active, 3 to reset bus?)
- m_pm_cmd[3], // length of ADB data
- m_pm_cmd[4], // adb data
- m_pm_cmd[5]);
- #endif
-
- #if 0
- m_pm_state = 10;
- m_pmu_send_timer->adjust(attotime(0, ATTOSECONDS_IN_USEC(200)));
- if (ADB_IS_PM_VIA1_CLASS)
- {
- m_pmu_int_status = 0x1;
- }
- else if (ADB_IS_PM_VIA2_CLASS)
- {
- m_pmu_int_status = 0x10;
- }
- else
- {
- fatalerror("mac: unknown ADB PMU type\n");
- }
- m_pmu_last_adb_command = m_pm_cmd[2];
- m_adb_command = m_pm_cmd[2];
- m_adb_waiting_cmd = 1;
- adb_talk();
-
- if ((m_pm_cmd[2] & 0xf) == 0xb) // LISTEN register 3 (remap)
- {
- m_adb_waiting_cmd = 0;
- m_adb_command = mac->m_pm_cmd[5];
- adb_talk();
- }
- #else
- if (((m_pm_cmd[2] == 0xfc) || (m_pm_cmd[2] == 0x2c)) && (m_pm_cmd[3] == 4))
- {
-// printf("PMU: request to poll ADB, returning nothing\n");
- m_pm_slen = 0;
- m_pmu_int_status = 0;
- }
- else
- {
- m_pm_state = 10;
- m_pmu_send_timer->adjust(attotime(0, ATTOSECONDS_IN_USEC(200)));
- if (ADB_IS_PM_VIA1_CLASS)
- {
- m_pmu_int_status = 0x1;
- }
- else if (ADB_IS_PM_VIA2_CLASS)
- {
- m_pmu_int_status = 0x10;
- }
- else
- {
- fatalerror("mac: unknown ADB PMU type\n");
- }
- m_pmu_last_adb_command = m_pm_cmd[2];
- }
-
- m_adb_command = m_pm_cmd[2];
- m_adb_waiting_cmd = 1;
- adb_talk();
- #endif
- break;
-
- case 0x21: // turn ADB auto-poll off (does this need a reply?)
- break;
-
- case 0x28: // read ADB
- if (m_adb_datasize > 0)
- {
- m_adb_datasize = 1; // hack
-
- m_pm_out[0] = m_pm_out[1] = 3 + m_adb_datasize;
- m_pm_out[2] = 0;
-// m_pm_out[3] = m_pmu_last_adb_command;
- m_pm_out[3] = 0;
- m_pm_out[4] = m_adb_datasize;
- for (int i = 0; i < m_adb_datasize; i++)
- {
- m_pm_out[5+i] = 0; //mac->m_adb_buffer[i];
- }
- m_pm_slen = 5 + m_adb_datasize;
- }
- else
- {
- m_pm_out[0] = m_pm_out[1] = 4;
- m_pm_out[2] = 0;
- m_pm_out[3] = 0;
-// m_pm_out[3] = m_pmu_last_adb_command;
- m_pm_out[4] = 1; // length of following data
- m_pm_out[5] = 0;
- m_pm_slen = 6;
- }
-/* printf("ADB packet: ");
- for (int i = 0; i < m_pm_slen; i++)
- {
- printf("%02x ", m_pm_out[i]);
- }
- printf("\n");*/
- m_pmu_send_timer->adjust(attotime(0, ATTOSECONDS_IN_USEC(1000)));
- break;
-
- case 0x31: // write first 20 bytes of PRAM
- {
- for (int i = 0; i < 20; i++)
- {
- m_adb_pram[i] = m_pm_cmd[1+i];
- }
- }
- break;
-
- case 0x32: // write extended PRAM byte(s). cmd[2] = address, cmd[3] = length, cmd[4...] = data
- if ((m_pm_cmd[2] + m_pm_cmd[3]) < 0x100)
- {
- int i;
-
- for (i = 0; i < m_pm_cmd[3]; i++)
- {
- m_adb_pram[m_pm_cmd[2] + i] = m_pm_cmd[4+i];
- }
- }
- break;
-
- case 0x38: // read time
- {
- m_pm_out[0] = m_pm_out[1] = 4;
- m_pm_out[2] = 0x63; // famous Mac RTC value of 8/27/56 8:35:00 PM
- m_pm_out[3] = 0x0b;
- m_pm_out[4] = 0xd1;
- m_pm_out[5] = 0x78;
- m_pm_slen = 6;
- m_pmu_send_timer->adjust(attotime(0, ATTOSECONDS_IN_USEC(200)));
- }
- break;
-
- case 0x39: // read first 20 bytes of PRAM
- {
- int i;
-
- m_pm_out[0] = m_pm_out[1] = 20;
- for (i = 0; i < 20; i++)
- {
- m_pm_out[2 + i] = m_adb_pram[i];
- }
- m_pm_slen = 22;
- m_pmu_send_timer->adjust(attotime(0, ATTOSECONDS_IN_USEC(200)));
- }
- break;
-
- case 0x3a: // read extended PRAM byte(s). cmd[2] = address, cmd[3] = length
- if ((m_pm_cmd[2] + m_pm_cmd[3]) < 0x100)
- {
- int i;
-
- m_pm_out[0] = m_pm_out[1] = m_pm_cmd[3];
- for (i = 0; i < m_pm_cmd[3]; i++)
- {
- m_pm_out[2 + i] = m_adb_pram[m_pm_cmd[2] + i];
- }
- m_pm_slen = m_pm_out[0] + 2;
- m_pmu_send_timer->adjust(attotime(0, ATTOSECONDS_IN_USEC(200)));
- }
- break;
-
- case 0x40: // set screen contrast
- break;
-
- case 0x41:
- break;
-
- case 0x58: // read internal modem status
- pmu_one_byte_reply(0);
- break;
-
- case 0x60: // set low power warning and cutoff battery levels
- break;
-
- case 0x68: // read battery/charger level
- pmu_three_byte_reply(255, 255, 255);
- break;
-
- case 0x69: // read battery/charger instantaneous level and status
- pmu_three_byte_reply(255, 255, 255);
- break;
-
- case 0x6b: // read extended battery/charger level and status (wants an 8 byte reply)
- m_pm_out[0] = m_pm_out[1] = 8; // length
- m_pm_out[2] = 255;
- m_pm_out[3] = 255;
- m_pm_out[4] = 255;
- m_pm_out[5] = 255;
- m_pm_out[6] = 255;
- m_pm_out[7] = 255;
- m_pm_out[8] = 255;
- m_pm_out[9] = 255;
- m_pm_slen = 10;
- m_pmu_send_timer->adjust(attotime(0, ATTOSECONDS_IN_USEC(200)));
- break;
-
- case 0x6c: // read battery ID
- pmu_one_byte_reply(1);
- break;
-
- case 0x78: // read interrupt flag
- if (ADB_IS_PM_VIA2_CLASS) // PB 140/170 use a "leaner" PMU protocol where you get the data for a PMU interrupt here
- {
- #if 0
- if ((m_pmu_int_status&0xf0) == 0x10)
- {
- if (m_adb_datasize > 0)
- {
- m_adb_datasize = 1; // hack
- m_pm_out[0] = m_pm_out[1] = 2 + m_adb_datasize;
- m_pm_out[2] = m_pmu_int_status; // ADB status in low nibble
- m_pm_out[3] = m_pmu_last_adb_command; // ADB command that was sent
- for (int i = 0; i < m_adb_datasize; i++)
- {
- m_pm_out[4+i] = 0; //m_adb_buffer[i];
- }
- m_pm_slen = 4 + m_adb_datasize;
- m_pmu_send_timer->adjust(attotime(0, ATTOSECONDS_IN_USEC(1500)));
-
-/* printf("ADB packet: ");
- for (int i = 0; i < m_pm_slen; i++)
- {
- printf("%02x ", m_pm_out[i]);
- }
- printf("\n");*/
- }
- else
- {
- m_pm_out[0] = m_pm_out[1] = 2;
- m_pm_out[2] = m_pmu_int_status; // ADB status in low nibble
- m_pm_out[3] = m_pmu_last_adb_command; // ADB command that was sent OR 0x80 for extra error-ness
- m_pm_out[4] = 0; // return data
- m_pm_slen = 4;
- m_pmu_send_timer->adjust(attotime(0, ATTOSECONDS_IN_USEC(1500)));
- }
- }
- else
- {
- pmu_one_byte_reply(mac, m_pmu_int_status);
- }
- #else
- if ((m_pmu_int_status&0xf0) == 0x10)
- {
- m_pm_out[0] = m_pm_out[1] = 2;
- m_pm_out[2] = m_pmu_int_status; // ADB status in low nibble
- m_pm_out[3] = m_pmu_last_adb_command; // ADB command that was sent OR 0x80 for extra error-ness
- m_pm_out[4] = 0; // return data
- m_pm_slen = 4;
- m_pmu_send_timer->adjust(attotime(0, ATTOSECONDS_IN_USEC(1500)));
- }
- else
- {
- pmu_one_byte_reply(m_pmu_int_status);
- }
- #endif
- }
- else
- {
- pmu_one_byte_reply(m_pmu_int_status);
- }
-
- m_pmu_int_status = 0;
- break;
-
- case 0x90: // sound power control
- break;
-
- case 0x98: // read sound power state
- pmu_one_byte_reply(1);
- break;
-
- case 0xd8: // read A/D converter (not sure what this does)
- pmu_one_byte_reply(0);
- break;
-
- case 0xe0: // write PMU internal RAM
- break;
-
- case 0xe8: // read PMU internal RAM (just return zeroes)
- {
- int i;
-
- m_pm_out[0] = m_pm_out[1] = m_pm_cmd[4];
-// printf("PMU read at %x\n", m_pm_cmd[2] | (m_pm_cmd[3]<<8));
-
- // note: read at 0xEE00 0 = target disk mode, 0xff = normal bootup
- // (actually 0x00EE, the 50753 port 6)
-
- for (i = 0; i < m_pm_cmd[4]; i++)
- {
- m_pm_out[2 + i] = 0xff;
- }
- m_pm_slen = m_pm_out[0] + 2;
- m_pmu_send_timer->adjust(attotime(0, ATTOSECONDS_IN_USEC(200)));
- }
- break;
-
- case 0xec: // PMU self-test (send 1 count byte + reply)
- pmu_one_byte_reply(0);
- break;
-
- default:
- fatalerror("PMU: Unhandled command %02x\n", m_pm_cmd[0]);
- }
-
- if (m_pm_slen > 0)
- {
- m_pm_state = 1;
- }
-}
-
-void mac_state::adb_vblank()
-{
- if ((m_adb_state == ADB_STATE_IDLE) || ((ADB_IS_PM_CLASS) && (m_pmu_poll)))
- {
- if (this->adb_pollmouse())
- {
- // if the mouse was the last TALK, we can just send the new data
- // otherwise we need to pull SRQ
- if ((m_adb_last_talk == m_adb_mouseaddr) && !(ADB_IS_PM_CLASS))
- {
- // repeat last TALK to get updated data
- m_adb_waiting_cmd = 1;
- this->adb_talk();
-
- m_adb_timer_ticks = 8;
- this->m_adb_timer->adjust(attotime(0, ATTOSECONDS_IN_USEC(100)));
- }
- #if 0
- else if (ADB_IS_PM_CLASS)
- {
- m_adb_waiting_cmd = 1;
- this->adb_talk();
- m_pm_state = 10;
- m_pmu_send_timer->adjust(attotime(0, ATTOSECONDS_IN_USEC(200)));
- if (ADB_IS_PM_VIA1_CLASS)
- {
- m_pmu_int_status = 0x1;
- }
- else if (ADB_IS_PM_VIA2_CLASS)
- {
- m_pmu_int_status = 0x10;
- }
- }
- #endif
- else
- {
- m_adb_irq_pending = 1;
- m_adb_command = m_adb_send = 0;
- m_adb_timer_ticks = 1; // one tick should be sufficient to make it see the IRQ
- this->m_adb_timer->adjust(attotime(0, ATTOSECONDS_IN_USEC(100)));
- m_adb_srq_switch = 1;
- }
- }
- else if (this->adb_pollkbd(0))
- {
- if ((m_adb_last_talk == m_adb_keybaddr) && !(ADB_IS_PM_CLASS))
- {
- // repeat last TALK to get updated data
- m_adb_waiting_cmd = 1;
- this->adb_talk();
-
- m_adb_timer_ticks = 8;
- this->m_adb_timer->adjust(attotime(0, ATTOSECONDS_IN_USEC(100)));
- }
- #if 0
- else if (ADB_IS_PM_CLASS)
- {
- m_adb_waiting_cmd = 1;
- this->adb_talk();
- m_pm_state = 10;
- m_pmu_send_timer->adjust(attotime(0, ATTOSECONDS_IN_USEC(200)));
- m_pmu_int_status = 0x1;
- }
- #endif
- else
- {
- m_adb_irq_pending = 1;
- m_adb_command = m_adb_send = 0;
- m_adb_timer_ticks = 1; // one tick should be sufficient to make it see the IRQ
- this->m_adb_timer->adjust(attotime(0, ATTOSECONDS_IN_USEC(100)));
- m_adb_srq_switch = 1;
- }
- }
- }
-}
-
-void mac_state::adb_reset()
-{
- int i;
-
- m_adb_srq_switch = 0;
- m_adb_irq_pending = 0; // no interrupt
- m_adb_timer_ticks = 0;
- m_adb_command = 0;
- m_adb_extclock = 0;
- m_adb_send = 0;
- m_adb_waiting_cmd = 0;
- m_adb_streaming = MCU_STREAMING_NONE;
- m_adb_state = 0;
- m_adb_srqflag = false;
- m_pmu_poll = 0;
- if (ADB_IS_BITBANG_CLASS)
- {
- m_adb_state = ADB_STATE_NOTINIT;
- }
- m_adb_direction = 0;
- m_adb_datasize = 0;
- m_adb_last_talk = -1;
-
- m_adb_linestate = 0;
-
- // mouse
- m_adb_mouseaddr = 3;
- m_adb_lastmousex = m_adb_lastmousey = m_adb_lastbutton = 0;
- m_adb_mouse_initialized = 0;
-
- // keyboard
- m_adb_keybaddr = 2;
- m_adb_keybinitialized = 0;
- m_adb_currentkeys[0] = m_adb_currentkeys[1] = 0xff;
- m_adb_modifiers = 0xff;
- for (i=0; i<7; i++)
- {
- m_key_matrix[i] = 0;
- }
- m_adb_keybuf_start = 0;
- m_adb_keybuf_end = 0;
-}
-
-WRITE_LINE_MEMBER(mac_state::adb_linechange_w)
-{
- int dtime = 0;
-/* static const char *states[] =
- {
- "idle",
- "attention",
- "bit0",
- "bit1",
- "bit2",
- "bit3",
- "bit4",
- "bit5",
- "bit6",
- "bit7",
- "tstop",
- "waitt1t",
- "rcvstartbit",
- "srqnodata"
- };*/
-
- if (ADB_IS_EGRET)
- {
- dtime = m_egret->get_adb_dtime();
- }
- else if (ADB_IS_CUDA)
- {
- dtime = m_cuda->get_adb_dtime();
- }
-
-/* if (m_adb_linestate <= 12)
- {
- printf("linechange: %d -> %d, time %d (state %d = %s)\n", state^1, state, dtime, m_adb_linestate, states[m_adb_linestate]);
- }
- else
- {
- printf("linechange: %d -> %d, time %d (state %d)\n", state^1, state, dtime, m_adb_linestate);
- }*/
-
- if ((m_adb_direction) && (m_adb_linestate == LST_TSTOP))
- {
- if (m_adb_stream_ptr & 1) // odd byte, can't end here
- {
-// printf("critical linechange: odd, cont\n");
- m_adb_linestate = LST_BIT0;
- }
- else
- {
- if (dtime < 90)
- {
-// printf("critical linechange: even, and it's another bit\n");
- m_adb_linestate = LST_BIT0;
- }
- }
- }
-
- switch (m_adb_linestate)
- {
- case LST_IDLE:
- if ((state) && (dtime >= 4500)) // reset
- {
-// printf("ADB RESET\n");
- }
- else if ((state) && (dtime >= 1200)) // attention
- {
-// printf("ADB ATTENTION\n");
- m_adb_waiting_cmd = 1;
- m_adb_direction = 0;
- m_adb_linestate++;
- }
- break;
-
- case LST_ATTENTION:
- if ((!state) && (dtime >= 90)) // Tsync
- {
-// printf("ADB Tsync\n");
- m_adb_command = 0;
- m_adb_linestate++;
- }
- break;
-
- case LST_BIT0:
- case LST_BIT1:
- case LST_BIT2:
- case LST_BIT3:
- case LST_BIT4:
- case LST_BIT5:
- case LST_BIT6:
- case LST_BIT7:
- if (!state)
- {
- if (dtime >= 90) // "1" bit
- {
- m_adb_command |= 1;
- }
-// printf("ADB bit %d\n", m_adb_command & 1);
-
- if (m_adb_linestate != LST_BIT7)
- {
- m_adb_command <<= 1;
- }
- else
- {
- if (m_adb_direction)
- {
-// printf("listen byte[%d] = %02x\n", m_adb_stream_ptr, m_adb_command);
- m_adb_buffer[m_adb_stream_ptr++] = m_adb_command;
- m_adb_command = 0;
- }
- }
-
- m_adb_linestate++;
- }
- break;
-
- case LST_TSTOP:
- if (state)
- {
-// printf("ADB TSTOP, command byte %02x\n", m_adb_command);
-
- if (m_adb_direction)
- {
- m_adb_command = m_adb_buffer[0];
- }
-
- m_adb_srqflag = false;
- adb_talk();
-
- if (!m_adb_srqflag)
- {
- set_adb_line(ASSERT_LINE);
- }
- else
- {
- set_adb_line(CLEAR_LINE);
- }
-
- if (m_adb_datasize > 0)
- {
-/* printf("Device has %d bytes of data: ", m_adb_datasize);
- for (int i = 0; i < m_adb_datasize; i++)
- {
- printf("%02x ", m_adb_buffer[i]);
- }*/
- m_adb_linestate = LST_TSTOPSTART; // T1t
- m_adb_timer->adjust(attotime::from_ticks(324/4, 1000000));
- m_adb_stream_ptr = 0;
- }
- else if (m_adb_direction) // if direction is set, we LISTENed to a valid device
- {
- m_adb_linestate = LST_WAITT1T;
- }
- else // no valid device targetted, time out
- {
- if (m_adb_srqflag)
- {
- m_adb_linestate = LST_SRQNODATA;
- m_adb_timer->adjust(attotime::from_ticks(486, 1000000)); // SRQ time
- }
- else
- {
- m_adb_linestate = LST_IDLE;
- }
- }
- }
- break;
-
- case LST_WAITT1T:
- if ((!state) && (dtime >= 300)) // T1t
- {
-// printf("ADB T1t\n");
- m_adb_linestate++;
- }
- break;
-
- case LST_RCVSTARTBIT:
- if ((!state) && (dtime >= 90)) // start
- {
-// printf("ADB start\n");
- m_adb_linestate = LST_BIT0;
- m_adb_command = 0;
- }
- break;
- }
-}
-
-void mac_state::set_adb_line(int linestate)
-{
- if (ADB_IS_EGRET)
- {
- m_egret->set_adb_line(linestate);
- }
- else if (ADB_IS_CUDA)
- {
- m_cuda->set_adb_line(linestate);
- }
-}