Previous 15994 Revisions Next

r3335 Saturday 27th September, 2008 at 10:22:14 UTC by Wilbert Pol
Changed AY-3-1015 code into a device.
[EXIDY] Added support for 1200 baud cassette images.
[docs]messnew.txt
[src/mess/drivers]exidy.c
[src/mess/machine]ay31015.c ay31015.h

src/mess/machine/ay31015.c
r3334r3335
22
33   ay31015.c by Robbbert, May 2008
44
5   Code for the AY-3-1014A, AY-3-1015(D), AY-5-1013(A) and AY-6-1013 UARTs
5   Code for the AY-3-1014A, AY-3-1015(D), AY-5-1013(A), and AY-6-1013 UARTs
6   The HD6402 UART is compatible with the AY-3-1015 UART.
67
78   This is cycle-accurate according to the specifications.
89
r3334r3335
8990#include "driver.h"
9091#include "ay31015.h"
9192
92//typedef struct _ay31015_token ay31015_token;
93static struct // _ay31015_token
93typedef enum
9494{
95   IDLE,
96   START_BIT,
97   PROCESSING,
98   PARITY_BIT,
99   FIRST_STOP_BIT,
100   SECOND_STOP_BIT,
101   PREP_TIME
102} state_t;
103
104
105typedef struct _ay31015_t ay31015_t;
106struct _ay31015_t
107{
108   const ay31015_config   *config;
109
110   int   pins[41];
111
95112   UINT8 control_reg;
96113   UINT8 status_reg;
97114   UINT16 second_stop_bit;   // 0, 8, 16
98115   UINT16 total_pulses;   // bits * 16
99116   UINT8 internal_sample;
100117
101   UINT8 rx_state;
118   state_t rx_state;
102119   UINT8 rx_data;      // byte being received
103120   UINT8 rx_buffer;   // received byte waiting to be accepted by computer
104121   UINT8 rx_bit_count;
105122   UINT8 rx_parity;
106123   UINT16 rx_pulses;   // total pulses left
124   double rx_clock;
125   emu_timer *rx_timer;
107126
108   UINT8 tx_state;
127   state_t tx_state;
109128   UINT8 tx_data;      // byte being sent
110129   UINT8 tx_buffer;   // next byte to send
111130   UINT8 tx_parity;
112131   UINT16 tx_pulses;   // total pulses left
113   UINT8 si;
114} ay;
132   double tx_clock;
133   emu_timer *tx_timer;
134};
115135
116//static struct _ay31015_token ay;
117136
118/* state - must only be altered by the timer callbacks */
137/* control reg */
138#define CONTROL_NB1      0x01
139#define CONTROL_NB2      0x02
140#define CONTROL_TSB      0x04
141#define CONTROL_EPS      0x08
142#define CONTROL_NP      0x10
119143
120#define IDLE      0
121#define START_BIT   1
122#define PROCESSING   2
123#define PARITY_BIT   3
124#define FIRST_STOP_BIT   4
125#define SECOND_STOP_BIT   5
126#define PREP_TIME   6
127144
128#if 0
145/* status reg */
146#define STATUS_TBMT      0x01
147#define STATUS_DAV      0x02
148#define STATUS_OR      0x04
149#define STATUS_FE      0x08
150#define STATUS_PE      0x10
151#define STATUS_EOC      0x20
152
153
129154/*-------------------------------------------------
130    get_token - safely gets the data
155    get_safe_token - safely gets the data
131156-------------------------------------------------*/
132157
133INLINE ay31015_token *get_token(const device_config *device)
158INLINE ay31015_t *get_safe_token(const device_config *device)
134159{
135160   assert(device != NULL);
136161   assert(device->token != NULL);
137162   assert(device->type == AY31015);
138   return (ay31015_token *) device->token;
163   return (ay31015_t *) device->token;
139164}
140165
141166
142/*-------------------------------------------------
143    get_config - safely gets the config
144-------------------------------------------------*/
145
146INLINE const ay31015_config *get_config(const device_config *device)
167INLINE UINT8 ay31015_get_si( const device_config *device )
147168{
148   assert(device != NULL);
149   assert(device->token != NULL);
150   assert(device->type == ay31015);
151   return (const ay31015_config *) device->static_config;
152}
169   ay31015_t   *ay31015 = get_safe_token( device );
153170
171   if ( ay31015->config->read_si )
172      ay31015->pins[AY31015_SI] = (ay31015->config->read_si)( device, 0 ) ? 1 : 0;
154173
155static DEVICE_START(ay31015)
156{
157   ay31015_token *ay;
158//   const ay31015_config *config = get_config(device);
159
160   ay = get_token(device);
161   return DEVICE_START_OK;
174   return ay31015->pins[AY31015_SI];
162175}
163#endif
164176
165177
166/*-------------------------------------------------
167    ay51013_xr - the reset pin
168-------------------------------------------------*/
169static void ay51013_xr( void )
178INLINE void ay31015_set_so( const device_config *device, int data )
170179{
171   /* total pulses = 16 * data-bits */
172   UINT8 t1;
173   t1 = (ay.control_reg & 3) + 5;               /* data bits */
174   ay.total_pulses = t1 << 4;               /* total clock pulses to load a byte */
175   ay.second_stop_bit = ((ay.control_reg & AY31015_TSB) ? 16 : 0);      /* 2nd stop bit */
176   ay.status_reg = AY31015_EOC | AY31015_TBMT | AY31015_SO;
177   ay.tx_data = 0;
178   ay.rx_state = PREP_TIME;
179   ay.tx_state = IDLE;
180   ay.si = 1;
181}
180   ay31015_t   *ay31015 = get_safe_token( device );
182181
182   ay31015->pins[AY31015_SO] = data ? 1 : 0;
183183
184/*-------------------------------------------------
185    ay51013_init - drivers should call this at
186    machine reset time
187-------------------------------------------------*/
188void ay51013_init( void )
189{
190   ay.control_reg = 0;
191   ay.rx_data = 0;
192   ay51013_xr();
184   if ( ay31015->config->write_so )
185      (ay31015->config->write_so)( device, 0, ay31015->pins[AY31015_SO] );
193186}
194187
195188
196/*-------------------------------------------------
197    ay51013_cs - The entire control register is
198    updated at once.
199-------------------------------------------------*/
200void ay51013_cs( UINT8 data )
189INLINE int ay31015_update_status_pin( ay31015_t *ay31015, UINT8 reg_bit, ay31015_output_pin_t pin )
201190{
202   UINT8 t1 = ay.control_reg;
203   ay.control_reg = data;
204   if (ay.control_reg != t1) ay51013_xr();
205}
191   int new_value = ( ay31015->status_reg & reg_bit ) ? 1 : 0;
206192
193   if ( new_value == ay31015->pins[pin] )
194      return 0;
207195
208
209/*-------------------------------------------------
210    ay31015_xr - the reset pin
211-------------------------------------------------*/
212static void ay31015_xr( void )
213{
214   /* total pulses = 16 * data-bits */
215   UINT8 t1;
216   t1 = (ay.control_reg & 3) + 5;               /* data bits */
217   ay.total_pulses = t1 << 4;               /* total clock pulses to load a byte */
218   ay.second_stop_bit = ((ay.control_reg & AY31015_TSB) ? 16 : 0);      /* 2nd stop bit */
219   if ((t1 == 5) && (ay.second_stop_bit == 16))
220      ay.second_stop_bit = 8;            /* 5 data bits and 2 stop bits = 1.5 stop bits */
221   ay.status_reg = AY31015_EOC | AY31015_TBMT | AY31015_SO;
222   ay.rx_data = 0;
223   ay.tx_data = 0;
224   ay.rx_state = PREP_TIME;
225   ay.tx_state = IDLE;
226   ay.si = 1;
196   ay31015->pins[pin] = new_value;
197   return 1;
227198}
228199
229200
230201/*-------------------------------------------------
231    ay31015_init - drivers should call this at
232    machine reset time
202    ay31015_update_status_pins - Update the status pins
233203-------------------------------------------------*/
234void ay31015_init( void )
204static void ay31015_update_status_pins( const device_config *device )
235205{
236   ay.control_reg = 0;
237   ay31015_xr();
238}
206   ay31015_t   *ay31015 = get_safe_token( device );
207   int status_pins_changed = 0;
239208
209   /* Should status pins be updated? */
210   if ( ! ay31015->pins[AY31015_SWE] )
211   {
212      status_pins_changed += ay31015_update_status_pin( ay31015, STATUS_PE, AY31015_PE );
213      status_pins_changed += ay31015_update_status_pin( ay31015, STATUS_FE, AY31015_FE );
214      status_pins_changed += ay31015_update_status_pin( ay31015, STATUS_OR, AY31015_OR );
215      status_pins_changed += ay31015_update_status_pin( ay31015, STATUS_DAV, AY31015_DAV );
216      status_pins_changed += ay31015_update_status_pin( ay31015, STATUS_TBMT, AY31015_TBMT );
217   }
218   status_pins_changed += ay31015_update_status_pin( ay31015, STATUS_EOC, AY31015_EOC );
240219
241/*-------------------------------------------------
242    ay31015_cs - The entire control register is
243    updated at once.
244-------------------------------------------------*/
245void ay31015_cs( UINT8 data )
246{
247   UINT8 t1 = ay.control_reg;
248   ay.control_reg = data;
249   if (ay.control_reg != t1) ay31015_xr();
220   if ( status_pins_changed && ay31015->config->status_changed )
221   {
222      (ay31015->config->status_changed)( device, 0, status_pins_changed );
223   }
250224}
251225
252226
r3334r3335
258232-------------------------------------------------*/
259233static TIMER_CALLBACK( ay31015_rx_process )
260234{
261   switch (ay.rx_state)
235   const device_config   *device = ptr;
236   ay31015_t         *ay31015 = get_safe_token( device );
237
238   switch (ay31015->rx_state)
262239   {
263240      case PREP_TIME:                     // assist sync by ensuring high bit occurs
264         ay.rx_pulses--;
265         if (ay.si)
266            ay.rx_state = IDLE;
241         ay31015->rx_pulses--;
242         if (ay31015_get_si( device ))
243            ay31015->rx_state = IDLE;
267244         return;
268245
269246      case IDLE:
270         ay.rx_pulses--;
271         if (!ay.si)
247         ay31015->rx_pulses--;
248         if (!ay31015_get_si( device ))
272249         {
273            ay.rx_state = START_BIT;
274            ay.rx_pulses = 16;
250            ay31015->rx_state = START_BIT;
251            ay31015->rx_pulses = 16;
275252         }
276253         return;
277254
278255      case START_BIT:
279         ay.rx_pulses--;
280         if ((ay.rx_pulses == 8) && (ay.si))         // start bit must be low at sample time
281            ay.rx_state = IDLE;
256         ay31015->rx_pulses--;
257         if (ay31015->rx_pulses == 8)         // start bit must be low at sample time
258         {
259            if ( ay31015_get_si( device ) )
260               ay31015->rx_state = IDLE;
261         }
282262         else
283         if (!ay.rx_pulses)               // end of start bit
263         if (!ay31015->rx_pulses)               // end of start bit
284264         {
285            ay.rx_state = PROCESSING;
286            ay.rx_pulses = ay.total_pulses;
287            ay.rx_bit_count = 0;
288            ay.rx_parity = 0;
289            ay.rx_data = 0;
265            ay31015->rx_state = PROCESSING;
266            ay31015->rx_pulses = ay31015->total_pulses;
267            ay31015->rx_bit_count = 0;
268            ay31015->rx_parity = 0;
269            ay31015->rx_data = 0;
290270         }
291271         return;
292272
293273      case PROCESSING:
294         ay.rx_pulses--;
295         if (!ay.rx_pulses)               // end of a byte
274         ay31015->rx_pulses--;
275         if (!ay31015->rx_pulses)               // end of a byte
296276         {
297            ay.rx_pulses = 16;
298            if (ay.control_reg & AY31015_NP)      // see if we need to get a parity bit
299               ay.rx_state = FIRST_STOP_BIT;
277            ay31015->rx_pulses = 16;
278            if (ay31015->control_reg & CONTROL_NP)      // see if we need to get a parity bit
279               ay31015->rx_state = FIRST_STOP_BIT;
300280            else
301               ay.rx_state = PARITY_BIT;
281               ay31015->rx_state = PARITY_BIT;
302282         }
303283         else
304         if (!(ay.rx_pulses & 15))            // end of a bit
305            ay.rx_bit_count++;
284         if (!(ay31015->rx_pulses & 15))            // end of a bit
285            ay31015->rx_bit_count++;
306286         else
307         if ((ay.rx_pulses & 15) == 8)            // sample input stream
287         if ((ay31015->rx_pulses & 15) == 8)            // sample input stream
308288         {
309            ay.internal_sample = ay.si;
310            ay.rx_parity ^= ay.internal_sample;      // calculate cumulative parity
311            ay.rx_data |= ay.internal_sample << ay.rx_bit_count;
289            ay31015->internal_sample = ay31015_get_si( device );
290            ay31015->rx_parity ^= ay31015->internal_sample;      // calculate cumulative parity
291            ay31015->rx_data |= ay31015->internal_sample << ay31015->rx_bit_count;
312292         }
313293         return;
314294
315295      case PARITY_BIT:
316         ay.rx_pulses--;
296         ay31015->rx_pulses--;
317297
318         if (ay.rx_pulses == 8)               // sample input stream
319            ay.rx_parity ^= ay.si;            // calculate cumulative parity
298         if (ay31015->rx_pulses == 8)               // sample input stream
299         {
300            ay31015->rx_parity ^= ay31015_get_si( device );            // calculate cumulative parity
301         }
320302         else
321         if (!ay.rx_pulses)               // end of a byte
303         if (!ay31015->rx_pulses)               // end of a byte
322304         {
323            ay.rx_pulses = 16;
324            ay.rx_state = FIRST_STOP_BIT;
305            ay31015->rx_pulses = 16;
306            ay31015->rx_state = FIRST_STOP_BIT;
325307
326            if ((ay.status_reg & AY31015_EPS) && (ay.rx_parity))
327               ay.rx_parity = 0;         // odd parity, ok
308            if ((ay31015->control_reg & CONTROL_EPS) && (ay31015->rx_parity))
309               ay31015->rx_parity = 0;         // odd parity, ok
328310            else
329            if ((!(ay.status_reg & AY31015_EPS)) && (!ay.rx_parity))
330               ay.rx_parity = 0;         // even parity, ok
311            if ((!(ay31015->control_reg & CONTROL_EPS)) && (!ay31015->rx_parity))
312               ay31015->rx_parity = 0;         // even parity, ok
331313            else
332               ay.rx_parity = 1;         // parity error
314               ay31015->rx_parity = 1;         // parity error
333315         }
334316         return;
335317
336318      case FIRST_STOP_BIT:
337         ay.rx_pulses--;
338         if (ay.rx_pulses == 8)            // sample input stream
339            ay.internal_sample = ay.si;
319         ay31015->rx_pulses--;
320         if (ay31015->rx_pulses == 8)            // sample input stream
321            ay31015->internal_sample = ay31015_get_si( device );
340322         else
341         if (ay.rx_pulses == 7)            // set error flags
323         if (ay31015->rx_pulses == 7)            // set error flags
342324         {
343            if (!ay.internal_sample)
325            if (!ay31015->internal_sample)
344326            {
345               ay.status_reg |= AY31015_FE;      // framing error - the stop bit not high
346               ay.rx_state = PREP_TIME;      // lost sync - start over
327               ay31015->status_reg |= STATUS_FE;      // framing error - the stop bit not high
328               ay31015->rx_state = PREP_TIME;      // lost sync - start over
347329         //      return;
348330            }
349331            else
350               ay.status_reg &= ~AY31015_FE;
332               ay31015->status_reg &= ~STATUS_FE;
351333
352            if ((ay.rx_parity) && (!(ay.control_reg & AY31015_NP)))
353               ay.status_reg |= AY31015_PE;      // parity error
334            if ((ay31015->rx_parity) && (!(ay31015->control_reg & CONTROL_NP)))
335               ay31015->status_reg |= STATUS_PE;      // parity error
354336            else
355               ay.status_reg &= ~AY31015_PE;
337               ay31015->status_reg &= ~STATUS_PE;
356338
357            if (ay.status_reg & AY31015_DAV)
358               ay.status_reg |= AY31015_OR;      // overrun error - previous byte still in buffer
339            if (ay31015->status_reg & STATUS_DAV)
340               ay31015->status_reg |= STATUS_OR;      // overrun error - previous byte still in buffer
359341            else
360               ay.status_reg &= ~AY31015_OR;
342               ay31015->status_reg &= ~STATUS_OR;
361343
362            ay.rx_buffer = ay.rx_data;      // bring received byte out for computer to read
344            ay31015->rx_buffer = ay31015->rx_data;      // bring received byte out for computer to read
345
346            ay31015_update_status_pins( device );
363347         }
364348         else
365         if (ay.rx_pulses == 6)
366            ay.status_reg |= AY31015_DAV;      // tell computer that new byte is ready
349         if (ay31015->rx_pulses == 6)
350         {
351            ay31015->status_reg |= STATUS_DAV;      // tell computer that new byte is ready
352            ay31015_update_status_pins( device );
353         }
367354         else
368         if (ay.rx_pulses == 4)
355         if (ay31015->rx_pulses == 4)
356         {
357            if (ay31015->second_stop_bit)
358            {
359               /* We should wait for the full first stop bit and
360                  the beginning of the second stop bit */
361               ay31015->rx_state = SECOND_STOP_BIT;
362               ay31015->rx_pulses += ay31015->second_stop_bit - 7;
363            }
364            else
365            {
366               /* We have seen a STOP bit, go back to PREP_TIME */
367               ay31015->rx_state = PREP_TIME;
368            }
369         }
370         return;
371         
372      case SECOND_STOP_BIT:
373         ay31015->rx_pulses--;
374         if (!ay31015->rx_pulses)
375            ay31015->rx_state = PREP_TIME;
376         return;
369377
370   /* According to the specs, this commented-out code is what happens.
371      However, it is not particularly effective at keeping sync.
372      Therefore, since the input is HIGH, we simply jump to PREP_TIME and
373      wait for the next start bit to begin. */
374
375//         if (!ay.rx_pulses)            // end of first stop bit
376//         {
377//            if (ay.second_stop_bit)
378//            {
379//               ay.rx_state = SECOND_STOP_BIT;
380//               ay.rx_pulses = ay.second_stop_bit;
381//            }
382//            else
383//               ay.rx_state = PREP_TIME;
384//         }
385//         return;
386//         
387//      case SECOND_STOP_BIT:
388//         ay.rx_pulses--;
389//         if (!ay.rx_pulses)
390            ay.rx_state = PREP_TIME;
391         return;
392378   }
393379}
394380
395381
396/*-------------------------------------------------
397    ay31015_set_rx_clock_speed - set receive clock
398-------------------------------------------------*/
399void ay31015_set_rx_clock_speed( UINT32 data )
400{
401//   if (data)
402      timer_pulse(ATTOTIME_IN_HZ(data),NULL,0,ay31015_rx_process);
403//   else
404//      turn timer off;
405}
406
407/*-------------------------------------------------
408    ay31015_swe - The entire status register is
409    returned at once.
410-------------------------------------------------*/
411UINT8 ay31015_swe( void )
412{
413   return ay.status_reg & 0x3f;
414}
415
416
417/*-------------------------------------------------
418    ay31015_rde - return a byte to the computer
419-------------------------------------------------*/
420UINT8 ay31015_rde( void )
421{
422   return ay.rx_buffer;
423}
424
425
426/*-------------------------------------------------
427    ay31015_rdav - tell uart computer has retrieved
428    the above byte.
429-------------------------------------------------*/
430void ay31015_rdav( void )
431{
432   ay.status_reg &= ~AY31015_DAV;      /* set dav low */
433}
434
435
436/*-------------------------------------------------
437    ay31015_si - send a serial bit to the uart
438-------------------------------------------------*/
439void ay31015_si( UINT8 data )
440{
441   ay.si = (data) ? 1 : 0;
442}
443
444
445382/*************************************************** TRANSMIT CONTROLS *************************************************/
446383
447384
r3334r3335
450387-------------------------------------------------*/
451388static TIMER_CALLBACK( ay31015_tx_process )
452389{
390   const device_config   *device = ptr;
391   ay31015_t         *ay31015 = get_safe_token( device );
392
453393   UINT8 t1;
454   switch (ay.tx_state)
394   switch (ay31015->tx_state)
455395   {
456396      case IDLE:
457         if (!(ay.status_reg & AY31015_TBMT))
397         if (!(ay31015->status_reg & STATUS_TBMT))
458398         {
459            ay.tx_state = PREP_TIME;      // When idle, see if a byte has been sent to us
460            ay.tx_pulses = 1;
399            ay31015->tx_state = PREP_TIME;      // When idle, see if a byte has been sent to us
400            ay31015->tx_pulses = 1;
461401         }
462402         return;
463403
464404      case PREP_TIME:                  // This phase lets the transmitter regain sync after an idle period
465         ay.tx_pulses--;
466         if (!ay.tx_pulses)
405         ay31015->tx_pulses--;
406         if (!ay31015->tx_pulses)
467407         {
468            ay.tx_state = START_BIT;
469            ay.tx_pulses = 16;
408            ay31015->tx_state = START_BIT;
409            ay31015->tx_pulses = 16;
470410         }
471411         return;
472412
473413      case START_BIT:
474         if (ay.tx_pulses == 16)            // beginning of start bit
414         if (ay31015->tx_pulses == 16)            // beginning of start bit
475415         {
476            ay.tx_data = ay.tx_buffer;         // load the shift register
477            ay.status_reg |= AY31015_TBMT;         // tell computer that another byte can be sent to uart
478            ay.status_reg &= ~AY31015_SO;         // start bit begins now (we are "spacing")
479            ay.status_reg &= ~AY31015_EOC;         // we are no longer idle
480            ay.tx_parity = 0;
416            ay31015->tx_data = ay31015->tx_buffer;         // load the shift register
417            ay31015->status_reg |= STATUS_TBMT;         // tell computer that another byte can be sent to uart
418            ay31015_set_so( device, 0 );            /* start bit begins now (we are "spacing") */
419            ay31015->status_reg &= ~STATUS_EOC;         // we are no longer idle
420            ay31015->tx_parity = 0;
421            ay31015_update_status_pins( device );
481422         }
482423
483         ay.tx_pulses--;
484         if (!ay.tx_pulses)               // end of start bit
424         ay31015->tx_pulses--;
425         if (!ay31015->tx_pulses)               // end of start bit
485426         {
486            ay.tx_state = PROCESSING;
487            ay.tx_pulses = ay.total_pulses;
427            ay31015->tx_state = PROCESSING;
428            ay31015->tx_pulses = ay31015->total_pulses;
488429         }
489430         return;
490431
491432      case PROCESSING:
492         if (!(ay.tx_pulses & 15))            // beginning of a data bit
433         if (!(ay31015->tx_pulses & 15))            // beginning of a data bit
493434         {
494            if (ay.tx_data & 1)
435            if (ay31015->tx_data & 1)
495436            {
496               ay.status_reg |= AY31015_SO;
497               ay.tx_parity++;            // calculate cumulative parity
437               ay31015_set_so( device, 1 );
438               ay31015->tx_parity++;            // calculate cumulative parity
498439            }
499440            else
500               ay.status_reg &= ~AY31015_SO;
441               ay31015_set_so( device, 0 );
501442
502            ay.tx_data >>= 1;            // adjust the shift register
443            ay31015->tx_data >>= 1;            // adjust the shift register
503444         }
504445           
505         ay.tx_pulses--;
506         if (!ay.tx_pulses)               // all data bits sent
446         ay31015->tx_pulses--;
447         if (!ay31015->tx_pulses)               // all data bits sent
507448         {
508            ay.tx_pulses = 16;
509            if (ay.control_reg & AY31015_NP)      // see if we need to make a parity bit
510               ay.tx_state = FIRST_STOP_BIT;
449            ay31015->tx_pulses = 16;
450            if (ay31015->control_reg & CONTROL_NP)      // see if we need to make a parity bit
451               ay31015->tx_state = FIRST_STOP_BIT;
511452            else
512               ay.tx_state = PARITY_BIT;
453               ay31015->tx_state = PARITY_BIT;
513454         }
514455
515456         return;
516457
517458      case PARITY_BIT:
518         if (ay.tx_pulses == 16)
459         if (ay31015->tx_pulses == 16)
519460         {
520            t1 = (ay.control_reg & AY31015_EPS) ? 0 : 1;
521            t1 ^= (ay.tx_parity & 1);
461            t1 = (ay31015->control_reg & CONTROL_EPS) ? 0 : 1;
462            t1 ^= (ay31015->tx_parity & 1);
522463            if (t1)
523               ay.status_reg |= AY31015_SO;      // extra bit to set the correct parity
464               ay31015_set_so( device, 1 );         /* extra bit to set the correct parity */
524465            else
525               ay.status_reg &= ~AY31015_SO;      // it was already correct
466               ay31015_set_so( device, 0 );         /* it was already correct */
526467         }
527468
528         ay.tx_pulses--;
529         if (!ay.tx_pulses)
469         ay31015->tx_pulses--;
470         if (!ay31015->tx_pulses)
530471         {
531            ay.tx_state = FIRST_STOP_BIT;
532            ay.tx_pulses = 16;
472            ay31015->tx_state = FIRST_STOP_BIT;
473            ay31015->tx_pulses = 16;
533474         }
534475         return;
535476
536477      case FIRST_STOP_BIT:
537         if (ay.tx_pulses == 16)
538            ay.status_reg |= AY31015_SO;         // create a stop bit (marking and soon idle)
539         ay.tx_pulses--;
540         if (!ay.tx_pulses)
478         if (ay31015->tx_pulses == 16)
479            ay31015_set_so( device, 1 );            /* create a stop bit (marking and soon idle) */
480         ay31015->tx_pulses--;
481         if (!ay31015->tx_pulses)
541482         {
542            ay.status_reg |= AY31015_EOC;         // character is completely sent
543            if (ay.second_stop_bit)
483            ay31015->status_reg |= STATUS_EOC;         // character is completely sent
484            if (ay31015->second_stop_bit)
544485            {
545               ay.tx_state = SECOND_STOP_BIT;
546               ay.tx_pulses = ay.second_stop_bit;
486               ay31015->tx_state = SECOND_STOP_BIT;
487               ay31015->tx_pulses = ay31015->second_stop_bit;
547488            }
548489            else
549            if (ay.status_reg & AY31015_TBMT)
550               ay.tx_state = IDLE;         // if nothing to send, go idle
490            if (ay31015->status_reg & STATUS_TBMT)
491               ay31015->tx_state = IDLE;         // if nothing to send, go idle
551492            else
552493            {
553               ay.tx_pulses = 16;
554               ay.tx_state = START_BIT;      // otherwise immediately start next byte
494               ay31015->tx_pulses = 16;
495               ay31015->tx_state = START_BIT;      // otherwise immediately start next byte
555496            }
497            ay31015_update_status_pins( device );
556498         }
557499         return;
558500
559501      case SECOND_STOP_BIT:
560         ay.tx_pulses--;
561         if (!ay.tx_pulses)
502         ay31015->tx_pulses--;
503         if (!ay31015->tx_pulses)
562504         {
563            if (ay.status_reg & AY31015_TBMT)
564               ay.tx_state = IDLE;         // if nothing to send, go idle
505            if (ay31015->status_reg & STATUS_TBMT)
506               ay31015->tx_state = IDLE;         // if nothing to send, go idle
565507            else
566508            {
567               ay.tx_pulses = 16;
568               ay.tx_state = START_BIT;      // otherwise immediately start next byte
509               ay31015->tx_pulses = 16;
510               ay31015->tx_state = START_BIT;      // otherwise immediately start next byte
569511            }
570512         }
571513         return;
r3334r3335
575517
576518
577519/*-------------------------------------------------
578    ay31015_set_tx_clock_speed - set transmit clock
520    ay31015_reset - reset internal state
579521-------------------------------------------------*/
580void ay31015_set_tx_clock_speed( UINT32 data )
522static void ay31015_reset( const device_config *device )
581523{
582//   if (data)
583      timer_pulse(ATTOTIME_IN_HZ(data),NULL,0,ay31015_tx_process);
584//   else
585//      turn timer off;
524   ay31015_t   *ay31015 = get_safe_token( device );
525
526   /* total pulses = 16 * data-bits */
527   UINT8 t1;
528
529   if ( ay31015->control_reg & CONTROL_NB2 )
530      t1 = ( ay31015->control_reg & CONTROL_NB1 ) ? 8 : 7;
531   else
532      t1 = ( ay31015->control_reg & CONTROL_NB1 ) ? 6 : 5;
533
534   ay31015->total_pulses = t1 << 4;               /* total clock pulses to load a byte */
535   ay31015->second_stop_bit = ((ay31015->control_reg & CONTROL_TSB) ? 16 : 0);      /* 2nd stop bit */
536   if ((t1 == 5) && (ay31015->second_stop_bit == 16))
537      ay31015->second_stop_bit = 8;            /* 5 data bits and 2 stop bits = 1.5 stop bits */
538   ay31015->status_reg = STATUS_EOC | STATUS_TBMT;
539   ay31015->tx_data = 0;
540   ay31015->rx_state = PREP_TIME;
541   ay31015->tx_state = IDLE;
542   ay31015->pins[AY31015_SI] = 1;
543   ay31015_set_so( device, 1 );
544
545   if ( ay31015->config->type == AY_3_1015 )
546      ay31015->rx_data = 0;
547
586548}
587549
588550
589551/*-------------------------------------------------
590    ay31015_so - return a serial bit to calling
591    driver.
552    ay31015_transfer_control_pins - transfers contents of controls pins to the control register
592553-------------------------------------------------*/
593UINT8 ay31015_so( void )
554static void ay31015_transfer_control_pins( const device_config *device )
594555{
595   return (ay.status_reg & AY31015_SO) ? 1 : 0;
556   ay31015_t   *ay31015 = get_safe_token( device );
557   UINT8 control = 0;
558
559   control |= ay31015->pins[AY31015_NP ] ? CONTROL_NP  : 0;
560   control |= ay31015->pins[AY31015_TSB] ? CONTROL_TSB : 0;
561   control |= ay31015->pins[AY31015_NB1] ? CONTROL_NB1 : 0;
562   control |= ay31015->pins[AY31015_NB2] ? CONTROL_NB2 : 0;
563   control |= ay31015->pins[AY31015_EPS] ? CONTROL_EPS : 0;
564
565   if ( ay31015->control_reg != control )
566   {
567      ay31015->control_reg = control;
568      ay31015_reset( device );
569   }
596570}
597571
598572
599573/*-------------------------------------------------
600    ay31015_ds - accept a byte to transmit, if able
574    ay31015_set_input_pin - set an input pin
601575-------------------------------------------------*/
602void ay31015_ds( UINT8 data )
576void ay31015_set_input_pin( const device_config *device, ay31015_input_pin_t pin, int data )
603577{
604   if (ay.status_reg & AY31015_TBMT)
578   ay31015_t   *ay31015 = get_safe_token(device);
579
580   data = data ? 1 : 0;
581
582   switch ( pin )
605583   {
606      ay.tx_buffer = data;
607      ay.status_reg &= ~AY31015_TBMT;
584   case AY31015_SWE:
585      ay31015->pins[pin] = data;
586      ay31015_update_status_pins( device );
587      break;
588   case AY31015_RDAV:
589      ay31015->pins[pin] = data;
590      if ( ! data )
591      {
592         ay31015->status_reg &= ~STATUS_DAV;
593         ay31015->pins[AY31015_DAV] = 0;
594      }
595      break;
596   case AY31015_SI:
597      ay31015->pins[pin] = data;
598      break;
599   case AY31015_XR:
600      ay31015->pins[pin] = data;
601      if ( data )
602         ay31015_reset( device );
603      break;
604   case AY31015_CS:
605   case AY31015_NP:
606   case AY31015_TSB:
607   case AY31015_NB1:
608   case AY31015_NB2:
609   case AY31015_EPS:
610      ay31015->pins[pin] = data;
611      if ( ay31015->pins[AY31015_CS] )
612         ay31015_transfer_control_pins( device );
613      break;
608614   }
609615}
610616
611617
618/*-------------------------------------------------
619    ay31015_get_output_pin - get the status of an output pin
620-------------------------------------------------*/
621int ay31015_get_output_pin( const device_config *device, ay31015_output_pin_t pin )
622{
623   ay31015_t   *ay31015 = get_safe_token(device);
612624
613#if 0
625   return ay31015->pins[pin];
626}
614627
615void
616   ay31015_token *ay = get_token(device);
617   const ay31015_config *config = get_config(device);
618628
629INLINE void ay31015_update_rx_timer( const device_config *device )
630{
631   ay31015_t   *ay31015 = get_safe_token( device );
619632
633   if ( ay31015->rx_clock > 0.0 )
634   {
635      timer_adjust_periodic( ay31015->rx_timer, ATTOTIME_IN_HZ( ay31015->rx_clock ), 0, ATTOTIME_IN_HZ( ay31015->rx_clock ) );
636   }
637   else
638   {
639      timer_enable( ay31015->rx_timer, 0 );
640   }
641}
642
643
644INLINE void ay31015_update_tx_timer( const device_config *device )
645{
646   ay31015_t   *ay31015 = get_safe_token( device );
647
648   if ( ay31015->tx_clock > 0.0 )
649   {
650      timer_adjust_periodic( ay31015->tx_timer, ATTOTIME_IN_HZ( ay31015->tx_clock ), 0, ATTOTIME_IN_HZ( ay31015->tx_clock ) );
651   }
652   else
653   {
654      timer_enable( ay31015->tx_timer, 0 );
655   }
656}
657
658
620659/*-------------------------------------------------
660    ay31015_set_receiver_clock - set receive clock
661-------------------------------------------------*/
662void ay31015_set_receiver_clock( const device_config *device, double new_clock )
663{
664   ay31015_t   *ay31015 = get_safe_token(device);
665
666   ay31015->rx_clock = new_clock;
667   ay31015_update_rx_timer( device );
668}
669
670
671/*-------------------------------------------------
672    ay31015_set_transmitter_clock - set transmit clock
673-------------------------------------------------*/
674void ay31015_set_transmitter_clock( const device_config *device, double new_clock )
675{
676   ay31015_t   *ay31015 = get_safe_token(device);
677
678   ay31015->tx_clock = new_clock;
679   ay31015_update_tx_timer( device );
680}
681
682
683/*-------------------------------------------------
684    ay31015_get_received_data - return a byte to the computer
685-------------------------------------------------*/
686UINT8 ay31015_get_received_data( const device_config *device )
687{
688   ay31015_t   *ay31015 = get_safe_token(device);
689
690   return ay31015->rx_buffer;
691}
692
693
694/*-------------------------------------------------
695    ay31015_set_transmit_data - accept a byte to transmit, if able
696-------------------------------------------------*/
697void ay31015_set_transmit_data( const device_config *device, UINT8 data )
698{
699   ay31015_t   *ay31015 = get_safe_token(device);
700
701   if (ay31015->status_reg & STATUS_TBMT)
702   {
703      ay31015->tx_buffer = data;
704      ay31015->status_reg &= ~STATUS_TBMT;
705      ay31015_update_status_pins( device );
706   }
707}
708
709
710static DEVICE_START(ay31015)
711{
712   ay31015_t   *ay31015 = get_safe_token(device);
713
714   ay31015->config = device->static_config;
715
716   ay31015->tx_clock = ay31015->config->transmitter_clock;
717   ay31015->rx_clock = ay31015->config->receiver_clock;
718
719   ay31015->rx_timer = timer_alloc( ay31015_rx_process, (void *)device );
720   ay31015->tx_timer = timer_alloc( ay31015_tx_process, (void *)device );
721
722   ay31015_update_rx_timer( device );
723   ay31015_update_tx_timer( device );
724
725   return DEVICE_START_OK;
726}
727
728
729static DEVICE_RESET( ay31015 )
730{
731   ay31015_t   *ay31015 = get_safe_token(device);
732
733   ay31015->control_reg = 0;
734   ay31015->rx_data = 0;
735
736   ay31015_reset( device );
737}
738
739
740static DEVICE_SET_INFO( ay31015 )
741{
742   switch ( state )
743   {
744      /* no parameters to set */
745   }
746}
747
748
749/*-------------------------------------------------
621750    DEVICE_GET_INFO(ay31015) - device getinfo
622751   function
623752-------------------------------------------------*/
624753
625DEVICE_GET_INFO(ay31015)
754DEVICE_GET_INFO( ay31015 )
626755{
627756   switch(state)
628757   {
629758      /* --- the following bits of info are returned as 64-bit signed integers --- */
630      case DEVINFO_INT_TOKEN_BYTES:         info->i = sizeof(ay31015_token); break;
631      case DEVINFO_INT_INLINE_CONFIG_BYTES:      info->i = 0; break;
632      case DEVINFO_INT_CLASS:            info->i = DEVICE_CLASS_PERIPHERAL; break;
633      case DEVINFO_INT_IMAGE_TYPE:         info->i = IO_PRINTER; break;
634      case DEVINFO_INT_IMAGE_READABLE:      info->i = 0; break;
635      case DEVINFO_INT_IMAGE_WRITEABLE:      info->i = 1; break;
636      case DEVINFO_INT_IMAGE_CREATABLE:      info->i = 1; break;
759      case DEVINFO_INT_TOKEN_BYTES:         info->i = sizeof(ay31015_t);               break;
760      case DEVINFO_INT_INLINE_CONFIG_BYTES:   info->i = 0;                           break;
761      case DEVINFO_INT_CLASS:               info->i = DEVICE_CLASS_PERIPHERAL;            break;
637762
638763      /* --- the following bits of info are returned as pointers to data or functions --- */
639      case DEVINFO_FCT_START:            info->start = DEVICE_START_NAME(ay31015); break;
764      case DEVINFO_FCT_SET_INFO:            info->set_info = DEVICE_SET_INFO_NAME(ay31015);   break;
765      case DEVINFO_FCT_START:               info->start = DEVICE_START_NAME(ay31015);      break;
766      case DEVINFO_FCT_STOP:               /* nothing */                           break;
767      case DEVINFO_FCT_RESET:               info->reset = DEVICE_RESET_NAME( ay31015 );      break;
640768
641769      /* --- the following bits of info are returned as NULL-terminated strings --- */
642      case DEVINFO_STR_NAME:            info->s = "ay31015"; break;
643      case DEVINFO_STR_FAMILY:         info->s = "ay31015"; break;
644      case DEVINFO_STR_SOURCE_FILE:         info->s = __FILE__; break;
645      case DEVINFO_STR_IMAGE_FILE_EXTENSIONS:      info->s = "prn"; break;
770      case DEVINFO_STR_NAME:               info->s = "AY-3-1015";                     break;
771      case DEVINFO_STR_FAMILY:            info->s = "AY-3-1015/AY-5-1013 UARTs";         break;
772      case DEVINFO_STR_VERSION:            info->s = "1.00";                        break;
773      case DEVINFO_STR_SOURCE_FILE:         info->s = __FILE__;                        break;
774      case DEVINFO_STR_CREDITS:            info->s = "Copyright the MAME and MESS Teams";   break;
646775   }
647776}
648#endif
649777
src/mess/machine/ay31015.h
r3334r3335
44
55*/
66
7/* control reg */
8#define AY31015_NB1   0x01
9#define AY31015_NB2   0x02
10#define AY31015_TSB   0x04
11#define AY31015_EPS   0x08
12#define AY31015_NP   0x10
7#ifndef __AY31015_H_
8#define __AY31015_H_
139
14/* status reg */
15#define AY31015_TBMT   0x01
16#define AY31015_DAV   0x02
17#define AY31015_OR   0x04
18#define AY31015_FE   0x08
19#define AY31015_PE   0x10
20#define AY31015_EOC   0x20
10/***************************************************************************
11    TYPE DEFINITIONS
12***************************************************************************/
2113
22#define AY31015_SO   0x40
2314
24// Reset the device
25void ay51013_init( void );
15typedef enum
16{
17   /* For AY-3-1014A, AY-3-1015(D) and HD6402 variants */
18   AY_3_1015,
2619
27// Set Control register
28void ay51013_cs( UINT8 data );
20   /* For AY-3-1014, AY-5-1013 and AY-6-1013 variants */
21   AY_5_1013
22} ay31015_type_t;
2923
30// Reset the device
31void ay31015_init( void );
3224
33// Set Control register
34void ay31015_cs( UINT8 data );
25typedef enum
26{
27   AY31015_SWE=16,         /* -SWE  - Pin 16 - Status word enable */
28   AY31015_RDAV=18,      /* -RDAV - Pin 18 - Reset data available */
29   AY31015_SI=20,         /*  SI   - Pin 20 - Serial input */
30   AY31015_XR=21,         /*  XR   - Pin 21 - External reset */
31   AY31015_CS=34,         /*  CS   - Pin 34 - Control strobe */
32   AY31015_NP=35,         /*  NP   - Pin 35 - No parity */
33   AY31015_TSB=36,         /*  TSB  - Pin 36 - Number of stop bits */
34   AY31015_NB1=37,         /*  NB1  - Pin 37 - Number of bits #1 */
35   AY31015_NB2=38,         /*  NB2  - Pin 38 - Number of bits #2 */
36   AY31015_EPS=39         /*  EPS  - Pin 39 - Odd/Even parity select */
37} ay31015_input_pin_t;
3538
36// Set Receive Clock
37void ay31015_set_rx_clock_speed( UINT32 data );
3839
39// Read status register
40UINT8 ay31015_swe( void );
40typedef enum
41{
42   AY31015_PE=13,         /* PE   - Pin 13 - Parity error */
43   AY31015_FE=14,         /* FE   - Pin 14 - Framing error */
44   AY31015_OR=15,         /* OR   - Pin 15 - Over-run */
45   AY31015_DAV=19,         /* DAV  - Pin 19 - Data available */
46   AY31015_TBMT=22,      /* TBMT - Pin 22 - Transmit buffer empty */
47   AY31015_EOC=24,         /* EOC  - Pin 24 - End of character */
48   AY31015_SO=25         /* SO   - Pin 25 - Serial output */
49} ay31015_output_pin_t;
4150
42// Send a bit to the device
43void ay31015_si( UINT8 data );
4451
45// Read a byte from the device
46UINT8 ay31015_rde( void );
52typedef struct _ay31015_config   ay31015_config;
53struct _ay31015_config
54{
55   ay31015_type_t      type;               /* Type of chip */
56   double            transmitter_clock;      /* TCP - pin 40 */
57   double            receiver_clock;         /* RCP - pin 17 */
58   read8_device_func   read_si;            /* SI - pin 20 - This will be called whenever the SI pin is sampled. Optional */
59   write8_device_func   write_so;            /* SO - pin 25 - This will be called whenever data is put on the SO pin. Optional */
60   write8_device_func   status_changed;         /* This will be called whenever one of the status pins may have changed. Optional */
61};
4762
48// Tell device you have read the data
49void ay31015_rdav( void );
5063
51// Set Transmit Clock
52void ay31015_set_tx_clock_speed( UINT32 data );
64/***************************************************************************
65    DEVICE CONFIGURATION MACROS
66***************************************************************************/
5367
54// Get serialised output
55UINT8 ay31015_so( void );
68#define MDRV_AY31015_ADD(_tag, _config)   \
69    MDRV_DEVICE_ADD(_tag, AY31015)      \
70    MDRV_DEVICE_CONFIG(_config)
5671
57// Send a byte to the device
58void ay31015_ds( UINT8 data );
72#define MDRV_AY31015_REMOVE(_tag)      \
73    MDRV_DEVICE_REMOVE(_tag, AY31015)
74
75
76/***************************************************************************
77    FUNCTION PROTOTYPES
78***************************************************************************/
79
80/* Set an input pin */
81void ay31015_set_input_pin( const device_config *device, ay31015_input_pin_t pin, int data );
82
83
84/* Get an output pin */
85int ay31015_get_output_pin( const device_config *device, ay31015_output_pin_t pin );
86
87
88/* Set a new transmitter clock (new_clock is in Hz) */
89void ay31015_set_transmitter_clock( const device_config *device, double new_clock );
90
91
92/* Set a new receiver clock (new_clock is in Hz) */
93void ay31015_set_receiver_clock( const device_config *device, double new_clock );
94
95
96/* Reead the received data */
97/* The received data is available on RD8-RD1 (pins 5-12) */
98UINT8 ay31015_get_received_data( const device_config *device );
99
100
101/* Set the transmitter buffer */
102/* The data to transmit is set on DB1-DB8 (pins 26-33) */
103void ay31015_set_transmit_data( const device_config *device, UINT8 data );
104
105
106/***************************************************************************
107    DEVICE INTERFACE
108***************************************************************************/
109
110#define AY31015 DEVICE_GET_INFO_NAME( ay31015 )
111DEVICE_GET_INFO( ay31015 );
112
113#endif
src/mess/drivers/exidy.c
r3334r3335
150150#include "machine/ay31015.h"
151151
152152
153static const device_config *exidy_ay31015;
154
155
153156static Z80BIN_EXECUTE( exidy );
154157
155158static DEVICE_IMAGE_LOAD( exidy_floppy )
r3334r3335
203206      return device_list_find_by_tag( machine->config->devicelist, CASSETTE, "cassette1" );
204207}
205208
206static UINT8 cass_data[]={ 0, 0, 0, 0, 0, 0, 0 };
207209
210static struct {
211   struct {
212      int length;      /* time cassette level is at input.level */
213      int level;      /* cassette level */
214      int bit;      /* bit being read */
215   } input;
216   struct {
217      int length;      /* time cassette level is at output.level */
218      int level;      /* cassette level */
219      int bit;      /* bit to to output */
220   } output;
221} cass_data;
222
223
208224static TIMER_CALLBACK(exidy_cassette_tc)
209225{
210226   UINT8 cass_ws = 0;
211   switch (exidy_fe & 0xc0)      // bit 7 low indicates cassette
227   switch (exidy_fe & 0xc0)      /*/ bit 7 low indicates cassette */
212228   {
213      case 0x00:            // cassette 300 baud - works
229      case 0x00:            /* Cassette 300 baud */
214230
215231         /* loading a tape - this is basically the same as the super80.
216232            We convert the 1200/2400 Hz signal to a 0 or 1, and send it to the uart. */
217233
218         cass_data[1]++;
234         cass_data.input.length++;
219235
220236         cass_ws = (cassette_input(cassette_device_image(machine)) > +0.02) ? 1 : 0;
221237
222         if (cass_ws != cass_data[0])
238         if (cass_ws != cass_data.input.level)
223239         {
224            cass_data[0] = cass_ws;
225            cass_data[2] = ((cass_data[1] < 0x6) || (cass_data[1] > 0x20)) ? 1 : 0;
226            cass_data[1] = 0;
227            if (cass_data[2] != cass_data[3])
228            {
229               ay31015_si(cass_data[2]);
230               cass_data[3] = cass_data[2];
231            }
240            cass_data.input.level = cass_ws;
241            cass_data.input.bit = ((cass_data.input.length < 0x6) || (cass_data.input.length > 0x20)) ? 1 : 0;
242            cass_data.input.length = 0;
243            ay31015_set_input_pin( exidy_ay31015, AY31015_SI, cass_data.input.bit );
232244         }
233245
234246         /* saving a tape - convert the serial stream from the uart, into 1200 and 2400 Hz frequencies.
235247            Synchronisation of the frequency pulses to the uart is extremely important. */
236248
237         cass_data[5]++;
238         if (!(cass_data[5] & 0x1f))
249         cass_data.output.length++;
250         if (!(cass_data.output.length & 0x1f))
239251         {
240            cass_ws = ay31015_so();
241            if (cass_ws != cass_data[4])
252            cass_ws = ay31015_get_output_pin( exidy_ay31015, AY31015_SO );
253            if (cass_ws != cass_data.output.bit)
242254            {
243               cass_data[4] = cass_ws;
244               cass_data[5]=0;
255               cass_data.output.bit = cass_ws;
256               cass_data.output.length = 0;
245257            }
246258         }
247259
248         if (!(cass_data[5] & 3))
260         if (!(cass_data.output.length & 3))
249261         {
250            if (!((cass_data[4] == 0) && (cass_data[5] & 4)))
262            if (!((cass_data.output.bit == 0) && (cass_data.output.length & 4)))
251263            {
252               cass_data[6] ^= 1;         // toggle output state, except on 2nd half of low bit
253               cassette_output(cassette_device_image(machine), cass_data[6] ? -1.0 : +1.0);
264               cass_data.output.level ^= 1;         // toggle output state, except on 2nd half of low bit
265               cassette_output(cassette_device_image(machine), cass_data.output.level ? -1.0 : +1.0);
254266            }
255267         }
256268         return;
257269
258      case 0x40:            // cassette 1200 baud - not working at this time
270      case 0x40:         /* Cassette 1200 baud */
259271         /* loading a tape */
260         cass_data[1]++;
272         cass_data.input.length++;
261273
262274         cass_ws = (cassette_input(cassette_device_image(machine)) > +0.02) ? 1 : 0;
263275
264         if (cass_ws != cass_data[0])
276         if (cass_ws != cass_data.input.level || cass_data.input.length == 10)
265277         {
266            cass_data[0] = cass_ws;
267            cass_data[2] = ((cass_data[1] < 0xc) || (cass_data[1] > 0x20)) ? 1 : 0;
268            cass_data[1] = 0;
269            if (cass_data[2] != cass_data[3])
278            cass_data.input.bit = ((cass_data.input.length < 10) || (cass_data.input.length > 0x20)) ? 1 : 0;
279            if ( cass_ws != cass_data.input.level )
270280            {
271               ay31015_si(cass_data[2]);
272               cass_data[3] = cass_data[2];
281               cass_data.input.length = 0;
282               cass_data.input.level = cass_ws;
273283            }
274            cass_data[2] = 0;
284            ay31015_set_input_pin( exidy_ay31015, AY31015_SI, cass_data.input.bit );
275285         }
276286
277287         /* saving a tape - convert the serial stream from the uart, into 600 and 1200 Hz frequencies. */
278288
279         cass_data[5]++;
280         if (!(cass_data[5] & 0x07))
289         cass_data.output.length++;
290         if (!(cass_data.output.length & 0x07))
281291         {
282            cass_ws = ay31015_so();
283            if (cass_ws != cass_data[4])
292            cass_ws = ay31015_get_output_pin( exidy_ay31015, AY31015_SO );
293            if (cass_ws != cass_data.output.bit)
284294            {
285               cass_data[4] = cass_ws;
286               cass_data[5]=0;
295               cass_data.output.bit = cass_ws;
296               cass_data.output.length = 0;
287297            }
288298         }
289299
290         if (!(cass_data[5] & 7))
300         if (!(cass_data.output.length & 7))
291301         {
292            if (!((cass_data[4] == 0) && (cass_data[5] & 8)))
302            if (!((cass_data.output.bit == 0) && (cass_data.output.length & 8)))
293303            {
294               cass_data[6] ^= 1;         // toggle output state, except on 2nd half of low bit
295               cassette_output(cassette_device_image(machine), cass_data[6] ? -1.0 : +1.0);
304               cass_data.output.level ^= 1;         // toggle output state, except on 2nd half of low bit
305               cassette_output(cassette_device_image(machine), cass_data.output.level ? -1.0 : +1.0);
296306            }
297307         }
298308         return;
r3334r3335
337347
338348static MACHINE_RESET( exidyd )
339349{
340   ay31015_init();
350   /* Initialize cassette interface */
351   cass_data.output.length = 0;
352   cass_data.output.level = 1;
353   cass_data.input.length = 0;
354   cass_data.input.bit = 1;
341355
356   exidy_ay31015 = device_list_find_by_tag( machine->config->devicelist, AY31015, "ay_3_1015" );
357
342358   centronics_config(0, exidy_cent_config);
343359   /* assumption: select is tied low */
344360   centronics_write_handshake(0, CENTRONICS_SELECT | CENTRONICS_NO_RESET, CENTRONICS_SELECT| CENTRONICS_NO_RESET);
r3334r3335
396412
397413static WRITE8_HANDLER(exidy_fc_port_w)
398414{
399   ay31015_ds( data );
415   ay31015_set_transmit_data( exidy_ay31015, data );
400416}
401417
402418
403419static WRITE8_HANDLER(exidy_fd_port_w)
404420{
405   ay31015_cs( data );
421   /* Translate data to control signals */
422
423   ay31015_set_input_pin( exidy_ay31015, AY31015_CS, 0 );
424   ay31015_set_input_pin( exidy_ay31015, AY31015_NB1, ( data & 0x01 ) ? 1 : 0 );
425   ay31015_set_input_pin( exidy_ay31015, AY31015_NB2, ( data & 0x02 ) ? 1 : 0 );
426   ay31015_set_input_pin( exidy_ay31015, AY31015_TSB, ( data & 0x04 ) ? 1 : 0 );
427   ay31015_set_input_pin( exidy_ay31015, AY31015_EPS, ( data & 0x08 ) ? 1 : 0 );
428   ay31015_set_input_pin( exidy_ay31015, AY31015_NP,  ( data & 0x10 ) ? 1 : 0 );
429   ay31015_set_input_pin( exidy_ay31015, AY31015_CS, 1 );
406430}
407431
408432#define EXIDY_CASSETTE_MOTOR_MASK ((1<<4)|(1<<5))
r3334r3335
455479   /* bit 6 */
456480   if (changed_bits & 0x40)
457481   {
458      ay31015_set_rx_clock_speed ((data & 0x40) ? 19200 : 4800);
459      ay31015_set_tx_clock_speed ((data & 0x40) ? 14400 : 4800);
482      ay31015_set_receiver_clock( exidy_ay31015, (data & 0x40) ? 19200.0 : 4800.0);
483      ay31015_set_transmitter_clock( exidy_ay31015, (data & 0x40) ? 19200.0 : 4800.0);
460484   }
461485
462486   /* bit 7 */
r3334r3335
495519
496520static READ8_HANDLER(exidy_fc_port_r)
497521{
498   UINT8 data = ay31015_rde();
499   ay31015_rdav();
522   UINT8 data = ay31015_get_received_data( exidy_ay31015 );
523   ay31015_set_input_pin( exidy_ay31015, AY31015_RDAV, 0 );
524   ay31015_set_input_pin( exidy_ay31015, AY31015_RDAV, 1 );
500525   return data;
501526}
502527
503528static READ8_HANDLER(exidy_fd_port_r)
504529{
505530   /* set unused bits high */
506   return ay31015_swe() | 0xe0;
531   UINT8 data = 0xe0;
532
533   ay31015_set_input_pin( exidy_ay31015, AY31015_SWE, 0 );
534   data |= ay31015_get_output_pin( exidy_ay31015, AY31015_TBMT ) ? 0x01 : 0;
535   data |= ay31015_get_output_pin( exidy_ay31015, AY31015_DAV  ) ? 0x02 : 0;
536   data |= ay31015_get_output_pin( exidy_ay31015, AY31015_OR   ) ? 0x04 : 0;
537   data |= ay31015_get_output_pin( exidy_ay31015, AY31015_FE   ) ? 0x08 : 0;
538   data |= ay31015_get_output_pin( exidy_ay31015, AY31015_PE   ) ? 0x10 : 0;
539   ay31015_set_input_pin( exidy_ay31015, AY31015_SWE, 1 );
540
541   return data;
507542}
508543
509544static READ8_HANDLER(exidy_fe_port_r)
r3334r3335
720755
721756/**********************************************************************************************************/
722757
758static const ay31015_config exidy_ay31015_config =
759{
760   AY_3_1015,
761   4800.0,
762   4800.0,
763   NULL,
764   NULL,
765   NULL
766};
767
768
723769static const cassette_config exidy_cassette_config =
724770{
725771   cassette_default_formats,
726772   NULL,
727   CASSETTE_STOPPED | CASSETTE_MOTOR_DISABLED | CASSETTE_SPEAKER_ENABLED
773   CASSETTE_PLAY | CASSETTE_MOTOR_DISABLED | CASSETTE_SPEAKER_ENABLED
728774};
729775
730776
r3334r3335
758804   MDRV_SOUND_ADD("speaker", SPEAKER, 0)
759805   MDRV_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.50)   // speaker on parallel port
760806
807   MDRV_AY31015_ADD( "ay_3_1015", exidy_ay31015_config )
808
761809   /* printer */
762810   MDRV_DEVICE_ADD("printer", PRINTER)
763811
docs/messnew.txt
r3334r3335
9090  we will start to use the correct ones. If you own a C128 PAL, please
9191  dump its BIOS to verify its content. [Fabio Priuli]
9292
93- [EXIDY] Added support for 1200 baud cassette images. [Wilbert Pol]
94
9395- [GENESIS / MD] Added possibility to choose between a 3 buttons and a 6
9496  buttons Joypad. [Fabio Priuli]
9597

Previous 15994 Revisions Next


© 1998-2018 The MESS Team