Previous 199869 Revisions Next

r21732 Saturday 9th March, 2013 at 04:05:14 UTC by R. Belmont
(MESS) Apollo updates: [Hans Ostermeyer]
* 3c505: fixed rare race conditions (between command response PCPs and receive packet PCPs)
  * receive command PCP data is now saved in m_rcv_response until receive occurs
  * improved end of command recognition with set_command_pending
* 3c505: using now portable byte order functions from endian.h (lsb_first -> htole16)
* 3c505: implemented CMD_CONFIGURE_82586 (to skip broadcast and multicast ethernet packets)
* struct pcb_struct is now packed to correct size (byte packing)
* added pcb_struct m_rcv_response as a one element receive PCB queue
* provide ready signal for the floppy controller
* improved mouse behaviour (especially if mouse is not grabbed)
* delay response for boot_$volun (find partner node), so that real Apollo Workstations will be prefered as diskless boot server
[src/mess/machine]3c505.c apollo.c apollo_kbd.c apollo_net.c

trunk/src/mess/machine/apollo_net.c
r21731r21732
850850   }
851851   else if (current_rx_data_length > 0)
852852   {
853      LOG(("!!!! apollo_netserver_receive: busy - skipped data with length %02x",rx_data_length));
853      LOG1(("apollo_netserver_receive: busy - skipped data with length %02x",rx_data_length));
854854      return 0;
855855   }
856856   else
r21731r21732
859859      current_rx_data_length = rx_data_length;
860860
861861      // delay response to multicast requests
862      int ms = is_apollo_multicast_address(rx_data_buffer) ? 100 : 1;
862      int ms = is_apollo_multicast_address(rx_data_buffer) ? 1000 : 1;
863863      device->machine().scheduler().timer_set(attotime::from_msec(ms), FUNC(receive_interrupt), 0, device);
864864      return 1;
865865   }
trunk/src/mess/machine/apollo.c
r21731r21732
440440   {
441441      SLOG1(("dma read byte at offset %x+%03x = %02x", page_offset, offset, data));
442442   }
443
443//   logerror(" %02x", data);
444444   return data;
445445}
446446
r21731r21732
460460   {
461461      SLOG1(("dma write byte at offset %x+%03x = %02x", page_offset, offset , data));
462462   }
463//   logerror(" %02x", data);
463464}
464465
465466READ8_MEMBER(apollo_state::apollo_dma_read_word){
r21731r21732
14091410   fdc->setup_intrq_cb(pc_fdc_at_device::line_cb(FUNC(apollo_state::fdc_interrupt), this));
14101411   fdc->setup_drq_cb(pc_fdc_at_device::line_cb(FUNC(apollo_state::fdc_dma_drq), this));
14111412
1413   // motor is on, floppy disk is ready
1414   fdc->fdc->ready_w(1);
1415
14121416   device_start_apollo_ptm (machine().device(APOLLO_PTM_TAG) );
14131417   device_start_apollo_sio(machine().device(APOLLO_SIO_TAG));
14141418   device_start_apollo_sio2(machine().device(APOLLO_SIO2_TAG));
trunk/src/mess/machine/apollo_kbd.c
r21731r21732
255255{
256256   if (m_tx_pending > 0)
257257   {
258      m_tx_pending -= 5;
258      m_tx_pending -= 5; // we will be called every 5ms
259259   }
260260   else
261261   {
r21731r21732
263263      int x = m_device->m_io_mouse2->read();
264264      int y = m_device->m_io_mouse3->read();
265265
266      /* sign extend values < 0 */
267      if (x & 0x800)
268         x |= 0xfffff000;
269      if (y & 0x800)
270         y |= 0xfffff000;
271      y = -y;
272
266273      if (m_last_b < 0)
267274      {
268275         m_last_b = b;
r21731r21732
271278      }
272279      else if (b != m_last_b || x != m_last_x || y != m_last_y)
273280      {
274         int dx = x - m_last_x;
275         int dy = y - m_last_y;
276281         UINT8 mouse_data[4];
277282         int mouse_data_size;
278283
279         LOG2(("read_mouse: b=%02x x=%04x y=%04x dx=%d dy=%d", b, x, y, dx, dy));
284         int dx = x - m_last_x;
285         int dy = y - m_last_y;
280286
287         // slow down huge mouse movements
288         dx = dx > 50 ? 50 : dx < -50 ? -50 : dx;
289         dy = dy > 50 ? 50 : dy < -50 ? -50 : dy;
290
291         LOG2(("read_mouse: b=%02x x=%d y=%d dx=%d dy=%d", b, x, y, dx, dy));
292
281293         if (m_device->m_mode == KBD_MODE_0_COMPATIBILITY)
282294         {
283295            mouse_data[0] = 0xdf;
284296            mouse_data[1] = 0xf0 ^ b;
285297            mouse_data[2] = dx;
286            mouse_data[3] = -dy;
298            mouse_data[3] = dy;
287299            mouse_data_size = 4;
288300         }
289301         else
r21731r21732
295307
296308            mouse_data[0] = 0xf0 ^ b;
297309            mouse_data[1] = dx;
298            mouse_data[2] = -dy;
310            mouse_data[2] = dy;
299311            mouse_data_size = 3;
300312         }
301313
r21731r21732
303315         {
304316            // mouse data submitted; update current mouse state
305317            m_last_b = b;
306            m_last_x = x;
307            m_last_y = y;
318            m_last_x += dx;
319            m_last_y += dy;
308320         }
309         m_tx_pending = 100; // mouse data packet will take 50 ms
321         m_tx_pending = 100; // mouse data packet will take 40 ms
310322      }
311323   }
312324}
r21731r21732
862874   }
863875   scan_keyboard();
864876
865   // Note: we omit extra traffic while keyboard is in Compatibitlit mode
877   // Note: we omit extra traffic while keyboard is in Compatibility mode
866878   if (m_device->m_mode != KBD_MODE_0_COMPATIBILITY)
867879   {
868880      m_mouse.read_mouse();
r21731r21732
11851197   PORT_BIT( 0x00000040, IP_ACTIVE_HIGH, IPT_BUTTON2) PORT_NAME("Center mouse button") PORT_CODE(MOUSECODE_BUTTON2)
11861198
11871199   PORT_START("mouse2")  // X-axis
1188   PORT_BIT( 0xfff, 0x00, IPT_MOUSE_X) PORT_SENSITIVITY(100) PORT_KEYDELTA(0) PORT_PLAYER(1)
1200   PORT_BIT( 0xfff, 0x00, IPT_MOUSE_X) PORT_SENSITIVITY(200) PORT_KEYDELTA(1) PORT_PLAYER(1)
11891201
11901202   PORT_START("mouse3")  // Y-axis
1191   PORT_BIT( 0xfff, 0x00, IPT_MOUSE_Y) PORT_SENSITIVITY(100) PORT_KEYDELTA(0) PORT_PLAYER(1)
1203   PORT_BIT( 0xfff, 0x00, IPT_MOUSE_Y) PORT_SENSITIVITY(200) PORT_KEYDELTA(1) PORT_PLAYER(1)
11921204
11931205INPUT_PORTS_END
trunk/src/mess/machine/3c505.c
r21731r21732
1212 *  - http://lxr.free-electrons.com/source/drivers/net/3c505.c
1313 *  - http://stason.org/TULARC/pc/network-cards/O/OLIVETTI-Ethernet-NPU-9144-3C505.html
1414 *  - http://www.bitsavers.org/pdf/3Com/3C500_Mar83.pdf
15 *  - http://www.bitsavers.org/pdf/3Com/1569-03_EtherLink_Plus_Technical_Reference_Jan89.pdf
1516 */
1617
1718#include "machine/3c505.h"
19#include <endian.h>
1820
1921#define VERBOSE 0
2022
r21731r21732
2729#define  MAINCPU "maincpu"
2830
2931//**************************************************************************
30//  DEVICE DEFINITIONS
31//**************************************************************************
32
33//const device_type THREECOM3C505 = threecom3c505_device_config::static_alloc_device_config;
34
35//**************************************************************************
3632//  CONSTANTS
3733//**************************************************************************
3834
r21731r21732
128124
129125   CMD_MC_17 = 0x17,
130126   CMD_TRANSMIT_PACKET_18 = 0x18,
131   CMD_MC_F8 =0xf8,
132   CMD_MC_F9 =0xf9,
133   CMD_MC_FA =0xfa,
127   CMD_MC_F8 = 0xf8,
128   CMD_TRANSMIT_PACKET_F9 = 0xf9,
129   CMD_MC_FA = 0xfa,
134130
135131   /*adapter PCB commands */
136132   CMD_RESET_RESPONSE = 0x30,
r21731r21732
157153   CMD_MC_E2_RESPONSE = 0xe2
158154};
159155
160/* These defines for 'configure' */
156/* defines for 'configure' */
157
161158#define RECV_STATION    0x00
162159#define RECV_BROAD      0x01
163160#define RECV_MULTI      0x02
r21731r21732
166163#define INT_LOOPBACK    0x08
167164#define EXT_LOOPBACK    0x10
168165
169// FIXME:
170// #define lsb_first(a) (((a & 255) << 8) | ((a >>8) & 255))
171#define lsb_first(a) (a)
172
173166/***************************************************************************
174    IMPLEMENTATION
175***************************************************************************/
167 IMPLEMENTATION
168 ***************************************************************************/
176169
177170// device type definition
178const device_type THREECOM3C505 = &device_creator<threecom3c505_device>;
171const device_type THREECOM3C505 = &device_creator<threecom3c505_device> ;
179172
180173//-------------------------------------------------
181// sc499_device - constructor
174// threecom3c505_device - constructor
182175//-------------------------------------------------
183176
184177threecom3c505_device::threecom3c505_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
r21731r21732
194187
195188void threecom3c505_device::static_set_interface(device_t &device, const threecom3c505_interface &interface)
196189{
197   threecom3c505_device &threecom3c505 = downcast<threecom3c505_device &>(device);
198   static_cast<threecom3c505_interface &>(threecom3c505) = interface;
190   threecom3c505_device &threecom3c505 = downcast<threecom3c505_device &> (device);
191   static_cast<threecom3c505_interface &> (threecom3c505) = interface;
199192}
200193
201194//-------------------------------------------------
r21731r21732
207200   m_device = this;
208201   LOG1(("start 3COM 3C505"));
209202
210      m_rx_fifo.start(this, RX_FIFO_SIZE, ETH_BUFFER_SIZE);
211      m_rx_data_buffer.start(this, ETH_BUFFER_SIZE);
212      m_tx_data_buffer.start(this, ETH_BUFFER_SIZE);
213      m_program_buffer.start(this, PGM_BUFFER_SIZE);
203   m_rx_fifo.start(this, RX_FIFO_SIZE, ETH_BUFFER_SIZE);
204   m_rx_data_buffer.start(this, ETH_BUFFER_SIZE);
205   m_tx_data_buffer.start(this, ETH_BUFFER_SIZE);
206   m_program_buffer.start(this, PGM_BUFFER_SIZE);
214207
215208   if (tx_init != NULL)
216209   {
217210      (*tx_init)(this);
218211   }
219212
220   m_timer = m_device->machine().scheduler().timer_alloc(FUNC(static_set_interrupt), this);
213   m_do_command_timer = m_device->machine().scheduler().timer_alloc(FUNC(static_do_command), this);
221214}
222215
223216//-------------------------------------------------
r21731r21732
234227   m_program_buffer.reset();
235228
236229   memset(m_reg, 0, sizeof(m_reg));
237   m_status = HCRE;
230   m_status = HCRE | DIR_;
238231   m_control = 0;
239232   m_command_index = 0;
240233   m_command_pending = 0;
241   m_mc_f9_pending = 0;
234   m_wait_for_nak = 0;
242235   m_wait_for_ack = 0;
243236   m_rx_data_index = 0;
244237   m_rx_pending = 0;
r21731r21732
249242   m_microcode_version = 0;
250243   m_i82586_config = 0;
251244
252   // FIXME: test data
253   m_netstat.tot_recv = 1;
254   m_netstat.tot_xmit = 2;
255   m_netstat.err_CRC = 3;
256   m_netstat.err_align = 4;
257   m_netstat.err_res = 5;
258   m_netstat.err_ovrrun = 6;
245   // these will appear in /etc/nodestat -l
246   m_netstat.tot_recv = 0;
247   m_netstat.tot_xmit = 0;
248   m_netstat.err_CRC = 0;
249   m_netstat.err_align = 0;
250   m_netstat.err_res = 0;
251   m_netstat.err_ovrrun = 0;
259252
260   memset(m_station_address, 0 , sizeof(m_station_address));
261   memset(m_multicast_list, 0 , sizeof(m_multicast_list));
253   memset(m_station_address, 0, sizeof(m_station_address));
254   memset(m_multicast_list, 0, sizeof(m_multicast_list));
262255   set_filter_list();
263256   set_promisc(true);
264257}
r21731r21732
339332   if (verbose > 0)
340333   {
341334      int i;
342      logerror("%s: %s (length=%02x)", m_device->cpu_context(),   title, m_length);
335      logerror("%s: %s (length=%02x)", m_device->cpu_context(), title, m_length);
343336      for (i = 0; i < m_length; i++)
344337      {
345338         logerror(" %02x", m_data[i]);
r21731r21732
386379   m_count = 0;
387380}
388381
389int threecom3c505_device::data_buffer_fifo::put(const UINT8 data[], const int length)
382int threecom3c505_device::data_buffer_fifo::put(const UINT8 data[],   const int length)
390383{
391384   UINT16 next_index = (m_put_index + 1) % m_size;
392385
r21731r21732
437430
438431void threecom3c505_device::set_filter_list()
439432{
440   memset(m_filter_list, 0 , sizeof(m_filter_list));
441   memcpy(m_filter_list, m_station_address,  ETHERNET_ADDR_SIZE);
442   memset(m_filter_list+ETHERNET_ADDR_SIZE,0xff, ETHERNET_ADDR_SIZE);
443   memcpy(m_filter_list+ETHERNET_ADDR_SIZE*2, m_multicast_list, sizeof(m_multicast_list));
433   memset(m_filter_list, 0, sizeof(m_filter_list));
434   memcpy(m_filter_list, m_station_address, ETHERNET_ADDR_SIZE);
435   memset(m_filter_list + ETHERNET_ADDR_SIZE, 0xff, ETHERNET_ADDR_SIZE);
436   memcpy(m_filter_list + ETHERNET_ADDR_SIZE * 2, m_multicast_list, sizeof(m_multicast_list));
444437
445438   if (setfilter != NULL)
446439   {
r21731r21732
465458         (*set_irq)(this, state);
466459      }
467460      irq_state = state;
468
469      // FIXME: hack?
470      if ( m_command_buffer[0] == CMD_EXECUTE_PROGRAM && state == 1)
471      {
472         m_status |= ASF_PCB_END;
473      }
474461   }
475462}
476463
477TIMER_CALLBACK( threecom3c505_device::static_set_interrupt )
478{
479   reinterpret_cast<threecom3c505_device *> (ptr)->set_interrupt(ASSERT_LINE);
480}
481
482464// -------------------------------------
483465
484466void threecom3c505_device::log_command()
r21731r21732
490472      switch (m_command_buffer[0])
491473      {
492474      case CMD_RESET: // 0x00
493         logerror("CMD_RESET");
475         logerror("!!! unexpected CMD_RESET");
494476         break;
495477      case CMD_CONFIGURE_ADAPTER_MEMORY: // 0x01
496478         logerror("CMD_CONFIGURE_ADAPTER_MEMORY");
r21731r21732
511493         logerror("CMD_LOAD_MULTICAST_LIST");
512494         break;
513495      case CMD_CLEAR_PROGRAM: // 0x0c
514         logerror("!!! Unexpected CMD_CLEAR_PROGRAM");
496         logerror("!!! unexpected CMD_CLEAR_PROGRAM");
515497         break;
516498      case CMD_DOWNLOAD_PROGRAM: // 0x0d
517499         logerror("CMD_DOWNLOAD_PROGRAM");
r21731r21732
535517      case CMD_MC_F8: // 0xf8
536518         logerror("!!! CMD_MC_F8");
537519         break;
538      case CMD_MC_F9: // 0xf9
539         logerror("CMD_MC_F9");
520      case CMD_TRANSMIT_PACKET_F9: // 0xf9
521         logerror("CMD_TRANSMIT_PACKET_F9");
540522         break;
541523      case CMD_MC_FA: // 0xfa
542524         logerror("!!! CMD_MC_FA");
543525         break;
544526
545527      default:
546         logerror("!!! Unexpected Command !!!");
528         logerror("!!! unexpected Command");
547529      }
548530
549531      switch (m_command_buffer[0])
550532      {
551      case CMD_MC_F9: // 0xf9
533      case CMD_TRANSMIT_PACKET_F9: // 0xf9
552534         logerror(" (%02x, length=00)", m_command_buffer[0]);
553535         break;
554536
r21731r21732
619601         logerror("!!! CMD_MC_E2_RESPONSE");
620602         break;
621603      default:
622         logerror("!!! Unexpected Response !!!");
604         logerror("!!! unexpected Response");
623605      }
624606      logerror(" (%02x, length=%02x)", m_response.command, m_response.length);
625607      for (i = 0; i < m_response.length; i++)
r21731r21732
630612   }
631613}
632614
615/***************************************************************************
616 do_receive_command
617 ***************************************************************************/
618
633619void threecom3c505_device::do_receive_command()
634620{
635   LOG2(("do_receive_command - data_length=%x rx_pending=%d",
636               m_rx_data_buffer.get_length(), m_rx_pending));
637#if 0
638   if (m_microcode_running && m_microcode_version == APOLLO_MC_VERSION_SR10_4)
621   // receive pending and no other command is pending
622   if (m_rx_pending > 0 && !m_command_pending)
639623   {
640      m_response.command = CMD_MC_E1_RESPONSE;
641      m_response.length = 0;
642      m_response_length = 0;
643      m_response_index = 0;
624      if (m_rx_data_buffer.get_length() == 0 && !m_rx_fifo.is_empty())
625      {
626         m_rx_fifo.get(&m_rx_data_buffer);
627      }
644628
645      m_rx_pending++;
646   }
647   else
648#endif
629      // receive data available ?
630      if (m_rx_data_buffer.get_length() > 0)
631      {
632         LOG2(("do_receive_command - data_length=%x rx_pending=%d",
633                     m_rx_data_buffer.get_length(), m_rx_pending));
649634
650   {
651      m_response.command = CMD_RECEIVE_PACKET_COMPLETE; // 0x38
652      m_response.length = 16;
653      m_response.data.rcv_resp.buf_ofs = 0;
654      m_response.data.rcv_resp.buf_seg = 0;
655      m_response.data.rcv_resp.buf_len = m_rx_data_buffer.get_length();
656      m_response.data.rcv_resp.pkt_len = m_rx_data_buffer.get_length(); // (?)
657      m_response.data.rcv_resp.timeout = 0; // successful completion
658      m_response.data.rcv_resp.status = m_rx_data_buffer.get_length() > 0 ? 0 : 0xffff;
659      m_response.data.rcv_resp.timetag = 0L; // TODO
635         m_rx_pending--;
636         set_command_pending(1);
660637
661      m_response_length = m_response.length + 2;
662      m_response_index = 0;
663   }
638         // preset receive response PCB
639         memcpy(&m_response, &m_rcv_response, sizeof(m_rcv_response));
664640
665   m_status |= ACRF; /* adapter command register full */
641//         m_response.command = CMD_RECEIVE_PACKET_COMPLETE; // 0x38
642//         m_response.length = 16;
643//         m_response.data.rcv_resp.buf_ofs = htole16(0);
644//         m_response.data.rcv_resp.buf_seg = htole16(0);
645//         m_response.data.rcv_resp.buf_len = htole16(buf_len);
646         m_response.data.rcv_resp.pkt_len = htole16(m_rx_data_buffer.get_length());
647         m_response.data.rcv_resp.timeout = htole16(0); // successful completion
648         m_response.data.rcv_resp.status  = htole16(m_rx_data_buffer.get_length() > 0 ? 0 : 0xffff);
649         m_response.data.rcv_resp.timetag = htole32(0); // TODO: time tag
666650
667   if (m_control & CMDE)
668   {
669      LOG2(("do_receive_command - set_interrupt(%d)", ASSERT_LINE));
670      // set_interrupt(ASSERT_LINE);
651         // compute and check no of bytes to be DMA'ed (must be even)
652         UINT16 buf_len = le16toh(m_response.data.rcv_resp.buf_len) & ~1;
653         if (m_rx_data_buffer.get_length() > buf_len)
654         {
655            LOG1(("do_receive_command !!! buffer size too small (%d < %d)", buf_len, m_rx_data_buffer.get_length()));
656            m_response.data.rcv_resp.pkt_len = htole16(buf_len);
657            m_response.data.rcv_resp.status = 0xffff;
658         }
659         else
660         {
661            buf_len = (m_rx_data_buffer.get_length() + 1) & ~1;
662            m_response.data.rcv_resp.buf_len = htole16(buf_len);
663         }
671664
672      // interrupt later
673      m_timer->adjust( attotime::from_usec(10));
665         m_response_length = m_response.length + 2;
666         m_response_index = 0;
667
668         m_status |= ACRF; /* set adapter command register full */
669         if (m_control & CMDE)
670         {
671            set_interrupt(ASSERT_LINE);
672         }
673      }
674674   }
675675}
676676
677void threecom3c505_device::set_command_pending(int onoff)
677/***************************************************************************
678 set_command_pending onoff
679 ***************************************************************************/
680
681void threecom3c505_device::set_command_pending(int state)
678682{
679   m_command_pending = onoff;
680   LOG2(("set_command_pending %d m_rx_pending=%d m_rx_data_buffer.get_length()=%x%s",
681         m_command_pending, m_rx_pending, m_rx_data_buffer.get_length(), onoff ? "" :"\n"));
683   LOG2(("set_command_pending %d -> %d m_wait_for_ack=%d m_wait_for_nak=%d m_rx_pending=%d%s",
684               m_command_pending, state, m_wait_for_ack, m_wait_for_nak, m_rx_pending, state ? "" :"\n"));
682685
683686//- verbose = onoff ? 1 : 2;
684687
685   if (!m_command_pending)
688   switch (state)
686689   {
690   case 0:
691      // command is no longer pending
692      m_command_pending = 0;
693
687694      // clear previous command byte
688695      m_command_buffer[0] = 0;
689696
690      m_mc_f9_pending = 0;
691697      m_wait_for_ack = 0;
698      m_wait_for_nak = 0;
692699
693      if (m_rx_pending > 0 && m_rx_data_buffer.get_length() > 0)
700      do_receive_command();
701      break;
702   case 1:
703      // command is pending
704      m_command_pending = 1;
705      break;
706   case 2:
707      // wait for nak/ack
708      if (m_microcode_running && m_microcode_version == APOLLO_MC_VERSION_SR10_4)
694709      {
695         m_rx_pending--;
696         m_command_pending = 1;
697
698         LOG2(("set_command_pending %d m_rx_pending=%d", m_command_pending, m_rx_pending));
699
700         do_receive_command();
710         m_wait_for_nak = 1;
701711      }
712      else
713      {
714         m_wait_for_ack = 1;
715      }
716      break;
717   default:
718      LOG(("set_command_pending %d unexpected" , state));
719      break;
702720   }
721
703722}
704723
705724/***************************************************************************
706725 do_command
707726 ***************************************************************************/
708727
728TIMER_CALLBACK( threecom3c505_device::static_do_command )
729{
730   reinterpret_cast<threecom3c505_device *> (ptr)->do_command();
731}
732
709733void threecom3c505_device::do_command()
710734{
735   pcb_struct &command_pcp = (pcb_struct &) m_command_buffer;
736
711737   // default to successful completion
712   m_response.command = m_command_buffer[0] + CMD_RESPONSE_OFFSET;
738   m_response.command = command_pcp.command + CMD_RESPONSE_OFFSET;
713739   m_response.length = 1;
714740   m_response.data.failed = 0; // successful completion
715741
716   switch (m_command_buffer[0])
742   switch (command_pcp.command)
717743   {
718744   case CMD_RESET: // 0x00
719//      FIXME:
720//      device_reset();
745      // FIXME: should never occur
721746      break;
722747
723748   case CMD_CONFIGURE_ADAPTER_MEMORY: // 0x01
724      m_i82586_config = m_program_buffer.get_word(1);
749      // TODO
725750      break;
726751
752   case CMD_CONFIGURE_82586: // 0x02
753      m_i82586_config = command_pcp.data.raw[0] + (command_pcp.data.raw[1] << 8);
754      break;
755
727756   case CMD_RECEIVE_PACKET: // 0x08
728      if (m_rx_data_buffer.get_length() == 0 && !m_rx_fifo.get(&m_rx_data_buffer))
729      {
730         // receive data not yet available
731         m_rx_pending++;
732         set_command_pending(0);
733      }
734      else
735      {
736         do_receive_command();
737      }
757      // preset response PCB from the Receive Command PCB
758      m_rcv_response.command = CMD_RECEIVE_PACKET_COMPLETE; // 0x38
759      m_rcv_response.length = sizeof(struct Rcv_resp);
760      m_rcv_response.data.rcv_resp.buf_ofs = command_pcp.data.rcv_pkt.buf_ofs;
761      m_rcv_response.data.rcv_resp.buf_seg = command_pcp.data.rcv_pkt.buf_seg;
762      m_rcv_response.data.rcv_resp.buf_len = command_pcp.data.rcv_pkt.buf_len;
763      m_rcv_response.data.rcv_resp.pkt_len = 0;
764      m_rcv_response.data.rcv_resp.timeout = 0;
765      m_rcv_response.data.rcv_resp.status = 0;
766      m_rcv_response.data.rcv_resp.timetag = 0L; // TODO
767
768      m_rx_pending++;
769      set_command_pending(0);
738770      return;
739771      // break;
740772
741   case CMD_MC_F9:
773   case CMD_TRANSMIT_PACKET_F9:
742774      m_response.command = CMD_TRANSMIT_PACKET_COMPLETE;
743775      // fall through
744776
745777   case CMD_TRANSMIT_PACKET: // 0x09
746778   case CMD_TRANSMIT_PACKET_18: // 0x18
747      m_response.length = 8;
779      m_response.length = sizeof(struct Xmit_resp);
748780      m_response.data.xmit_resp.buf_ofs = 0;
749781      m_response.data.xmit_resp.buf_seg = 0;
750782      m_response.data.xmit_resp.c_stat = 0; // successful completion
r21731r21732
752784      break;
753785
754786   case CMD_EXECUTE_PROGRAM: // 0x0e
755      m_response.length = 0;
756      m_microcode_running = 1;
757      m_microcode_version = m_program_buffer.get_word(1);
787      // m_response.length = 0;
788
789      // FIXME: hack?
790      m_status |= ASF_PCB_END;
758791      break;
759792
760793   case CMD_NETWORK_STATISTICS: // 0x0a
761794      m_response.length = sizeof(struct Netstat);
762      // response data must be LSB first!
763      m_response.data.netstat.tot_recv = lsb_first(m_netstat.tot_recv);
764      m_response.data.netstat.tot_xmit = lsb_first(m_netstat.tot_xmit);
765      m_response.data.netstat.err_CRC = lsb_first(m_netstat.err_CRC);
766      m_response.data.netstat.err_align = lsb_first(m_netstat.err_align);
767      m_response.data.netstat.err_res = lsb_first(m_netstat.err_res);
768      m_response.data.netstat.err_ovrrun = lsb_first(m_netstat.err_ovrrun);
795      m_response.data.netstat.tot_recv = htole16(m_netstat.tot_recv);
796      m_response.data.netstat.tot_xmit = htole16(m_netstat.tot_xmit);
797      m_response.data.netstat.err_CRC = htole16(m_netstat.err_CRC);
798      m_response.data.netstat.err_align = htole16(m_netstat.err_align);
799      m_response.data.netstat.err_res = htole16(m_netstat.err_res);
800      m_response.data.netstat.err_ovrrun = htole16(m_netstat.err_ovrrun);
769801      break;
770802
771803   case CMD_ADAPTER_INFO: // 0x11
772804      m_response.length = sizeof(struct Info);
773      // FIXME: replace test data; must be LSB first!
805      // FIXME: using demo data
774806      m_response.data.info.minor_vers = 1;
775807      m_response.data.info.major_vers = 2;
776      m_response.data.info.ROM_cksum = lsb_first(3);
777      m_response.data.info.RAM_sz = lsb_first(4);
778      m_response.data.info.free_ofs = lsb_first(5);
779      m_response.data.info.free_seg = lsb_first(6);
808      m_response.data.info.ROM_cksum = htole16(3);
809      m_response.data.info.RAM_sz = htole16(4);
810      m_response.data.info.free_ofs = htole16(5);
811      m_response.data.info.free_seg = htole16(6);
780812      break;
781813
782814   case CMD_LOAD_MULTICAST_LIST:// 0x0b
783      if (m_command_buffer[1] > sizeof(m_multicast_list) ||
784            (m_command_buffer[1] % ETHERNET_ADDR_SIZE) != 0)
815      if (command_pcp.length > sizeof(m_multicast_list)
816            || (command_pcp.length % ETHERNET_ADDR_SIZE) != 0)
785817      {
786         LOG(("CMD_LOAD_MULTICAST_LIST - !!! unexpected data size %d !!!", m_command_buffer[1]));
818         LOG(("CMD_LOAD_MULTICAST_LIST - unexpected data size %d", command_pcp.length));
787819      }
788820      else
789821      {
790         memset(m_multicast_list, 0 , sizeof(m_multicast_list));
791         memcpy(m_multicast_list, m_command_buffer+2 , m_command_buffer[1]-2);
822         memset(m_multicast_list, 0, sizeof(m_multicast_list));
823         memcpy(m_multicast_list, command_pcp.data.multicast, command_pcp.length- 2);
792824         set_filter_list();
793825      }
794826      break;
795827
796828   case CMD_SET_STATION_ADDRESS: // 0x10
797      if (m_command_buffer[1] != sizeof(m_station_address))
829      if (command_pcp.length != sizeof(m_station_address))
798830      {
799         LOG(("CMD_SET_STATION_ADDRESS - !!! unexpected data size %d !!!", m_command_buffer[1]));
800         memset(m_station_address, 0 , sizeof(m_station_address));
831         LOG(("CMD_SET_STATION_ADDRESS - unexpected data size %d", command_pcp.length));
832         memset(m_station_address, 0, sizeof(m_station_address));
801833      }
802834      else
803835      {
804         memcpy(m_station_address, m_command_buffer+2 , m_command_buffer[1]);
836         memcpy(m_station_address, command_pcp.data.eth_addr, command_pcp.length);
805837      }
806838      set_filter_list();
807      set_mac((char *)m_station_address);
839      set_mac((char *) m_station_address);
808840      break;
809841
810   case CMD_CONFIGURE_82586: // 0x02
811   case CMD_DOWNLOAD_PROGRAM: // 0x0d
812842   case CMD_MC_17: // 0x17
813   default:
843      m_microcode_running = 1;
814844      break;
845
846   case CMD_DOWNLOAD_PROGRAM: // 0x0d
847      UINT16 mc_version = m_program_buffer.get_word(1);
848      switch (mc_version)
849      {
850      case APOLLO_MC_VERSION_SR10_2:
851      case APOLLO_MC_VERSION_SR10_4:
852         m_microcode_version = mc_version;
853         break;
854      default:
855         m_microcode_version = 0;
856         LOG(("CMD_DOWNLOAD_PROGRAM - unexpected microcode version %04x", mc_version));
857         break;
858      }
859      // return microcode version as program id
860      m_response.length = 2;
861      m_response.data.raw[0] = m_microcode_version & 0xff;
862      m_response.data.raw[1] = (m_microcode_version >> 8) & 0xff;
863      break;
815864   }
816865
817866   m_response_index = 0;
818867   m_response_length = m_response.length + 2;
819   m_status |= ACRF; /* adapter command register full */
820868
869   m_status |= ACRF; /* set adapter command register full */
821870   if (m_control & CMDE)
822871   {
823      switch (m_command_buffer[0])
824      {
825      case CMD_NETWORK_STATISTICS: // 0x0a
826      case CMD_DOWNLOAD_PROGRAM: // 0xd
827      case CMD_EXECUTE_PROGRAM: // 0x0e
828      case CMD_ADAPTER_INFO: // 0x11
829         // interrupt later
830         m_timer->adjust( attotime::from_msec(5));
831         break;
832
833      default:
834         // interrupt at once
835         set_interrupt(ASSERT_LINE);
836         break;
837      }
872      set_interrupt(ASSERT_LINE);
838873   }
839874}
840875
r21731r21732
848883   // wireshark filter: eth.addr eq 08:00:1e:01:ae:a5 or eth.dst eq ff:ff:ff:ff:ff:ff or eth.dst eq 09:00:1e:00:00:00 or eth.dst eq 09:00:1e:00:00:01
849884
850885   int i;
886   static const UINT8 broadcast_address[ETHERNET_ADDR_SIZE] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
887
888   // accept all packets if RECV_PROMISC is set
889   if (m_i82586_config & RECV_PROMISC)
890   {
891      return 1;
892   }
893
894   // skip Ethernet broadcast packets if RECV_BROAD is not set
895   if (!(m_i82586_config & RECV_BROAD) && memcmp(mac_address,
896         broadcast_address, ETHERNET_ADDR_SIZE) == 0)
897   {
898      return 0;
899   }
900
901   // skip Ethernet multicast packets if RECV_MULTI is not set
902   if (!(m_i82586_config & RECV_MULTI) && (mac_address[0] & 0x01) != 0)
903   {
904      return 0;
905   }
906
851907   for (i = 0; i + ETHERNET_ADDR_SIZE < sizeof(m_filter_list); i += ETHERNET_ADDR_SIZE)
852908   {
853909      if (memcmp(mac_address, m_filter_list + i, ETHERNET_ADDR_SIZE) == 0)
r21731r21732
862918         return 1;
863919      }
864920   }
865   return 0;
921   return 0;
866922}
867923
868924/***************************************************************************
r21731r21732
871927
872928void threecom3c505_device::recv_cb(UINT8 *data, int length)
873929{
930
874931   if (length < ETHERNET_ADDR_SIZE || !ethernet_packet_is_for_me(data))
875932   {
876933      // skip packet
r21731r21732
888945      m_netstat.tot_recv++;
889946      LOG2(("recv_cb: data_length=%x m_rx_pending=%d", length, m_rx_pending));
890947
891      if (m_rx_data_buffer.get_length() == 0)
892      {
893         m_rx_fifo.get(&m_rx_data_buffer);
894      }
895
896      if (!m_command_pending && m_rx_pending > 0
897            && m_rx_data_buffer.get_length() > 0)
898      {
899         m_rx_pending--;
900         set_command_pending(1);
901         do_receive_command();
902      }
948      do_receive_command();
903949   }
904950}
905951
906void threecom3c505_device::write_command_port( UINT8 data)
952/***************************************************************************
953 write_command_port
954***************************************************************************/
955
956void threecom3c505_device::write_command_port(UINT8 data)
907957{
908   LOG2(("writing 3C505 command port %02x - m_status=%02x m_control=%02x m_command_index=%02x", data, m_status, m_control, m_command_index));
958   LOG2(("writing 3C505 command port %02x - m_status=%02x m_control=%02x m_command_index=%02x",
959         data, m_status, m_control, m_command_index));
909960
910   if ((m_control & HSF_PCB_MASK) != HSF_PCB_END)
961   if (m_command_index == 0)
911962   {
912      m_command_buffer[m_command_index++] = data;
913      m_status |= HCRE; /* command register empty */
914
915      if (m_command_index == 1)
963      switch (data)
916964      {
917         switch (data)
918         {
919         case 0:
920            // spurious data; set command register empty
921            m_command_index = 0;
922            m_status |= HCRE;
923            break;
965      case 0:
966         LOG2(("!!! writing 3C505 Command Register = %02x", data));
967         // spurious data; reset?
968         break;
924969
925         case CMD_MC_F9:
926//          case CMD_MC_FA:
927            // read data length from data port (not from command port)
928            m_tx_data_buffer.reset();
929            m_status |= HRDY; /* data register ready */
930            set_command_pending(1);
931            break;
970      case CMD_TRANSMIT_PACKET_F9:
971         // read data length from data port (not from command port)
972         m_tx_data_buffer.reset();
973         m_status |= HRDY; /* data register ready */
974         m_command_buffer[m_command_index++] = data;
975         set_command_pending(1);
976         break;
932977
933         default:
934            set_command_pending(1);
935            break;
936         }
978      default:
979         m_command_buffer[m_command_index++] = data;
980         set_command_pending(1);
981         break;
937982      }
938983   }
984   else if ((m_control & HSF_PCB_MASK) != HSF_PCB_END)
985   {
986      m_command_buffer[m_command_index++] = data;
987   }
939988   else
940989   {
941990      m_status &= ~ASF_PCB_MASK;
r21731r21732
9661015         m_status |= HRDY; /* data register ready */
9671016         break;
9681017
1018      case CMD_NETWORK_STATISTICS: // 0x0a
1019      case CMD_EXECUTE_PROGRAM: // 0x0e
1020      case CMD_ADAPTER_INFO: // 0x11
1021         // delay command execution
1022         m_do_command_timer->adjust(attotime::from_usec(100));
1023         break;
1024
9691025      default:
9701026         do_command();
9711027         break;
9721028      }
9731029   }
1030
1031   m_status |= HCRE; /* command register empty */
9741032}
9751033
1034/***************************************************************************
1035 read_command_port
1036 ***************************************************************************/
1037
9761038UINT8 threecom3c505_device::read_command_port()
9771039{
9781040   UINT8 data;
1041
1042   // the interrupt request is cleared when the Command Register is read
1043   set_interrupt(CLEAR_LINE);
1044
9791045   if (m_response_index == 0)
9801046   {
981//      set_command_pending(1);
9821047      data = m_response.command;
9831048   }
9841049   else if (m_response_index == 1)
r21731r21732
9931058   {
9941059      data = m_response.length + 2;
9951060   }
996   else if (m_response_index == m_response_length+1 /*&& m_microcode_running*/)
1061   else if (m_response_index == m_response_length + 1 /*&& m_microcode_running*/)
9971062   {
9981063      // FIXME: special for SR10.4 microcode, content doesn't matter?
9991064      data = 0; // ?
10001065      m_response_index++;
10011066
1002      m_status &= ~ACRF; /* adapter command register no longer full */
1067      m_status &= ~ACRF; /* the adapter command register is no longer full */
10031068
1004      LOG2(("FIXME: reading 3C505 Command Register at offset %02x with index %02x = %02x",
1005            PORT_COMMAND, m_response_index, data));
1069      LOG2(("read_command_port: !!! reading 3C505 Command Register = %02x - m_status=%02x m_control=%02x",
1070                  data, m_status, m_control));
10061071
1007      if (m_mc_f9_pending == 1)
1008      {
1009         m_mc_f9_pending++;
1010      }
1072      // wait for nak in control register
1073      set_command_pending(2);
10111074   }
10121075   else
10131076   {
10141077      // should never happen
10151078      data = 0; // 0xff;
1016      LOG(("UNEXPECTED: reading 3C505 Command Register at offset %02x = %02x", PORT_COMMAND, data));
1079      LOG(("read_command_port: unexpected reading Command Register at index %04x", m_response_index));
10171080   }
10181081
10191082   if (m_response_index <= m_response_length + 1)
r21731r21732
10241087      }
10251088      else if (m_response_index == m_response_length + 1)
10261089      {
1027         // FIXME:
1028         if (!(m_status & DIR_))
1029         {
1030            m_status &= ~HRDY; /* data register no longer ready */
1031         }
1032
10331090         log_response();
10341091
10351092         switch (m_response.command)
r21731r21732
10491106         case CMD_TRANSMIT_PACKET_18_COMPLETE:
10501107            m_netstat.tot_xmit++;
10511108
1052            if(!send(m_tx_data_buffer.get_data(), m_tx_data_buffer.get_length()))
1109            if (!send(m_tx_data_buffer.get_data(),    m_tx_data_buffer.get_length()))
10531110            {
1054               // FIXME: failed to send the ethernet packet
1055               LOG(("read_command_port(): failed to send ethernet packet"));
1111               // FIXME: failed to send the Ethernet packet
1112               LOG(("read_command_port(): !!! failed to send Ethernet packet"));
10561113            }
10571114
10581115            if (tx_data != NULL && //
1059               (*tx_data)(this, m_tx_data_buffer.get_data(), m_tx_data_buffer.get_length()) == 0)
1116                  (*tx_data)(this, m_tx_data_buffer.get_data(), m_tx_data_buffer.get_length()) == 0)
10601117            {
1061               // FIXME: failed to transmit the ethernet packet
1062               LOG(("read_command_port(): failed to transmit ethernet packet"));
1118               // FIXME: failed to transmit the Ethernet packet
1119               LOG(("read_command_port(): !!! failed to transmit Ethernet packet"));
10631120            }
10641121
10651122            m_tx_data_buffer.reset();
1066            if (m_command_buffer[0] != CMD_MC_F9)
1123            if (m_command_buffer[0] != CMD_TRANSMIT_PACKET_F9)
10671124            {
1068//                  set_command_pending(0);
1069               m_wait_for_ack = 1;
1125               set_command_pending(2);
10701126            }
10711127            break;
10721128
10731129         case CMD_DOWNLOAD_PROGRAM_RESPONSE:
10741130            m_program_buffer.reset();
1075//              set_command_pending(0);
1076            m_wait_for_ack = 1;
1131            set_command_pending(2);
10771132            break;
10781133
10791134         default:
1080//              set_command_pending(0);
1081            m_wait_for_ack = 1;
1135            set_command_pending(2);
10821136            break;
10831137         }
10841138      }
r21731r21732
10861140   return data;
10871141}
10881142
1089void threecom3c505_device::write_data_port( UINT8 data)
1143/***************************************************************************
1144 write_data_port
1145 ***************************************************************************/
1146
1147void threecom3c505_device::write_data_port(UINT8 data)
10901148{
10911149   if (m_control & FLSH)
10921150   {
r21731r21732
10941152   }
10951153   else if ((m_status & HRDY) == 0)
10961154   {
1097      // this will happen in ether.dex Test 20/1
1155      // this happened in ether.dex Test 20/1
10981156      LOG(("write_data_port: failed to write tx data (data register not ready), data length=%x status=%x",
10991157                  m_tx_data_buffer.get_length(), m_status));
11001158   }
r21731r21732
11071165   }
11081166#endif
11091167
1110   else if (m_command_buffer[0] == CMD_MC_F9)
1168   else if (m_command_buffer[0] == CMD_TRANSMIT_PACKET_F9)
11111169   {
1112      switch (m_command_index) {
1170      switch (m_command_index)
1171      {
11131172      case 1:
11141173         m_command_buffer[m_command_index++] = data;
11151174         break;
r21731r21732
11271186         if (m_tx_data_buffer.get_length() == m_tx_data_length)
11281187         {
11291188            // CMD_TRANSMIT_PACKET_COMPLETE
1130#if 0
1131            if (m_command_buffer[0] == CMD_MC_F8)
1132            {
1133               // FIXME: what does it do?
1134               LOG(("write_data_port: !!! TODO: CMD_MC_F8 !!! command=%x data length=%x", m_command_buffer[0], m_tx_data_length));
1135            }
1136#endif
11371189            m_tx_data_buffer.log("Tx Data");
11381190            do_command();
11391191         }
11401192         break;
11411193      }
11421194   }
1143   else if (m_command_buffer[0] == CMD_TRANSMIT_PACKET ||
1144         m_command_buffer[0] == CMD_TRANSMIT_PACKET_18)
1195   else if (m_command_buffer[0] == CMD_TRANSMIT_PACKET || //
1196         m_command_buffer[0]   == CMD_TRANSMIT_PACKET_18)
11451197   {
11461198      if (!m_tx_data_buffer.append(data))
11471199      {
r21731r21732
11811233   }
11821234   else
11831235   {
1184      LOG(("write_data_port: !!! UNEXPECTED !!! command=%x data=%02x", m_command_buffer[0], data));
1236      LOG(("write_data_port: unexpected command %02x data=%02x", m_command_buffer[0], data));
11851237   }
11861238
11871239   if (m_tx_data_buffer.get_length() >= PORT_DATA_FIFO_SIZE
r21731r21732
11971249   }
11981250}
11991251
1200UINT8 threecom3c505_device::read_data_port(){
1252/***************************************************************************
1253 read_data_port
1254 ***************************************************************************/
1255
1256UINT8 threecom3c505_device::read_data_port()
1257{
12011258   UINT8 data;
12021259   UINT16 data_length = m_rx_data_buffer.get_length();
12031260   // DomainOS will read  words (i.e. even number of bytes); must handle packets with odd byte length
1204   UINT16 even_data_length = (data_length+1) & ~1;
1261   UINT16 even_data_length = (data_length + 1) & ~1;
12051262
12061263   if (m_rx_data_index < even_data_length)
12071264   {
12081265      // eventually prepend data length (for CMD_MC_E1_RESPONSE)
12091266      data = m_rx_data_index == -2 ? (data_length & 0xff) : //
12101267            m_rx_data_index == -1 ? (data_length << 8) : //
1211            m_rx_data_buffer.get(m_rx_data_index);
1268                  m_rx_data_buffer.get(m_rx_data_index);
12121269
12131270      m_rx_data_index++;
12141271
r21731r21732
12171274         m_status &= ~HRDY; /* data register no longer ready */
12181275         m_rx_data_buffer.log("Rx Data");
12191276         m_rx_data_buffer.reset();
1220//          set_command_pending(0);
1221         m_wait_for_ack = 1;
1277         set_command_pending(2);
12221278      }
12231279   }
1224
1225#if 0
1226   else if (m_rx_data_index == data_length && (data_length & 1))
1227   {
1228      // data length is odd, pad with 0 to next even size
1229      data = 0;
1230      m_rx_data_index++;
1231      LOG(("!!!: padding 3C505 Rx Data with odd data length %2x with value %02x", data_length, data));
1232   }
1233#endif
1234
12351280   else
12361281   {
12371282      // FIXME: should never happen
12381283      data = 0xff;
1239      m_status &= ~HRDY; /* data register no longer ready */
1240      set_command_pending(0);
1241      LOG(("UNEXPECTED: reading 3C505 data Register as %02x (data_length=%02x)", data, data_length));
1284      LOG(("read_data_port: unexpected reading data at index %04x)", m_rx_data_index));
12421285   }
12431286   return data;
12441287}
12451288
1246void threecom3c505_device::write_control_port( UINT8 data)
1289/***************************************************************************
1290 write_control_port
1291 ***************************************************************************/
1292
1293void threecom3c505_device::write_control_port(UINT8 data)
12471294{
1248   // if (m_device->machine->firstcpu->safe_pcbase() == 0x3C4BAD48) verbose = 3;
1249   // if (m_device->machine->firstcpu->safe_pcbase() == 0x010464DC) verbose = 3;
1250
1251   if (verbose <= 2 && (data & (DMAE | TCEN /*| CMDE*/)) != 0)
1295   switch (data & (ATTN | FLSH))
12521296   {
1253      // dma or interrupts enabled
1254      LOG1(("writing 3C505 Control Register at offset %02x = %02x", PORT_CONTROL, data));
1255   }
1297   case ATTN:
1298      LOG2(("write_control_port %02x - Soft Reset", data));
1299      // TODO: soft reset
1300      break;
12561301
1257   m_status = (m_status & ~DIR_) | (data & DIR_);
1258
1259   switch (data & HSF_PCB_MASK)
1260   {
1261   case HSF_PCB_ACK: // HSF1
1262      if (m_wait_for_ack)
1302   case FLSH:
1303      LOG2(("write_control_port %02x - Flush Data Register", data));
1304      // flush data register
1305      if (data & DIR_)
12631306      {
1264         set_command_pending(0);
1307         m_status &= ~HRDY; /* data register not ready */
12651308      }
1266      break;
1267   case HSF_PCB_NAK: // HSF2
1268      if (m_microcode_running)
1309      else
12691310      {
1270         m_status = (m_status & ~ASF_PCB_MASK) | ASF_PCB_ACK;
1311         // download to adapter
1312         m_status |= HRDY; /* data register ready */
1313
1314         // flush data register (reset tx data fifo)
1315         // m_tx_data_length = 0;
1316         m_tx_data_buffer.reset();
12711317      }
12721318      break;
1273   case HSF_PCB_END: // (HSF2|HSF1)
1274      m_status &= ~(ATTN | DMAE | ASF_PCB_MASK);
1275      if (m_microcode_running)
1276      {
1277         m_status = (m_status & ~ASF_PCB_MASK) | ASF_PCB_ACK;
1278      }
1319
1320   case ATTN | FLSH:
1321      LOG2(("write_control_port %02x - Reset Adapter", data));
1322      device_reset();
12791323      break;
1280   default: // 0
1281      m_command_index = 0;
1282      m_status |= HCRE; /* command register empty */
12831324
1284      if (m_command_buffer[0] == CMD_MC_F9)
1325   case 0:
1326      LOG2(("write_control_port %02x", data));
1327
1328      // end reset
1329      if ((m_control & (ATTN | FLSH)) == (ATTN | FLSH))
12851330      {
1286         m_mc_f9_pending = 1;
1287//-         verbose = 2;
1331         m_status |= ASF_PCB_END;
1332         m_status |= HRDY; /* 20 byte data fifo is empty */
12881333      }
12891334
1290      if (data == 0x00)
1335      if (data == DIR_)
12911336      {
1292         // hardware reset
1337         // why?? dex ether 20 expects HRDY
12931338         m_status |= HRDY; /* data register ready */
1294         // flush data register (reset tx data fifo)
1295         m_tx_data_length = 0;
1296         // FIXME: Don't do this (but why?)
1297         // m_tx_data_buffer.reset();
12981339      }
1299      else if (data == DIR_)
1340      break;
1341   }
1342
1343   // propagate DIR_ from Control to Status register
1344   m_status = (m_status & ~DIR_) | (data & DIR_);
1345
1346   switch (data & HSF_PCB_MASK)
1347   {
1348   case HSF_PCB_ACK: // HSF1
1349      if (m_wait_for_ack)
13001350      {
1301         // why?? dex ether 20 expects HRDY
1302         // m_status &= ~HRDY; /* data register not ready */
1303         m_status |= HRDY; /* data register ready */
1351         set_command_pending(0);
13041352      }
1305      else if (data & FLSH)
1353      break;
1354
1355   case HSF_PCB_END: // (HSF2|HSF1)
1356      m_status &= ~ACRF; /* adapter command register is not full */
1357      // fall through
1358
1359   case HSF_PCB_NAK: // HSF2
1360      if (m_microcode_running)
13061361      {
1307         if (data & DIR_)
1362         if (m_wait_for_nak)
13081363         {
1309            m_status &= ~HRDY; /* data register not ready */
1364            set_command_pending(0);
13101365         }
1311         else
1312         {
1313            // flush data register (reset tx data fifo)
1314//              m_tx_data_length = 0;
1315            m_tx_data_buffer.reset();
1316            m_status |= HRDY; /* data register ready */
1317         }
1366         m_status = (m_status & ~ASF_PCB_MASK) | ASF_PCB_ACK;
13181367      }
13191368      break;
1320   }
13211369
1322   if ((m_control & (ATTN | FLSH)) == (ATTN | FLSH) && (data & (ATTN | FLSH)) == 0)
1323   {
1324      m_status |= ASF_PCB_END;
1370   default: // 0
1371      m_command_index = 0;
1372      m_status |= HCRE; /* host command register is empty */
1373      break;
13251374   }
13261375
1327   if (m_mc_f9_pending == 2)
1328   {
1329      m_mc_f9_pending = 0;
1330      set_command_pending(0);
1331   }
1332
13331376   m_control = data;
13341377}
13351378
1379/***************************************************************************
1380 read_status_port
1381 ***************************************************************************/
1382
13361383UINT8 threecom3c505_device::read_status_port()
13371384{
13381385   UINT8 data = m_status;
13391386   m_status &= ~ASF_PCB_MASK;
13401387
1341   switch (data & ASF_PCB_MASK) {
1388   switch (data & ASF_PCB_MASK)
1389   {
13421390   case ASF_PCB_END:
13431391      m_status |= ASF_PCB_ACK;
13441392      break;
r21731r21732
13461394   return data;
13471395}
13481396
1397/***************************************************************************
1398 write_port
1399 ***************************************************************************/
1400
13491401void threecom3c505_device::write_port(offs_t offset, UINT8 data)
13501402{
13511403   m_reg[offset & 0x0f] = data;
r21731r21732
13701422   }
13711423}
13721424
1425/***************************************************************************
1426 read_port
1427 ***************************************************************************/
1428
13731429//READ8_DEVICE_HANDLER( threecom3c505_r )
13741430UINT8 threecom3c505_device::read_port(offs_t offset)
13751431{
r21731r21732
13841440      data = read_command_port();
13851441      break;
13861442   case PORT_STATUS: /* 0x02 read only, 8-bit */
1387      data=read_status_port();
1443      data = read_status_port();
13881444
1389      set_interrupt(CLEAR_LINE);
1390
13911445      // omit excessive logging
13921446      if (data == last_data)
13931447      {
13941448         UINT32 pc = machine().device(MAINCPU)->safe_pcbase();
1395         if (pc == last_pc) {
1449         if (pc == last_pc)
1450         {
13961451            return data;
13971452         }
13981453         last_pc = pc;
r21731r21732
14051460      data = read_data_port();
14061461      break;
14071462   case PORT_CONTROL: /* 0x06 read/write, 8-bit */
1408      // just return current value
1463      data = m_control;
14091464      break;
14101465   default:
14111466      break;
r21731r21732
14311486
14321487int threecom3c505_receive(device_t *device, const UINT8 data[], int length)
14331488{
1434      downcast<threecom3c505_device *> (device)->recv_cb((UINT8 *)data,length);
1435      return 1;
1489   downcast<threecom3c505_device *> (device)->recv_cb((UINT8 *) data, length);
1490   return 1;
14361491}
14371492
14381493void threecom3c505_set_verbose(int on_off)

Previous 199869 Revisions Next


© 1997-2024 The MAME Team