Previous 15994 Revisions Next

r9768 Monday 13th December, 2010 at 16:23:14 UTC by Curt Coder
[QL] Refactored ZX8302 to a C++ device.
[src/mess/drivers]ql.c
[src/mess/includes]ql.h
[src/mess/machine]zx8302.c zx8302.h

src/mess/machine/zx8302.c
r9767r9768
99
1010/*
1111
12    TODO:
12   TODO:
1313
14    - microdrive
15    - RTC register write
16    - serial data latching?
17    - transmit interrupt timing
18    - interface interrupt
14   - set time
15   - read from microdrive
16   - write to microdrive
17   - DTR/CTS handling
18   - network
1919
2020*/
2121
2222#include "emu.h"
23#include "zx8302.h"
24#include "devices/microdrv.h"
2523#include <time.h>
24#include "devices/microdrv.h"
25#include "machine/devhelpr.h"
26#include "zx8302.h"
2627
27/***************************************************************************
28    PARAMETERS
29***************************************************************************/
3028
29
30//**************************************************************************
31//   MACROS / CONSTANTS
32//**************************************************************************
33
3134#define LOG 0
3235
36
37// IPC serial state
3338enum
3439{
35   ZX8302_IPC_START,
36   ZX8302_IPC_DATA,
37   ZX8302_IPC_STOP
40   IPC_START,
41   IPC_DATA,
42   IPC_STOP
3843};
3944
40#define ZX8302_BAUD_19200   0x00
41#define ZX8302_BAUD_9600   0x01
42#define ZX8302_BAUD_4800   0x02
43#define ZX8302_BAUD_2400   0x03
44#define ZX8302_BAUD_1200   0x04
45#define ZX8302_BAUD_600      0x05
46#define ZX8302_BAUD_300      0x06
47#define ZX8302_BAUD_75      0x07
48#define ZX8302_BAUD_MASK   0x07
4945
50#define ZX8302_MODE_SER1   0x00
51#define ZX8302_MODE_SER2   0x08
52#define ZX8302_MODE_MDV      0x10
53#define ZX8302_MODE_NET      0x18
54#define ZX8302_MODE_MASK   0x18
46// baud rate
47static const int BAUD_19200            = 0x00;
48static const int BAUD_9600            = 0x01;
49static const int BAUD_4800            = 0x02;
50static const int BAUD_2400            = 0x03;
51static const int BAUD_1200            = 0x04;
52static const int BAUD_600            = 0x05;
53static const int BAUD_300            = 0x06;
54static const int BAUD_75            = 0x07;
55static const int BAUD_MASK            = 0x07;
5556
56#define ZX8302_INT_GAP         0x01
57#define ZX8302_INT_INTERFACE   0x02
58#define ZX8302_INT_TRANSMIT      0x04
59#define ZX8302_INT_FRAME      0x08
60#define ZX8302_INT_EXTERNAL      0x10
6157
62#define ZX8302_STATUS_NETWORK_PORT      0x01
63#define ZX8302_STATUS_TX_BUFFER_FULL   0x02
64#define ZX8302_STATUS_RX_BUFFER_FULL   0x04
65#define ZX8302_STATUS_MICRODRIVE_GAP   0x08
58// transmit mode
59static const int MODE_SER1            = 0x00;
60static const int MODE_SER2            = 0x08;
61static const int MODE_MDV            = 0x10;
62static const int MODE_NET            = 0x18;
63static const int MODE_MASK            = 0x18;
6664
67#define ZX8302_TXD_START   0
68#define ZX8302_TXD_STOP      9
69#define ZX8302_TXD_STOP2   10
7065
71/***************************************************************************
72    TYPE DEFINITIONS
73***************************************************************************/
66// interrupts
67static const int INT_GAP            = 0x01;
68static const int INT_INTERFACE         = 0x02;
69static const int INT_TRANSMIT         = 0x04;
70static const int INT_FRAME            = 0x08;
71static const int INT_EXTERNAL         = 0x10;
7472
75typedef struct _zx8302_t zx8302_t;
76struct _zx8302_t
77{
78   devcb_resolved_write_line   out_ipl1l_func;
79   devcb_resolved_write_line   out_baudx4_func;
80   devcb_resolved_write_line   out_comdata_func;
8173
82   /* registers */
83   UINT8 idr;                  /* IPC data register */
84   UINT8 tcr;                  /* transfer control register */
85   UINT8 tdr;                  /* transfer data register */
86   UINT8 irq;                  /* interrupt register */
87   UINT32 ctr;                  /* counter register */
88   UINT8 status;               /* status register */
74// status register
75static const int STATUS_NETWORK_PORT   = 0x01;
76static const int STATUS_TX_BUFFER_FULL   = 0x02;
77static const int STATUS_RX_BUFFER_FULL   = 0x04;
78static const int STATUS_MICRODRIVE_GAP   = 0x08;
8979
90   /* IPC communication state */
91   int comdata;               /* communication data */
92   int comctl;                  /* communication control */
93   int ipc_state;               /* communication state */
94   int ipc_rx;                  /* receiving data from IPC */
95   int ipc_busy;               /* IPC busy */
96   int baudx4;                  /* IPC baud x4 */
9780
98   /* serial transmit state */
99   int tx_bits;               /* bits transmitted */
100   int ser1_rxd;               /* serial 1 receive */
101   int ser1_cts;               /* serial 1 clear to send */
102   int ser2_txd;               /* serial 2 transmit */
103   int ser2_dtr;               /* serial 2 data terminal ready */
104   int netout;                  /* ZXNet output */
105   int netin;                  /* ZXNet input */
81// transmit bits
82static const int TXD_START            = 0;
83static const int TXD_STOP            = 9;
84static const int TXD_STOP2            = 10;
10685
107   /* microdrive state */
108   int mdrdw;                  /* read/write */
109   int mdselck;               /* select clock */
110   int mdseld;                  /* select data */
111   int erase;                  /* erase head */
11286
113   int mdv_motor;               /* selected motor */
114   int mdv_offset[8];            /* image offset */
87// Monday 1st January 1979 00:00:00 UTC
88static const int RTC_BASE_ADJUST      = 283996800;
11589
116   UINT8 *mdv_image[8];         /* image */
11790
118   /* timers */
119   emu_timer *txd_timer;         /* transmit timer */
120   emu_timer *ipc_timer;         /* baud x4 timer */
121   emu_timer *rtc_timer;         /* real time clock timer */
122   emu_timer *gap_timer;         /* microdrive gap timer */
123};
12491
125/***************************************************************************
126    INLINE FUNCTIONS
127***************************************************************************/
92//**************************************************************************
93//  DEVICE DEFINITIONS
94//**************************************************************************
12895
129INLINE zx8302_t *get_safe_token(running_device *device)
130{
131   assert(device != NULL);
96const device_type ZX8302 = zx8302_device_config::static_alloc_device_config;
13297
133   return (zx8302_t *)downcast<legacy_device_base *>(device)->token();
134}
13598
136INLINE const zx8302_interface *get_interface(running_device *device)
137{
138   assert(device != NULL);
139   assert((device->type() == ZX8302));
140   return (const zx8302_interface *) device->baseconfig().static_config();
141}
14299
143/***************************************************************************
144    IMPLEMENTATION
145***************************************************************************/
100//**************************************************************************
101//  DEVICE CONFIGURATION
102//**************************************************************************
146103
147/*-------------------------------------------------
148    zx8302_interrupt - interrupt line manager
149-------------------------------------------------*/
104GENERIC_DEVICE_CONFIG_SETUP(zx8302, "Sinclair ZX8302")
150105
151static void zx8302_interrupt(running_device *device, UINT8 line)
152{
153   zx8302_t *zx8302 = get_safe_token(device);
154106
155   zx8302->irq |= line;
156   devcb_call_write_line(&zx8302->out_ipl1l_func, ASSERT_LINE);
157}
107//-------------------------------------------------
108//  device_config_complete - perform any
109//  operations now that the configuration is
110//  complete
111//-------------------------------------------------
158112
159/*-------------------------------------------------
160    zx8302_irq_status_r - interrupt status
161    register
162-------------------------------------------------*/
163
164READ8_DEVICE_HANDLER( zx8302_irq_status_r )
113void zx8302_device_config::device_config_complete()
165114{
166   zx8302_t *zx8302 = get_safe_token(device);
115   // inherit a copy of the static data
116   const zx8302_interface *intf = reinterpret_cast<const zx8302_interface *>(static_config());
117   if (intf != NULL)
118      *static_cast<zx8302_interface *>(this) = *intf;
167119
168   return zx8302->irq;
120   // or initialize to defaults if none provided
121   else
122   {
123      memset(&out_ipl1l_func, 0, sizeof(out_ipl1l_func));
124      memset(&out_baudx4_func, 0, sizeof(out_baudx4_func));
125      memset(&out_comdata_func, 0, sizeof(out_comdata_func));
126      memset(&out_txd1_func, 0, sizeof(out_txd1_func));
127      memset(&out_txd2_func, 0, sizeof(out_txd2_func));
128      memset(&in_dtr1_func, 0, sizeof(in_dtr1_func));
129      memset(&in_cts2_func, 0, sizeof(in_cts2_func));
130      memset(&out_netout_func, 0, sizeof(out_netout_func));
131      memset(&in_netin_func, 0, sizeof(in_netin_func));
132   }
169133}
170134
171/*-------------------------------------------------
172    zx8302_irq_acknowledge_w - interrupt
173    acknowledge
174-------------------------------------------------*/
175135
176WRITE8_DEVICE_HANDLER( zx8302_irq_acknowledge_w )
177{
178   zx8302_t *zx8302 = get_safe_token(device);
179136
180   zx8302->irq &= ~data;
137//**************************************************************************
138//  INLINE HELPERS
139//**************************************************************************
181140
182   if (LOG) logerror("ZX8302 Interrupt Acknowledge: %02x\n", data);
141//-------------------------------------------------
142//  trigger_interrupt -
143//-------------------------------------------------
183144
184   if (!zx8302->irq)
185   {
186      devcb_call_write_line(&zx8302->out_ipl1l_func, CLEAR_LINE);
187   }
188}
189
190/*-------------------------------------------------
191    TIMER_CALLBACK( zx8302_ipc_tick )
192-------------------------------------------------*/
193
194static TIMER_CALLBACK( zx8302_ipc_tick )
145inline void zx8302_device::trigger_interrupt(UINT8 line)
195146{
196   zx8302_t *zx8302 = get_safe_token((running_device *)ptr);
147   m_irq |= line;
197148
198   zx8302->baudx4 = !zx8302->baudx4;
199   devcb_call_write_line(&zx8302->out_baudx4_func, zx8302->baudx4);
149   devcb_call_write_line(&m_out_ipl1l_func, ASSERT_LINE);
200150}
201151
202/*-------------------------------------------------
203    zx8302_ipc_comm_tick - IPC serial transfer
204-------------------------------------------------*/
205152
206static void zx8302_ipc_comm_tick(running_device *device)
153//-------------------------------------------------
154//  transmit_ipc_data - transmit IPC data
155//-------------------------------------------------
156
157inline void zx8302_device::transmit_ipc_data()
207158{
208159   /*
209160
r9767r9768
230181
231182    */
232183
233   zx8302_t *zx8302 = get_safe_token(device);
234
235   switch (zx8302->ipc_state)
184   switch (m_ipc_state)
236185   {
237   case ZX8302_IPC_START:
238      if (LOG) logerror("ZX8302 COMDATA START W: %x\n", 0);
186   case IPC_START:
187      if (LOG) logerror("ZX8302 '%s' COMDATA Start Bit\n", tag());
239188
240      devcb_call_write_line(&zx8302->out_comdata_func, 0);
241      zx8302->ipc_busy = 1;
242      zx8302->ipc_state = ZX8302_IPC_DATA;
189      devcb_call_write_line(&m_out_comdata_func, 0);
190      m_ipc_busy = 1;
191      m_ipc_state = IPC_DATA;
243192      break;
244193
245   case ZX8302_IPC_DATA:
246      if (LOG) logerror("ZX8302 COMDATA W: %x\n", BIT(zx8302->idr, 1));
194   case IPC_DATA:
195      if (LOG) logerror("ZX8302 '%s' COMDATA Data Bit: %x\n", tag(), BIT(m_idr, 1));
247196
248      zx8302->comdata = BIT(zx8302->idr, 1);
249      devcb_call_write_line(&zx8302->out_comdata_func, zx8302->comdata);
250      zx8302->ipc_state = ZX8302_IPC_STOP;
197      m_comdata = BIT(m_idr, 1);
198      devcb_call_write_line(&m_out_comdata_func, m_comdata);
199      m_ipc_state = IPC_STOP;
251200      break;
252201
253   case ZX8302_IPC_STOP:
254      if (!zx8302->ipc_rx)
202   case IPC_STOP:
203      if (!m_ipc_rx)
255204      {
256         if (LOG) logerror("ZX8302 COMDATA STOP W: %x\n", 1);
205         if (LOG) logerror("ZX8302 '%s' COMDATA Stop Bit\n", tag());
257206
258         devcb_call_write_line(&zx8302->out_comdata_func, 1);
259         zx8302->ipc_busy = 0;
260         zx8302->ipc_state = ZX8302_IPC_START;
207         devcb_call_write_line(&m_out_comdata_func, 1);
208         m_ipc_busy = 0;
209         m_ipc_state = IPC_START;
261210      }
262211      break;
263212   }
264213}
265214
266/*-------------------------------------------------
267    zx8302_comctl_w - IPC COMCTL accessor
268-------------------------------------------------*/
269215
270WRITE_LINE_DEVICE_HANDLER( zx8302_comctl_w )
271{
272   if (LOG) logerror("IPC COMCTL W: %x\n", state);
216//-------------------------------------------------
217//  transmit_bit - transmit serial bit
218//-------------------------------------------------
273219
274   if (state == 1)
275   {
276      zx8302_ipc_comm_tick(device);
277   }
278}
279
280/*-------------------------------------------------
281    zx8302_comctl_w - IPC COMDATA accessor
282-------------------------------------------------*/
283
284WRITE_LINE_DEVICE_HANDLER( zx8302_comdata_w )
220inline void zx8302_device::transmit_bit(int state)
285221{
286   zx8302_t *zx8302 = get_safe_token(device);
287
288   if (LOG) logerror("IPC COMDATA W: %x\n", state);
289
290   if (zx8302->ipc_state == ZX8302_IPC_DATA || zx8302->ipc_state == ZX8302_IPC_STOP)
222   switch (m_tcr & MODE_MASK)
291223   {
292      if (zx8302->ipc_rx)
293      {
294         zx8302->ipc_rx = 0;
295         zx8302->ipc_busy = 0;
296         zx8302->ipc_state = ZX8302_IPC_START;
297      }
298      else
299      {
300         zx8302->ipc_rx = 1;
301         zx8302->comdata = state;
302      }
303   }
304}
305
306/*-------------------------------------------------
307    TIMER_CALLBACK( zx8302_delayed_ipc_command )
308-------------------------------------------------*/
309
310static TIMER_CALLBACK( zx8302_delayed_ipc_command )
311{
312   zx8302_t *zx8302 = get_safe_token((running_device *)ptr);
313
314   zx8302->idr = param;
315   zx8302->ipc_state = ZX8302_IPC_START;
316   zx8302->ipc_rx = 0;
317
318   zx8302_ipc_comm_tick((running_device *)ptr);
319}
320
321/*-------------------------------------------------
322    zx8302_ipc_command_w - IPC command register
323-------------------------------------------------*/
324
325WRITE8_DEVICE_HANDLER( zx8302_ipc_command_w )
326{
327   if (LOG) logerror("ZX8302 IPC Command: %02x\n", data);
328
329   if (data != 0x01)
330   {
331      timer_set(device->machine,ATTOTIME_IN_NSEC(480), (void *) device, data, zx8302_delayed_ipc_command);
332   }
333}
334
335/*-------------------------------------------------
336    zx8302_txd - IPC serial transmit
337-------------------------------------------------*/
338
339static WRITE_LINE_DEVICE_HANDLER( zx8302_txd )
340{
341   zx8302_t *zx8302 = get_safe_token(device);
342
343   switch (zx8302->tcr & ZX8302_MODE_MASK)
344   {
345   case ZX8302_MODE_SER1:
346      zx8302->ser1_rxd = state;
224   case MODE_SER1:
225      devcb_call_write_line(&m_out_txd1_func, state);
347226      break;
348227
349   case ZX8302_MODE_SER2:
350      zx8302->ser2_txd = state;
228   case MODE_SER2:
229      devcb_call_write_line(&m_out_txd2_func, state);
351230      break;
352231
353   case ZX8302_MODE_MDV:
232   case MODE_MDV:
354233      // TODO
355234      break;
356235
357   case ZX8302_MODE_NET:
358      zx8302->netout = state;
236   case MODE_NET:
237      devcb_call_write_line(&m_out_netout_func, state);
359238      break;
360239   }
361240}
362241
363/*-------------------------------------------------
364    TIMER_CALLBACK( zx8302_txd_tick )
365-------------------------------------------------*/
366242
367static TIMER_CALLBACK( zx8302_txd_tick )
368{
369   zx8302_t *zx8302 = get_safe_token((running_device *)ptr);
243//-------------------------------------------------
244//  transmit_data - transmit serial data
245//-------------------------------------------------
370246
371   switch (zx8302->tx_bits)
247inline void zx8302_device::transmit_serial_data()
248{
249   switch (m_tx_bits)
372250   {
373   case ZX8302_TXD_START:
374      if (!(zx8302->irq & ZX8302_INT_TRANSMIT))
251   case TXD_START:
252      if (!(m_irq & INT_TRANSMIT))
375253      {
376         zx8302_txd((running_device *)ptr, 0);
377         zx8302->tx_bits++;
254         transmit_bit(0);
255         m_tx_bits++;
378256      }
379257      break;
380258
381259   default:
382      zx8302_txd((running_device *)ptr, BIT(zx8302->tdr, 0));
383      zx8302->tdr >>= 1;
384      zx8302->tx_bits++;
260      transmit_bit(BIT(m_tdr, 0));
261      m_tdr >>= 1;
262      m_tx_bits++;
385263      break;
386264
387   case ZX8302_TXD_STOP:
388      zx8302_txd((running_device *)ptr, 1);
389      zx8302->tx_bits++;
265   case TXD_STOP:
266      transmit_bit(1);
267      m_tx_bits++;
390268      break;
391269
392   case ZX8302_TXD_STOP2:
393      zx8302_txd((running_device *)ptr, 1);
394      zx8302->tx_bits = ZX8302_TXD_START;
395      zx8302->status &= ~ZX8302_STATUS_TX_BUFFER_FULL;
396      zx8302_interrupt((running_device *)ptr, ZX8302_INT_TRANSMIT);
270   case TXD_STOP2:
271      transmit_bit(1);
272      m_tx_bits = TXD_START;
273      m_status &= ~STATUS_TX_BUFFER_FULL;
274      trigger_interrupt(INT_TRANSMIT);
397275      break;
398276   }
399277}
400278
401/*-------------------------------------------------
402    zx8302_data_w - transmit data register
403-------------------------------------------------*/
404279
405WRITE8_DEVICE_HANDLER( zx8302_data_w )
406{
407   zx8302_t *zx8302 = get_safe_token(device);
408280
409   if (LOG) logerror("ZX8302 Data Register: %02x\n", data);
281//**************************************************************************
282//  LIVE DEVICE
283//**************************************************************************
410284
411   zx8302->tdr = data;
412   zx8302->status |= ZX8302_STATUS_TX_BUFFER_FULL;
285//-------------------------------------------------
286//  zx8302_device - constructor
287//-------------------------------------------------
288
289zx8302_device::zx8302_device(running_machine &_machine, const zx8302_device_config &config)
290    : device_t(_machine, config),
291     m_idr(1),
292     m_irq(0),
293     m_ctr(time(NULL) + RTC_BASE_ADJUST),
294     m_status(0),
295     m_comdata(1),
296     m_comctl(1),
297     m_ipc_state(0),
298     m_ipc_rx(0),
299     m_ipc_busy(0),
300     m_track(0),
301      m_config(config)
302{
413303}
414304
415/*-------------------------------------------------
416    zx8302_control_w - serial control register
417-------------------------------------------------*/
418305
419WRITE8_DEVICE_HANDLER( zx8302_control_w )
306//-------------------------------------------------
307//  device_start - device-specific startup
308//-------------------------------------------------
309
310void zx8302_device::device_start()
420311{
421   zx8302_t *zx8302 = get_safe_token(device);
312   // resolve callbacks
313   devcb_resolve_write_line(&m_out_ipl1l_func, &m_config.out_ipl1l_func, this);
314   devcb_resolve_write_line(&m_out_baudx4_func, &m_config.out_baudx4_func, this);
315   devcb_resolve_write_line(&m_out_comdata_func, &m_config.out_comdata_func, this);
316   devcb_resolve_write_line(&m_out_txd1_func, &m_config.out_txd1_func, this);
317   devcb_resolve_write_line(&m_out_txd2_func, &m_config.out_txd2_func, this);
318   devcb_resolve_read_line(&m_in_dtr1_func, &m_config.in_dtr1_func, this);
319   devcb_resolve_read_line(&m_in_cts2_func, &m_config.in_cts2_func, this);
320   devcb_resolve_write_line(&m_out_netout_func, &m_config.out_netout_func, this);
321   devcb_resolve_read_line(&m_in_netin_func, &m_config.in_netin_func, this);
422322
423   int baud = (19200 >> (data & ZX8302_BAUD_MASK));
424   int baudx4 = baud * 4;
323   // allocate timers
324   m_txd_timer = device_timer_alloc(*this, TIMER_TXD);
325   m_baudx4_timer = device_timer_alloc(*this, TIMER_BAUDX4);
326   m_rtc_timer = device_timer_alloc(*this, TIMER_RTC);
327   m_gap_timer = device_timer_alloc(*this, TIMER_GAP);
328   m_ipc_timer = device_timer_alloc(*this, TIMER_IPC);
425329
426   if (LOG) logerror("ZX8302 Transmit Control Register: %02x\n", data);
330   timer_adjust_periodic(m_rtc_timer, attotime_zero, 0, ATTOTIME_IN_HZ(m_config.rtc_clock / 32768));
331   timer_adjust_periodic(m_gap_timer, attotime_zero, 0, ATTOTIME_IN_MSEC(31));
427332
428   zx8302->tcr = data;
429
430   timer_adjust_periodic(zx8302->txd_timer, attotime_zero, 0, ATTOTIME_IN_HZ(baud));
431   timer_adjust_periodic(zx8302->ipc_timer, attotime_zero, 0, ATTOTIME_IN_HZ(baudx4));
333   // register for state saving
334   state_save_register_device_item(this, 0, m_idr);
335   state_save_register_device_item(this, 0, m_tcr);
336   state_save_register_device_item(this, 0, m_tdr);
337   state_save_register_device_item(this, 0, m_irq);
338   state_save_register_device_item(this, 0, m_ctr);
339   state_save_register_device_item(this, 0, m_status);
340   state_save_register_device_item(this, 0, m_comdata);
341   state_save_register_device_item(this, 0, m_comctl);
342   state_save_register_device_item(this, 0, m_ipc_state);
343   state_save_register_device_item(this, 0, m_ipc_rx);
344   state_save_register_device_item(this, 0, m_ipc_busy);
345   state_save_register_device_item(this, 0, m_baudx4);
346   state_save_register_device_item(this, 0, m_tx_bits);
347   state_save_register_device_item(this, 0, m_mdrdw);
348   state_save_register_device_item(this, 0, m_mdselck);
349   state_save_register_device_item(this, 0, m_mdseld);
350   state_save_register_device_item(this, 0, m_erase);
351   state_save_register_device_item(this, 0, m_mdv_motor);
352   state_save_register_device_item_array(this, 0, m_mdv_data);
353   state_save_register_device_item(this, 0, m_track);
432354}
433355
434/*-------------------------------------------------
435    TIMER_CALLBACK( zx8302_rtc_tick )
436-------------------------------------------------*/
437356
438static TIMER_CALLBACK( zx8302_rtc_tick )
357//-------------------------------------------------
358//  device_timer - handler timer events
359//-------------------------------------------------
360
361void zx8302_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
439362{
440   zx8302_t *zx8302 = get_safe_token((running_device *)ptr);
363   switch (id)
364   {
365   case TIMER_TXD:
366      transmit_serial_data();
367      break;
441368
442   zx8302->ctr++;
369   case TIMER_BAUDX4:
370      m_baudx4 = !m_baudx4;
371      devcb_call_write_line(&m_out_baudx4_func, m_baudx4);
372      break;
373
374   case TIMER_RTC:
375      m_ctr++;
376      break;
377
378   case TIMER_GAP:
379      if (m_mdv_motor)
380      {
381         trigger_interrupt(INT_GAP);
382      }
383      break;
384
385   case TIMER_IPC:
386      m_idr = param;
387      m_ipc_state = IPC_START;
388      m_ipc_rx = 0;
389
390      transmit_ipc_data();
391      break;
392   }
443393}
444394
445/*-------------------------------------------------
446    zx8302_rtc_r - clock register read
447-------------------------------------------------*/
448395
449READ8_DEVICE_HANDLER( zx8302_rtc_r )
396//-------------------------------------------------
397//  rtc_r - real time clock read
398//-------------------------------------------------
399
400READ8_MEMBER( zx8302_device::rtc_r )
450401{
451   zx8302_t *zx8302 = get_safe_token(device);
402   UINT8 data = 0;
452403
453404   switch (offset)
454405   {
455406   case 0:
456      return (zx8302->ctr >> 24) & 0xff;
407      data = (m_ctr >> 24) & 0xff;
457408   case 1:
458      return (zx8302->ctr >> 16) & 0xff;
409      data = (m_ctr >> 16) & 0xff;
459410   case 2:
460      return (zx8302->ctr >> 8) & 0xff;
411      data = (m_ctr >> 8) & 0xff;
461412   case 3:
462      return zx8302->ctr;
413      data = m_ctr & 0xff;
463414   }
464415
465   return 0;
416   return data;
466417}
467418
468/*-------------------------------------------------
469    zx8302_rtc_w - clock register write
470-------------------------------------------------*/
471419
472WRITE8_DEVICE_HANDLER( zx8302_rtc_w )
473{
474//  zx8302_t *zx8302 = get_safe_token(device);
420//-------------------------------------------------
421//  rtc_w - real time clock write
422//-------------------------------------------------
475423
476   if (LOG) logerror("ZX8302 Real Time Clock Register: %02x\n", data);
424WRITE8_MEMBER( zx8302_device::rtc_w )
425{
426   if (LOG) logerror("ZX8302 '%s' Set Real Time Clock: %02x\n", tag(), data);
477427}
478428
479/*-------------------------------------------------
480    TIMER_CALLBACK( zx8302_gap_tick )
481-------------------------------------------------*/
482429
483static TIMER_CALLBACK( zx8302_gap_tick )
430//-------------------------------------------------
431//  control_w - serial transmit clock
432//-------------------------------------------------
433
434WRITE8_MEMBER( zx8302_device::control_w )
484435{
485   zx8302_t *zx8302 = get_safe_token((running_device *)ptr);
436   if (LOG) logerror("ZX8302 '%s' Transmit Control: %02x\n", tag(), data);
486437
487   if (zx8302->mdv_motor)
488   {
489      zx8302_interrupt((running_device *)ptr, ZX8302_INT_GAP);
490   }
438   int baud = (19200 >> (data & BAUD_MASK));
439   int baudx4 = baud * 4;
440
441   m_tcr = data;
442
443   timer_adjust_periodic(m_txd_timer, attotime_zero, 0, ATTOTIME_IN_HZ(baud));
444   timer_adjust_periodic(m_baudx4_timer, attotime_zero, 0, ATTOTIME_IN_HZ(baudx4));
491445}
492446
493/*-------------------------------------------------
494    zx8302_get_selected_microdrive - gets the
495    index of the selected microdrive
496-------------------------------------------------*/
497447
498static int zx8302_get_selected_microdrive(running_device *device)
448//-------------------------------------------------
449//  mdv_track_r - microdrive track data
450//-------------------------------------------------
451
452READ8_MEMBER( zx8302_device::mdv_track_r )
499453{
500   zx8302_t *zx8302 = get_safe_token(device);
454   if (LOG) logerror("ZX8302 '%s' Microdrive Track %u: %02x\n", tag(), m_track, m_mdv_data[m_track]);
501455
502 int i;
456   UINT8 data = m_mdv_data[m_track];
503457
504    for (i = 0; i < 8; i++)
505    {
506        if (BIT(zx8302->mdv_motor, i)) return 7 - i;
507    }
458   m_track = !m_track;
508459
509    return 0;
460   return data;
510461}
511462
512/*-------------------------------------------------
513    zx8302_get_microdrive_status - gets the
514    status of the selected microdrive
515-------------------------------------------------*/
516463
517static UINT8 zx8302_get_microdrive_status(running_device *device)
464//-------------------------------------------------
465//  status_r - status register
466//-------------------------------------------------
467
468READ8_MEMBER( zx8302_device::status_r )
518469{
519   zx8302_t *zx8302 = get_safe_token(device);
470   /*
520471
521   int drive = zx8302_get_selected_microdrive(device);
522   UINT8 status = 0;
472        bit     description
523473
524   if (zx8302->mdv_motor)
525   {
526      switch (zx8302->mdv_offset[drive] % MDV_SECTOR_LENGTH)
527      {
528      case MDV_OFFSET_HEADER_PREAMBLE:
529         zx8302->status &= ~ZX8302_STATUS_MICRODRIVE_GAP;
530         zx8302->mdv_offset[drive] += MDV_PREAMBLE_LENGTH;
531         break;
474        0       Network port
475        1       Transmit buffer full
476        2       Receive buffer full
477        3       Microdrive GAP
478        4       SER1 DTR
479        5       SER2 CTS
480        6       IPC busy
481        7       COMDATA
532482
533      case MDV_OFFSET_HEADER:
534         zx8302->status |= ZX8302_STATUS_RX_BUFFER_FULL;
535         break;
483    */
536484
537      case MDV_OFFSET_DATA_PREAMBLE:
538         zx8302->status &= ~ZX8302_STATUS_RX_BUFFER_FULL;
539         zx8302->mdv_offset[drive] += MDV_PREAMBLE_LENGTH;
540         break;
485   UINT8 data = 0;
541486
542      case MDV_OFFSET_DATA:
543         zx8302->status |= ZX8302_STATUS_RX_BUFFER_FULL;
544         break;
487   // TODO network port
545488
546      case MDV_OFFSET_GAP:
547         zx8302->status &= ~ZX8302_STATUS_RX_BUFFER_FULL;
548         zx8302->status |= ZX8302_STATUS_MICRODRIVE_GAP;
549         zx8302->mdv_offset[drive] += MDV_GAP_LENGTH;
550         break;
551      }
552   }
489   // serial status
490   data |= m_status;
553491
554   return status;
555}
492   // TODO microdrive GAP
556493
557/*-------------------------------------------------
558    zx8302_mdv_track_r - microdrive data register
559-------------------------------------------------*/
494   // data terminal ready
495   data |= devcb_call_read_line(&m_in_dtr1_func) << 4;
560496
561READ8_DEVICE_HANDLER( zx8302_mdv_track_r )
562{
563   zx8302_t *zx8302 = get_safe_token(device);
497   // clear to send
498   data |= devcb_call_read_line(&m_in_cts2_func) << 5;
564499
565   int drive = zx8302_get_selected_microdrive(device);
566   UINT8 data = zx8302->mdv_image[drive][zx8302->mdv_offset[drive]];
500   // IPC busy
501   data |= m_ipc_busy << 6;
567502
568   zx8302->mdv_offset[drive]++;
503   // COMDATA
504   data |= m_comdata << 7;
569505
570   if (zx8302->mdv_offset[drive] == MDV_IMAGE_LENGTH)
571   {
572      zx8302->mdv_offset[drive] = 0;
573   }
506   if (LOG) logerror("ZX8302 '%s' Status: %02x\n", tag(), data);
574507
575508   return data;
576509}
577510
578/*-------------------------------------------------
579    zx8302_mdv_control_w - microdrive control
580    register
581-------------------------------------------------*/
582511
583WRITE8_DEVICE_HANDLER( zx8302_mdv_control_w )
512//-------------------------------------------------
513//  ipc_command_w - IPC command
514//-------------------------------------------------
515
516WRITE8_MEMBER( zx8302_device::ipc_command_w )
584517{
585   zx8302_t *zx8302 = get_safe_token(device);
518   if (LOG) logerror("ZX8302 '%s' IPC Command: %02x\n", tag(), data);
586519
520   if (data != 0x01)
521   {
522      timer_adjust_oneshot(m_ipc_timer, ATTOTIME_IN_NSEC(480), data);
523   }
524}
525
526
527//-------------------------------------------------
528//  mdv_control_w - microdrive control
529//-------------------------------------------------
530
531WRITE8_MEMBER( zx8302_device::mdv_control_w )
532{
587533   /*
588534
589535        bit     description
r9767r9768
599545
600546    */
601547
602   if (LOG) logerror("ZX8302 Microdrive Control Register: %02x\n", data);
548   if (LOG) logerror("ZX8302 '%s' Microdrive Control: %02x\n", tag(), data);
603549
604   zx8302->mdseld = BIT(data, 0);
605   zx8302->mdselck = BIT(data, 1);
606   zx8302->mdrdw = BIT(data, 2) ? 0 : 1;
607   zx8302->erase = BIT(data, 3);
550   m_mdseld = BIT(data, 0);
551   m_mdselck = BIT(data, 1);
552   m_mdrdw = BIT(data, 2) ? 0 : 1;
553   m_erase = BIT(data, 3);
608554
609555   // Microdrive selection shift register
610
611   if (zx8302->mdselck)
556   if (m_mdselck)
612557   {
613      int drive = 0;
558      m_mdv_motor >>= 1;
559      m_mdv_motor |= (m_mdseld << 7);
614560
615      zx8302->mdv_motor >>= 1;
616      zx8302->mdv_motor |= (zx8302->mdseld << 7);
617
618      drive = zx8302_get_selected_microdrive(device);
619
620      zx8302->mdv_offset[drive] = 0;
621      zx8302->status &= ~ZX8302_STATUS_RX_BUFFER_FULL;
561      m_status &= ~STATUS_RX_BUFFER_FULL;
622562   }
623563}
624564
625/*-------------------------------------------------
626    zx8302_status_r - status register
627-------------------------------------------------*/
628565
629READ8_DEVICE_HANDLER( zx8302_status_r )
566//-------------------------------------------------
567//  irq_status_r - interrupt status
568//-------------------------------------------------
569
570READ8_MEMBER( zx8302_device::irq_status_r )
630571{
631   zx8302_t *zx8302 = get_safe_token(device);
572   if (LOG) logerror("ZX8302 '%s' Interrupt Status: %02x\n", tag(), m_irq);
632573
633   /*
574   return m_irq;
575}
634576
635        bit     description
636577
637        0       Network port
638        1       Transmit buffer full
639        2       Receive buffer full
640        3       Microdrive GAP
641        4       SER1 DTR
642        5       SER2 CTS
643        6       IPC busy
644        7       COMDATA
578//-------------------------------------------------
579//  irq_acknowledge_w - interrupt acknowledge
580//-------------------------------------------------
645581
646    */
582WRITE8_MEMBER( zx8302_device::irq_acknowledge_w )
583{
584   if (LOG) logerror("ZX8302 '%s' Interrupt Acknowledge: %02x\n", tag(), data);
647585
648   UINT8 data = 0;
586   m_irq &= ~data;
649587
650   data |= zx8302->comdata << 7;
651   data |= zx8302->ipc_busy << 6;
652   data |= zx8302->ser1_cts << 5;
653   data |= zx8302->ser2_dtr << 4;
654   data |= zx8302_get_microdrive_status(device);
655   data |= zx8302->status;
656
657   if (LOG) logerror("ZX8302 Status Register: %02x\n", data);
658
659   return data;
660}
661
662/*-------------------------------------------------
663    zx8302_vsync_w - vertical sync accessor
664-------------------------------------------------*/
665
666WRITE_LINE_DEVICE_HANDLER( zx8302_vsync_w )
667{
668   if (state)
588   if (!m_irq)
669589   {
670      zx8302_interrupt(device, ZX8302_INT_FRAME);
671      if (LOG) logerror("ZX8302 Frame Interrupt\n");
590      devcb_call_write_line(&m_out_ipl1l_func, CLEAR_LINE);
672591   }
673592}
674593
675/*-------------------------------------------------
676    DEVICE_START( zx8302 )
677-------------------------------------------------*/
678594
679static DEVICE_START( zx8302 )
595//-------------------------------------------------
596//  data_w - transmit buffer
597//-------------------------------------------------
598
599WRITE8_MEMBER( zx8302_device::data_w )
680600{
681   zx8302_t *zx8302 = get_safe_token(device);
682   const zx8302_interface *intf = get_interface(device);
683   int i;
601   if (LOG) logerror("ZX8302 '%s' Data Register: %02x\n", tag(), data);
684602
685   /* resolve callbacks */
686   devcb_resolve_write_line(&zx8302->out_ipl1l_func, &intf->out_ipl1l_func, device);
687   devcb_resolve_write_line(&zx8302->out_baudx4_func, &intf->out_baudx4_func, device);
688   devcb_resolve_write_line(&zx8302->out_comdata_func, &intf->out_comdata_func, device);
603   m_tdr = data;
604   m_status |= STATUS_TX_BUFFER_FULL;
605}
689606
690   /* set initial values */
691   zx8302->comctl = 1;
692   zx8302->comdata = 1;
693   zx8302->idr = 1;
694607
695   zx8302->ctr = time(NULL) + 283996800;
608//-------------------------------------------------
609//  vsync_w - vertical sync
610//-------------------------------------------------
696611
697   /* allocate microdrive images */
698   for (i = 0; i < 8; i++)
612WRITE_LINE_MEMBER( zx8302_device::vsync_w )
613{
614   if (state)
699615   {
700      zx8302->mdv_image[i] = auto_alloc_array(device->machine, UINT8, MDV_IMAGE_LENGTH);
616      if (LOG) logerror("ZX8302 '%s' Frame Interrupt\n", tag());
617
618      trigger_interrupt(INT_FRAME);
701619   }
620}
702621
703   /* create the timers */
704   zx8302->txd_timer = timer_alloc(device->machine, zx8302_txd_tick, (void *)device);
705   zx8302->ipc_timer = timer_alloc(device->machine, zx8302_ipc_tick, (void *)device);
706   zx8302->rtc_timer = timer_alloc(device->machine, zx8302_rtc_tick, (void *)device);
707   zx8302->gap_timer = timer_alloc(device->machine, zx8302_gap_tick, (void *)device);
708622
709   timer_adjust_periodic(zx8302->rtc_timer, attotime_zero, 0, ATTOTIME_IN_HZ(intf->rtc_clock/32768));
710   timer_adjust_periodic(zx8302->gap_timer, attotime_zero, 0, ATTOTIME_IN_MSEC(31));
623//-------------------------------------------------
624//  comctl_w - IPC COMCTL
625//-------------------------------------------------
711626
712   /* register for state saving */
627WRITE_LINE_MEMBER( zx8302_device::comctl_w )
628{
629   if (LOG) logerror("ZX8302 '%s' COMCTL: %x\n", tag(), state);
713630
714   state_save_register_item(device->machine, "zx8302", device->tag(), 0, zx8302->idr);
715   state_save_register_item(device->machine, "zx8302", device->tag(), 0, zx8302->tcr);
716   state_save_register_item(device->machine, "zx8302", device->tag(), 0, zx8302->tdr);
717   state_save_register_item(device->machine, "zx8302", device->tag(), 0, zx8302->irq);
718   state_save_register_item(device->machine, "zx8302", device->tag(), 0, zx8302->ctr);
719   state_save_register_item(device->machine, "zx8302", device->tag(), 0, zx8302->status);
720
721   state_save_register_item(device->machine, "zx8302", device->tag(), 0, zx8302->comdata);
722   state_save_register_item(device->machine, "zx8302", device->tag(), 0, zx8302->comctl);
723   state_save_register_item(device->machine, "zx8302", device->tag(), 0, zx8302->ipc_state);
724   state_save_register_item(device->machine, "zx8302", device->tag(), 0, zx8302->ipc_rx);
725   state_save_register_item(device->machine, "zx8302", device->tag(), 0, zx8302->ipc_busy);
726   state_save_register_item(device->machine, "zx8302", device->tag(), 0, zx8302->baudx4);
727
728   state_save_register_item(device->machine, "zx8302", device->tag(), 0, zx8302->tx_bits);
729   state_save_register_item(device->machine, "zx8302", device->tag(), 0, zx8302->ser1_rxd);
730   state_save_register_item(device->machine, "zx8302", device->tag(), 0, zx8302->ser1_cts);
731   state_save_register_item(device->machine, "zx8302", device->tag(), 0, zx8302->ser2_txd);
732   state_save_register_item(device->machine, "zx8302", device->tag(), 0, zx8302->ser2_dtr);
733   state_save_register_item(device->machine, "zx8302", device->tag(), 0, zx8302->netout);
734   state_save_register_item(device->machine, "zx8302", device->tag(), 0, zx8302->netin);
735
736   state_save_register_item(device->machine, "zx8302", device->tag(), 0, zx8302->mdrdw);
737   state_save_register_item(device->machine, "zx8302", device->tag(), 0, zx8302->mdselck);
738   state_save_register_item(device->machine, "zx8302", device->tag(), 0, zx8302->mdseld);
739   state_save_register_item(device->machine, "zx8302", device->tag(), 0, zx8302->erase);
740
741   state_save_register_item(device->machine, "zx8302", device->tag(), 0, zx8302->mdv_motor);
742   state_save_register_item_array(device->machine, "zx8302", device->tag(), 0, zx8302->mdv_offset);
631   if (state)
632   {
633      transmit_ipc_data();
634   }
743635}
744636
745/*-------------------------------------------------
746    DEVICE_RESET( zx8301 )
747-------------------------------------------------*/
748637
749static DEVICE_RESET( zx8302 )
638//-------------------------------------------------
639//  comdata_w - IPC COMDATA
640//-------------------------------------------------
641
642WRITE_LINE_MEMBER( zx8302_device::comdata_w )
750643{
751// zx8302_t *zx8302 = get_safe_token(device);
644   if (LOG) logerror("ZX8302 '%s' COMDATA: %x\n", tag(), state);
752645
646   if (m_ipc_state == IPC_DATA || m_ipc_state == IPC_STOP)
647   {
648      if (m_ipc_rx)
649      {
650         m_ipc_rx = 0;
651         m_ipc_busy = 0;
652         m_ipc_state = IPC_START;
653      }
654      else
655      {
656         m_ipc_rx = 1;
657         m_comdata = state;
658      }
659   }
753660}
754661
755/*-------------------------------------------------
756    DEVICE_GET_INFO( zx8301 )
757-------------------------------------------------*/
758662
759DEVICE_GET_INFO( zx8302 )
663//-------------------------------------------------
664//  extint_w - external interrupt
665//-------------------------------------------------
666
667WRITE_LINE_MEMBER( zx8302_device::extint_w )
760668{
761   switch (state)
762   {
763      /* --- the following bits of info are returned as 64-bit signed integers --- */
764      case DEVINFO_INT_TOKEN_BYTES:               info->i = sizeof(zx8302_t);                  break;
765      case DEVINFO_INT_INLINE_CONFIG_BYTES:         info->i = 0;                           break;
669   if (LOG) logerror("ZX8302 '%s' EXTINT: %x\n", tag(), state);
766670
767      /* --- the following bits of info are returned as pointers to data or functions --- */
768      case DEVINFO_FCT_START:                     info->start = DEVICE_START_NAME(zx8302);      break;
769      case DEVINFO_FCT_STOP:                     /* Nothing */                           break;
770      case DEVINFO_FCT_RESET:                     info->reset = DEVICE_RESET_NAME(zx8302);      break;
771
772      /* --- the following bits of info are returned as NULL-terminated strings --- */
773      case DEVINFO_STR_NAME:                     strcpy(info->s, "Sinclair ZX8302");            break;
774      case DEVINFO_STR_FAMILY:                  strcpy(info->s, "Sinclair QL");               break;
775      case DEVINFO_STR_VERSION:                  strcpy(info->s, "1.0");                     break;
776      case DEVINFO_STR_SOURCE_FILE:               strcpy(info->s, __FILE__);                  break;
777      case DEVINFO_STR_CREDITS:                  strcpy(info->s, "Copyright MESS Team");         break;
671   if (state == ASSERT_LINE)
672   {
673      trigger_interrupt(INT_EXTERNAL);
778674   }
779675}
780
781DEFINE_LEGACY_DEVICE(ZX8302, zx8302);
src/mess/machine/zx8302.h
r9767r9768
77
88**********************************************************************
99                            _____   _____
10                 ERASE   1 |*    \_/     | 40
10                 ERASE   1 |*    \_/     | 40  Vdd
1111               EXTINTL   2 |             | 39  DB4
1212                MDRDWL   3 |             | 38  DB5
13                         4 |             | 37  DB0
13                NETOUT   4 |             | 37  DB0
1414                BAUDX4   5 |             | 36  DB1
15                NETOUT   6 |             | 35  COMDATA
16                         7 |             | 34  MDSELDH
15                 DTR1L   6 |             | 35  COMDATA
16                 CTS2L   7 |             | 34  MDSELDH
1717                 DCSML   8 |             | 33  MDSELCKH
18                         9 |             | 32  VSYNCH
18                  ROWL   9 |             | 32  VSYNCH
1919                 PCENL  10 |    ZX8302   | 31  XTAL2
20                        11 |     ULA     | 30  XTAL1
20                   Vdd  11 |     ULA     | 30  XTAL1
2121                   DB2  12 |             | 29
22                        13 |             | 28  RESETOUTL
23                        14 |             | 27  DB7
22                  TXD1  13 |             | 28  RESETOUTL
23                  TXD2  14 |             | 27  DB7
2424                    A5  15 |             | 26  IPL1L
2525                 NETIN  16 |             | 25  CLKCPU
2626                    A1  17 |             | 24  DB3
2727                    A0  18 |             | 23  DB6
2828                  RAW2  19 |             | 22  COMCTL
29             RESETOUTL  20 |_____________| 21  RAW1
29                   GND  20 |_____________| 21  RAW1
3030
3131**********************************************************************/
3232
33#pragma once
34
3335#ifndef __ZX8302__
3436#define __ZX8302__
3537
36#include "devcb.h"
38#include "emu.h"
3739
38/***************************************************************************
39    MACROS / CONSTANTS
40***************************************************************************/
4140
42DECLARE_LEGACY_DEVICE(ZX8302, zx8302);
4341
44#define MDRV_ZX8302_ADD(_tag, _clock, _config) \
42///*************************************************************************
43//   MACROS / CONSTANTS
44///*************************************************************************
45
46
47
48
49///*************************************************************************
50//  INTERFACE CONFIGURATION MACROS
51///*************************************************************************
52
53#define MDRV_ZX8302_ADD(_tag, _clock, _intrf) \
4554   MDRV_DEVICE_ADD(_tag, ZX8302, _clock) \
46   MDRV_DEVICE_CONFIG(_config)
55   MDRV_DEVICE_CONFIG(_intrf)
4756
4857#define ZX8302_INTERFACE(name) \
49   const zx8302_interface(name) =
58   const zx8302_interface (name)=
5059
51/***************************************************************************
52    TYPE DEFINITIONS
53***************************************************************************/
5460
55typedef struct _zx8302_interface zx8302_interface;
56struct _zx8302_interface
61
62///*************************************************************************
63//   TYPE DEFINITIONS
64///*************************************************************************
65
66// ======================> zx8302_interface
67
68struct zx8302_interface
5769{
58   int rtc_clock;            /* the RTC clock (pin 30) of the chip */
70   int rtc_clock;            // the RTC clock (pin 30) of the chip
5971
60   const char *mdv1_tag;      /* microdrive 1 */
61   const char *mdv2_tag;      /* microdrive 2 */
62
63   /* this gets called for every change of the IPL1L pin (pin 26) */
6472   devcb_write_line   out_ipl1l_func;
65
66   /* this gets called for every change of the BAUDX4 pin (pin 5) */
6773   devcb_write_line   out_baudx4_func;
68
69   /* this gets called for every write of the COMDATA pin (pin 35) */
7074   devcb_write_line   out_comdata_func;
75   devcb_write_line   out_txd1_func;
76   devcb_write_line   out_txd2_func;
77   devcb_read_line      in_dtr1_func;
78   devcb_read_line      in_cts2_func;
79   devcb_write_line   out_netout_func;
80   devcb_read_line      in_netin_func;
7181};
7282
73/***************************************************************************
74    PROTOTYPES
75***************************************************************************/
76/* real time clock */
77READ8_DEVICE_HANDLER( zx8302_rtc_r );
78WRITE8_DEVICE_HANDLER( zx8302_rtc_w );
7983
80/* control */
81WRITE8_DEVICE_HANDLER( zx8302_control_w );
84// ======================> zx8302_device_config
8285
83/* microdrive track data */
84READ8_DEVICE_HANDLER( zx8302_mdv_track_r );
86class zx8302_device_config :   public device_config,
87                                public zx8302_interface
88{
89    friend class zx8302_device;
8590
86/* status */
87READ8_DEVICE_HANDLER( zx8302_status_r );
91    // construction/destruction
92    zx8302_device_config(const machine_config &mconfig, const char *tag, const device_config *owner, UINT32 clock);
8893
89/* IPC command */
90WRITE8_DEVICE_HANDLER( zx8302_ipc_command_w );
94public:
95    // allocators
96    static device_config *static_alloc_device_config(const machine_config &mconfig, const char *tag, const device_config *owner, UINT32 clock);
97    virtual device_t *alloc_device(running_machine &machine) const;
9198
92/* microdrive control */
93WRITE8_DEVICE_HANDLER( zx8302_mdv_control_w );
99protected:
100    // device_config overrides
101    virtual void device_config_complete();
102};
94103
95/* interrupt status */
96READ8_DEVICE_HANDLER( zx8302_irq_status_r );
97104
98/* interrupt acknowledge */
99WRITE8_DEVICE_HANDLER( zx8302_irq_acknowledge_w );
105// ======================> zx8302_device
100106
101/* serial data */
102WRITE8_DEVICE_HANDLER( zx8302_data_w );
107class zx8302_device :  public device_t
108{
109    friend class zx8302_device_config;
103110
104/* vertical sync */
105WRITE_LINE_DEVICE_HANDLER( zx8302_vsync_w );
111    // construction/destruction
112    zx8302_device(running_machine &_machine, const zx8302_device_config &_config);
106113
107/* communication control */
108WRITE_LINE_DEVICE_HANDLER( zx8302_comctl_w );
114public:
115   DECLARE_READ8_MEMBER( rtc_r );
116   DECLARE_WRITE8_MEMBER( rtc_w );
117   DECLARE_WRITE8_MEMBER( control_w );
118   DECLARE_READ8_MEMBER( mdv_track_r );
119   DECLARE_READ8_MEMBER( status_r );
120   DECLARE_WRITE8_MEMBER( ipc_command_w );
121   DECLARE_WRITE8_MEMBER( mdv_control_w );
122   DECLARE_READ8_MEMBER( irq_status_r );
123   DECLARE_WRITE8_MEMBER( irq_acknowledge_w );
124   DECLARE_WRITE8_MEMBER( data_w );
125   DECLARE_WRITE_LINE_MEMBER( vsync_w );
126   DECLARE_WRITE_LINE_MEMBER( comctl_w );
127   DECLARE_WRITE_LINE_MEMBER( comdata_w );
128   DECLARE_WRITE_LINE_MEMBER( extint_w );
109129
110/* communication data */
111WRITE_LINE_DEVICE_HANDLER( zx8302_comdata_w );
130protected:
131    // device-level overrides
132    virtual void device_start();
133   virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr);
112134
135   inline void trigger_interrupt(UINT8 line);
136   inline void transmit_ipc_data();
137   inline void transmit_bit(int state);
138   inline void transmit_serial_data();
139
140private:
141   static const device_timer_id TIMER_TXD = 0;
142   static const device_timer_id TIMER_BAUDX4 = 1;
143   static const device_timer_id TIMER_RTC = 2;
144   static const device_timer_id TIMER_GAP = 3;
145   static const device_timer_id TIMER_IPC = 4;
146
147   devcb_resolved_write_line   m_out_ipl1l_func;
148   devcb_resolved_write_line   m_out_baudx4_func;
149   devcb_resolved_write_line   m_out_comdata_func;
150   devcb_resolved_write_line   m_out_txd1_func;
151   devcb_resolved_write_line   m_out_txd2_func;
152   devcb_resolved_read_line   m_in_dtr1_func;
153   devcb_resolved_read_line   m_in_cts2_func;
154   devcb_resolved_write_line   m_out_netout_func;
155   devcb_resolved_read_line   m_in_netin_func;
156
157   // registers
158   UINT8 m_idr;               // IPC data register
159   UINT8 m_tcr;               // transfer control register
160   UINT8 m_tdr;               // transfer data register
161   UINT8 m_irq;               // interrupt register
162   UINT32 m_ctr;               // counter register
163   UINT8 m_status;               // status register
164
165   // IPC communication state
166   int m_comdata;               // communication data
167   int m_comctl;               // communication control
168   int m_ipc_state;            // communication state
169   int m_ipc_rx;               // receiving data from IPC
170   int m_ipc_busy;               // IPC busy
171   int m_baudx4;               // IPC baud x4
172
173   // serial transmit state
174   int m_tx_bits;               // bits transmitted
175
176   // microdrive state
177   int m_mdrdw;               // read/write
178   int m_mdselck;               // select clock
179   int m_mdseld;               // select data
180   int m_erase;               // erase head
181   int m_mdv_motor;            // selected motor
182   UINT8 m_mdv_data[2];         // track data register
183   int m_track;               // current track
184
185   // timers
186   emu_timer *m_txd_timer;         // transmit timer
187   emu_timer *m_baudx4_timer;      // baud x4 timer
188   emu_timer *m_rtc_timer;         // real time clock timer
189   emu_timer *m_gap_timer;         // microdrive gap timer
190   emu_timer *m_ipc_timer;         // delayed IPC command timer
191
192   const zx8302_device_config &m_config;
193};
194
195
196// device type definition
197extern const device_type ZX8302;
198
199
200
113201#endif
src/mess/includes/ql.h
r9767r9768
3535   required_device<cpu_device> m_maincpu;
3636   required_device<cpu_device> m_ipc;
3737   required_device<zx8301_device> m_zx8301;
38   required_device<running_device> m_zx8302;
38   required_device<zx8302_device> m_zx8302;
3939   required_device<running_device> m_speaker;
4040   required_device<running_device> m_ram;
4141
src/mess/drivers/ql.c
r9767r9768
5858
5959WRITE8_MEMBER( ql_state::ipc_w )
6060{
61   zx8302_comctl_w(m_zx8302, 0);
62   zx8302_comctl_w(m_zx8302, 1);
61   m_zx8302->comctl_w(0);
62   m_zx8302->comctl_w(1);
6363}
6464
6565WRITE8_MEMBER( ql_state::ipc_port1_w )
r9767r9768
133133
134134   m_comdata = BIT(data, 7);
135135
136   zx8302_comdata_w(m_zx8302, BIT(data, 7));
136   m_zx8302->comdata_w(BIT(data, 7));
137137}
138138
139139READ8_MEMBER( ql_state::ipc_port2_r )
r9767r9768
202202   AM_RANGE(0x000000, 0x00bfff) AM_ROM   // 48K System ROM
203203   AM_RANGE(0x00c000, 0x00ffff) AM_ROM // 16K Cartridge ROM
204204   AM_RANGE(0x010000, 0x017fff) AM_UNMAP // 32K Expansion I/O
205   AM_RANGE(0x018000, 0x018003) AM_DEVREAD_LEGACY(ZX8302_TAG, zx8302_rtc_r)
206   AM_RANGE(0x018000, 0x018001) AM_DEVWRITE_LEGACY(ZX8302_TAG, zx8302_rtc_w)
207   AM_RANGE(0x018002, 0x018002) AM_DEVWRITE_LEGACY(ZX8302_TAG, zx8302_control_w)
208   AM_RANGE(0x018003, 0x018003) AM_DEVWRITE_LEGACY(ZX8302_TAG, zx8302_ipc_command_w)
209   AM_RANGE(0x018020, 0x018020) AM_DEVREADWRITE_LEGACY(ZX8302_TAG, zx8302_status_r, zx8302_mdv_control_w)
210   AM_RANGE(0x018021, 0x018021) AM_DEVREADWRITE_LEGACY(ZX8302_TAG, zx8302_irq_status_r, zx8302_irq_acknowledge_w)
211   AM_RANGE(0x018022, 0x018022) AM_DEVREADWRITE_LEGACY(ZX8302_TAG, zx8302_mdv_track_r, zx8302_data_w)
212   AM_RANGE(0x018023, 0x018023) AM_DEVREAD_LEGACY(ZX8302_TAG, zx8302_mdv_track_r) AM_WRITENOP
205   AM_RANGE(0x018000, 0x018003) AM_DEVREAD(ZX8302_TAG, zx8302_device, rtc_r)
206   AM_RANGE(0x018000, 0x018001) AM_DEVWRITE(ZX8302_TAG, zx8302_device, rtc_w)
207   AM_RANGE(0x018002, 0x018002) AM_DEVWRITE(ZX8302_TAG, zx8302_device, control_w)
208   AM_RANGE(0x018003, 0x018003) AM_DEVWRITE(ZX8302_TAG, zx8302_device, ipc_command_w)
209   AM_RANGE(0x018020, 0x018020) AM_DEVREADWRITE(ZX8302_TAG, zx8302_device, status_r, mdv_control_w)
210   AM_RANGE(0x018021, 0x018021) AM_DEVREADWRITE(ZX8302_TAG, zx8302_device, irq_status_r, irq_acknowledge_w)
211   AM_RANGE(0x018022, 0x018022) AM_DEVREADWRITE(ZX8302_TAG, zx8302_device, mdv_track_r, data_w)
212   AM_RANGE(0x018023, 0x018023) AM_DEVREAD(ZX8302_TAG, zx8302_device, mdv_track_r) AM_WRITENOP
213213   AM_RANGE(0x018063, 0x018063) AM_DEVWRITE(ZX8301_TAG, zx8301_device, control_w)
214214   AM_RANGE(0x01c000, 0x01ffff) AM_UNMAP // 16K Expansion I/O
215215   AM_RANGE(0x020000, 0x03ffff) AM_DEVREADWRITE(ZX8301_TAG, zx8301_device, data_r, data_w)
r9767r9768
459459{
460460   M68008_TAG,
461461   SCREEN_TAG,
462   DEVCB_DEVICE_LINE(ZX8302_TAG, zx8302_vsync_w)
462   DEVCB_DEVICE_LINE_MEMBER(ZX8302_TAG, zx8302_device, vsync_w)
463463};
464464
465465/* ZX8302 Interface */
r9767r9768
477477static ZX8302_INTERFACE( ql_zx8302_intf )
478478{
479479   X2,
480   MDV1_TAG,
481   MDV2_TAG,
482480   DEVCB_CPU_INPUT_LINE(M68008_TAG, M68K_IRQ_2),
483481   DEVCB_DRIVER_LINE_MEMBER(ql_state, ql_baudx4_w),
484   DEVCB_DRIVER_LINE_MEMBER(ql_state, ql_comdata_w)
482   DEVCB_DRIVER_LINE_MEMBER(ql_state, ql_comdata_w),
483   DEVCB_NULL,
484   DEVCB_NULL,
485   DEVCB_NULL,
486   DEVCB_NULL,
487   DEVCB_NULL,
488   DEVCB_NULL
485489};
486490
487491static PALETTE_INIT( ql )

Previous 15994 Revisions Next


© 1998-2018 The MESS Team