Previous 199869 Revisions Next

r24774 Tuesday 6th August, 2013 at 15:23:27 UTC by Osso
Modernized decocass_tape device. (nw)
[src/mame/machine]decocass.c decocass_tape.c decocass_tape.h

trunk/src/mame/machine/decocass_tape.c
r24773r24774
88#include "cpu/m6502/m6502.h"
99#include "cpu/mcs48/mcs48.h"
1010#include "machine/decocass_tape.h"
11#include "devlegcy.h"
1211
1312#define LOG_CASSETTE_STATE      0
1413
r24773r24774
1615    CASSETTE DEVICE INTERFACE
1716***************************************************************************/
1817
19/* regions within the virtual tape */
20enum tape_region
21{
22   REGION_LEADER,              /* in clear leader section */
23   REGION_LEADER_GAP,          /* in gap between leader and BOT */
24   REGION_BOT,                 /* in BOT hole */
25   REGION_BOT_GAP,             /* in gap between BOT hole and data */
26   REGION_DATA_BLOCK_0,        /* in data block 0 */
27   REGION_DATA_BLOCK_255 = REGION_DATA_BLOCK_0 + 255,
28   REGION_EOT_GAP,             /* in gap between data and EOT hole */
29   REGION_EOT,                 /* in EOT hole */
30   REGION_TRAILER_GAP,         /* in gap between trailer and EOT */
31   REGION_TRAILER              /* in clear trailer section */
32};
33
34
35/* bytes within a data block on a virtual tape */
36enum tape_byte
37{
38   BYTE_PRE_GAP_0,             /* 34 bytes of gap, clock held to 0, no data */
39   BYTE_PRE_GAP_33 = BYTE_PRE_GAP_0 + 33,
40   BYTE_LEADIN,                /* 1 leadin byte, clocked value 0x00 */
41   BYTE_HEADER,                /* 1 header byte, clocked value 0xAA */
42   BYTE_DATA_0,                /* 256 bytes of data, clocked */
43   BYTE_DATA_255 = BYTE_DATA_0 + 255,
44   BYTE_CRC16_MSB,             /* 2 bytes of CRC, clocked MSB first, then LSB */
45   BYTE_CRC16_LSB,
46   BYTE_TRAILER,               /* 1 trailer byte, clocked value 0xAA */
47   BYTE_LEADOUT,               /* 1 leadout byte, clocked value 0x00 */
48   BYTE_LONGCLOCK,             /* 1 longclock byte, clock held to 1, no data */
49   BYTE_POSTGAP_0,             /* 34 bytes of gap, no clock, no data */
50   BYTE_POSTGAP_33 = BYTE_POSTGAP_0 + 33,
51   BYTE_BLOCK_TOTAL            /* total number of bytes in block */
52};
53
54
55/* state of the tape */
56struct tape_state
57{
58   running_machine *   machine;            /* pointer back to the machine */
59   emu_timer *         timer;              /* timer for running the tape */
60   INT8                speed;              /* speed: <-1=fast rewind, -1=reverse, 0=stopped, 1=normal, >1=fast forward */
61   tape_region         region;             /* current region */
62   tape_byte           bytenum;            /* byte number within a datablock */
63   UINT8               bitnum;             /* bit number within a byte */
64   UINT32              clockpos;           /* the current clock position of the tape */
65   UINT32              numclocks;          /* total number of clocks on the entire tape */
66   UINT16              crc16[256];         /* CRC16 for each block */
67};
68
69
7018/* number of tape clock pulses per second */
7119#define TAPE_CLOCKRATE                  4800
7220#define TAPE_CLOCKS_PER_BIT             2
r24773r24774
10452#define REGION_BOT_GAP_LEN_CLOCKS       TAPE_MSEC_TO_CLOCKS(300)    /* 300ms */
10553#define REGION_BOT_GAP_END_CLOCK        (REGION_BOT_GAP_START_CLOCK+REGION_BOT_GAP_LEN_CLOCKS)
10654
55static UINT16 tape_crc16_byte(UINT16 crc, UINT8 data);
10756
108/*-------------------------------------------------
109    get_safe_token - makes sure that the passed
110    in device is, in fact, an IDE controller
111-------------------------------------------------*/
57const device_type DECOCASS_TAPE = &device_creator<decocass_tape_device>;
11258
113INLINE tape_state *get_safe_token(device_t *device)
59decocass_tape_device::decocass_tape_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
60   : device_t(mconfig, DECOCASS_TAPE, "DECO Cassette Tape", tag, owner, clock, "decocass_tape", __FILE__),
61   m_tape_timer(NULL),
62   m_speed(0),
63   m_bitnum(0),
64   m_clockpos(0),
65   m_numclocks(0)
11466{
115   assert(device != NULL);
116   assert(device->type() == DECOCASS_TAPE);
67   for (int i = 0; i < 256; i++)
68   m_crc16[i] = 0;
69}
11770
118   return (tape_state *)downcast<decocass_tape_device *>(device)->token();
71//-------------------------------------------------
72//  device_config_complete - perform any
73//  operations now that the configuration is
74//  complete
75//-------------------------------------------------
76
77void decocass_tape_device::device_config_complete()
78{
11979}
12080
81//-------------------------------------------------
82//  device_start - device-specific startup
83//-------------------------------------------------
12184
85void decocass_tape_device::device_start()
86{
87   int curblock, offs, numblocks;
88
89   /* fetch the data pointer */
90   m_tape_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(decocass_tape_device::tape_clock_callback), this));
91   if (region() == NULL)
92      return;
93   UINT8 *regionbase = *region();
94
95   /* scan for the first non-empty block in the image */
96   for (offs = region()->bytes() - 1; offs >= 0; offs--)
97      if (regionbase[offs] != 0)
98         break;
99   numblocks = ((offs | 0xff) + 1) / 256;
100   assert(numblocks < ARRAY_LENGTH(m_crc16));
101
102   /* compute the total length */
103   m_numclocks = REGION_BOT_GAP_END_CLOCK + numblocks * BYTE_BLOCK_TOTAL * 16 + REGION_BOT_GAP_END_CLOCK;
104
105   /* compute CRCs for each block */
106   for (curblock = 0; curblock < numblocks; curblock++)
107   {
108      UINT16 crc = 0;
109      int testval;
110
111      /* first CRC the 256 bytes of data */
112      for (offs = 256 * curblock; offs < 256 * curblock + 256; offs++)
113         crc = tape_crc16_byte(crc, regionbase[offs]);
114
115      /* then find a pair of bytes that will bring the CRC to 0 (any better way than brute force?) */
116      for (testval = 0; testval < 0x10000; testval++)
117         if (tape_crc16_byte(tape_crc16_byte(crc, testval >> 8), testval) == 0)
118            break;
119      m_crc16[curblock] = testval;
120   }
121
122   /* register states */
123   save_item(NAME(m_speed));
124   save_item(NAME(m_bitnum));
125   save_item(NAME(m_clockpos));
126}
127
128//-------------------------------------------------
129//  device_reset - device-specific reset
130//-------------------------------------------------
131
132void decocass_tape_device::device_reset()
133{
134   /* turn the tape off */
135   change_speed(0);
136}
137
122138/*-------------------------------------------------
123139    tape_crc16_byte - accumulate 8 bits worth of
124140    CRC data
r24773r24774
139155   return crc;
140156}
141157
142
143158/*-------------------------------------------------
144159    tape_describe_state - create a string that
145160    describes the state of the tape
146161-------------------------------------------------*/
147162
148static const char *tape_describe_state(tape_state *tape)
163const char *decocass_tape_device::describe_state()
149164{
150165   static char buffer[40];
151166   char temprname[40];
152167   const char *rname = temprname;
153168
154   if (tape->region == REGION_LEADER)
169   if (m_region == REGION_LEADER)
155170      rname = "LEAD";
156   else if (tape->region == REGION_LEADER_GAP)
171   else if (m_region == REGION_LEADER_GAP)
157172      rname = "LGAP";
158   else if (tape->region == REGION_BOT)
173   else if (m_region == REGION_BOT)
159174      rname = "BOT ";
160   else if (tape->region == REGION_BOT_GAP)
175   else if (m_region == REGION_BOT_GAP)
161176      rname = "BGAP";
162   else if (tape->region == REGION_TRAILER)
177   else if (m_region == REGION_TRAILER)
163178      rname = "TRLR";
164   else if (tape->region == REGION_TRAILER_GAP)
179   else if (m_region == REGION_TRAILER_GAP)
165180      rname = "TGAP";
166   else if (tape->region == REGION_EOT)
181   else if (m_region == REGION_EOT)
167182      rname = "EOT ";
168   else if (tape->region == REGION_EOT_GAP)
183   else if (m_region == REGION_EOT_GAP)
169184      rname = "EGAP";
170185   else
171186   {
r24773r24774
173188      const char *bname = tempbname;
174189      int clk;
175190
176      if (tape->bytenum <= BYTE_PRE_GAP_33)
177         sprintf(tempbname, "PR%02d", tape->bytenum - BYTE_PRE_GAP_0);
178      else if (tape->bytenum == BYTE_LEADIN)
191      if (m_bytenum <= BYTE_PRE_GAP_33)
192         sprintf(tempbname, "PR%02d", m_bytenum - BYTE_PRE_GAP_0);
193      else if (m_bytenum == BYTE_LEADIN)
179194         bname = "LDIN";
180      else if (tape->bytenum == BYTE_HEADER)
195      else if (m_bytenum == BYTE_HEADER)
181196         bname = "HEAD";
182      else if (tape->bytenum <= BYTE_DATA_255)
183         sprintf(tempbname, "BY%02X", tape->bytenum - BYTE_DATA_0);
184      else if (tape->bytenum == BYTE_CRC16_MSB)
197      else if (m_bytenum <= BYTE_DATA_255)
198         sprintf(tempbname, "BY%02X", m_bytenum - BYTE_DATA_0);
199      else if (m_bytenum == BYTE_CRC16_MSB)
185200         bname = "CRCM";
186      else if (tape->bytenum == BYTE_CRC16_LSB)
201      else if (m_bytenum == BYTE_CRC16_LSB)
187202         bname = "CRCL";
188      else if (tape->bytenum == BYTE_TRAILER)
203      else if (m_bytenum == BYTE_TRAILER)
189204         bname = "TRLR";
190      else if (tape->bytenum == BYTE_LEADOUT)
205      else if (m_bytenum == BYTE_LEADOUT)
191206         bname = "LOUT";
192      else if (tape->bytenum == BYTE_LONGCLOCK)
207      else if (m_bytenum == BYTE_LONGCLOCK)
193208         bname = "LONG";
194209      else
195         sprintf(tempbname, "PO%02d", tape->bytenum - BYTE_POSTGAP_0);
210         sprintf(tempbname, "PO%02d", m_bytenum - BYTE_POSTGAP_0);
196211
197212      /* in the main data area, the clock alternates at the clock rate */
198      if (tape->bytenum >= BYTE_LEADIN && tape->bytenum <= BYTE_LEADOUT)
199         clk = ((UINT32)(tape->clockpos - REGION_BOT_GAP_END_CLOCK) & 1) ? 0 : 1;
200      else if (tape->bytenum == BYTE_LONGCLOCK)
213      if (m_bytenum >= BYTE_LEADIN && m_bytenum <= BYTE_LEADOUT)
214         clk = ((UINT32)(m_clockpos - REGION_BOT_GAP_END_CLOCK) & 1) ? 0 : 1;
215      else if (m_bytenum == BYTE_LONGCLOCK)
201216         clk = 1;
202217      else
203218         clk = 0;
204219
205      sprintf(temprname, "BL%02X.%4s.%d.%d", tape->region - REGION_DATA_BLOCK_0, bname, tape->bitnum, clk);
220      sprintf(temprname, "BL%02X.%4s.%d.%d", m_region - REGION_DATA_BLOCK_0, bname, m_bitnum, clk);
206221   }
207222
208   sprintf(buffer, "{%9d=%s}", tape->clockpos, rname);
223   sprintf(buffer, "{%9d=%s}", m_clockpos, rname);
209224   return buffer;
210225}
211226
r24773r24774
215230    to increment/decrement the tape location
216231-------------------------------------------------*/
217232
218static TIMER_CALLBACK( tape_clock_callback )
233TIMER_CALLBACK_MEMBER( decocass_tape_device::tape_clock_callback )
219234{
220   device_t *device = (device_t *)ptr;
221   tape_state *tape = get_safe_token(device);
222
223235   /* advance by one clock in the desired direction */
224   if (tape->speed < 0 && tape->clockpos > 0)
225      tape->clockpos--;
226   else if (tape->speed > 0 && tape->clockpos < tape->numclocks)
227      tape->clockpos++;
236   if (m_speed < 0 && m_clockpos > 0)
237      m_clockpos--;
238   else if (m_speed > 0 && m_clockpos < m_numclocks)
239      m_clockpos++;
228240
229241   /* look for states before the start of data */
230   if (tape->clockpos < REGION_LEADER_END_CLOCK)
231      tape->region = REGION_LEADER;
232   else if (tape->clockpos < REGION_LEADER_GAP_END_CLOCK)
233      tape->region = REGION_LEADER_GAP;
234   else if (tape->clockpos < REGION_BOT_END_CLOCK)
235      tape->region = REGION_BOT;
236   else if (tape->clockpos < REGION_BOT_GAP_END_CLOCK)
237      tape->region = REGION_BOT_GAP;
242   if (m_clockpos < REGION_LEADER_END_CLOCK)
243      m_region = REGION_LEADER;
244   else if (m_clockpos < REGION_LEADER_GAP_END_CLOCK)
245      m_region = REGION_LEADER_GAP;
246   else if (m_clockpos < REGION_BOT_END_CLOCK)
247      m_region = REGION_BOT;
248   else if (m_clockpos < REGION_BOT_GAP_END_CLOCK)
249      m_region = REGION_BOT_GAP;
238250
239251   /* look for states after the end of data */
240   else if (tape->clockpos >= tape->numclocks - REGION_LEADER_END_CLOCK)
241      tape->region = REGION_TRAILER;
242   else if (tape->clockpos >= tape->numclocks - REGION_LEADER_GAP_END_CLOCK)
243      tape->region = REGION_TRAILER_GAP;
244   else if (tape->clockpos >= tape->numclocks - REGION_BOT_END_CLOCK)
245      tape->region = REGION_EOT;
246   else if (tape->clockpos >= tape->numclocks - REGION_BOT_GAP_END_CLOCK)
247      tape->region = REGION_EOT_GAP;
252   else if (m_clockpos >= m_numclocks - REGION_LEADER_END_CLOCK)
253      m_region = REGION_TRAILER;
254   else if (m_clockpos >= m_numclocks - REGION_LEADER_GAP_END_CLOCK)
255      m_region = REGION_TRAILER_GAP;
256   else if (m_clockpos >= m_numclocks - REGION_BOT_END_CLOCK)
257      m_region = REGION_EOT;
258   else if (m_clockpos >= m_numclocks - REGION_BOT_GAP_END_CLOCK)
259      m_region = REGION_EOT_GAP;
248260
249261   /* everything else is data */
250262   else
251263   {
252      UINT32 dataclock = tape->clockpos - REGION_BOT_GAP_END_CLOCK;
264      UINT32 dataclock = m_clockpos - REGION_BOT_GAP_END_CLOCK;
253265
254266      /* compute the block number */
255      tape->region = (tape_region)(REGION_DATA_BLOCK_0 + dataclock / (TAPE_CLOCKS_PER_BYTE * BYTE_BLOCK_TOTAL));
256      dataclock -= (tape->region - REGION_DATA_BLOCK_0) * TAPE_CLOCKS_PER_BYTE * BYTE_BLOCK_TOTAL;
267      m_region = (tape_region)(REGION_DATA_BLOCK_0 + dataclock / (TAPE_CLOCKS_PER_BYTE * BYTE_BLOCK_TOTAL));
268      dataclock -= (m_region - REGION_DATA_BLOCK_0) * TAPE_CLOCKS_PER_BYTE * BYTE_BLOCK_TOTAL;
257269
258270      /* compute the byte within the block */
259      tape->bytenum = (tape_byte)(dataclock / TAPE_CLOCKS_PER_BYTE);
260      dataclock -= tape->bytenum * TAPE_CLOCKS_PER_BYTE;
271      m_bytenum = (tape_byte)(dataclock / TAPE_CLOCKS_PER_BYTE);
272      dataclock -= m_bytenum * TAPE_CLOCKS_PER_BYTE;
261273
262274      /* compute the bit within the byte */
263      tape->bitnum = dataclock / TAPE_CLOCKS_PER_BIT;
275      m_bitnum = dataclock / TAPE_CLOCKS_PER_BIT;
264276   }
265277
266278   /* log */
267279   if (LOG_CASSETTE_STATE)
268      tape_describe_state(tape);
280      describe_state();
269281}
270282
271283
r24773r24774
274286    bits from the tape
275287-------------------------------------------------*/
276288
277UINT8 tape_get_status_bits(device_t *device)
289UINT8 decocass_tape_device::get_status_bits()
278290{
279   tape_state *tape = get_safe_token(device);
280291   UINT8 tape_bits = 0;
281292
282293   /* bit 0x20 is the BOT/EOT signal, which is also set in the leader/trailer area */
283   if (tape->region == REGION_LEADER || tape->region == REGION_BOT || tape->region == REGION_EOT || tape->region == REGION_TRAILER)
294   if (m_region == REGION_LEADER || m_region == REGION_BOT || m_region == REGION_EOT || m_region == REGION_TRAILER)
284295      tape_bits |= 0x20;
285296
286297   /* bit 0x40 is the clock, which is only valid in some areas of the data block */
287298   /* bit 0x80 is the data, which is only valid in some areas of the data block */
288   if (tape->region >= REGION_DATA_BLOCK_0 && tape->region <= REGION_DATA_BLOCK_255)
299   if (m_region >= REGION_DATA_BLOCK_0 && m_region <= REGION_DATA_BLOCK_255)
289300   {
290      int blocknum = tape->region - REGION_DATA_BLOCK_0;
301      int blocknum = m_region - REGION_DATA_BLOCK_0;
291302      UINT8 byteval = 0x00;
292303
293304      /* in the main data area, the clock alternates at the clock rate */
294      if (tape->bytenum >= BYTE_LEADIN && tape->bytenum <= BYTE_LEADOUT)
295         tape_bits |= ((UINT32)(tape->clockpos - REGION_BOT_GAP_END_CLOCK) & 1) ? 0x00 : 0x40;
305      if (m_bytenum >= BYTE_LEADIN && m_bytenum <= BYTE_LEADOUT)
306         tape_bits |= ((UINT32)(m_clockpos - REGION_BOT_GAP_END_CLOCK) & 1) ? 0x00 : 0x40;
296307
297308      /* in the longclock area, the clock holds high */
298      else if (tape->bytenum == BYTE_LONGCLOCK)
309      else if (m_bytenum == BYTE_LONGCLOCK)
299310         tape_bits |= 0x40;
300311
301312      /* everywhere else, the clock holds to 0 */
r24773r24774
303314         ;
304315
305316      /* lead-in and lead-out bytes are 0xAA */
306      if (tape->bytenum == BYTE_HEADER || tape->bytenum == BYTE_TRAILER)
317      if (m_bytenum == BYTE_HEADER || m_bytenum == BYTE_TRAILER)
307318         byteval = 0xaa;
308319
309320      /* data block bytes are data */
310      else if (tape->bytenum >= BYTE_DATA_0 && tape->bytenum <= BYTE_DATA_255)
311         byteval = static_cast<UINT8 *>(*device->region())[blocknum * 256 + (tape->bytenum - BYTE_DATA_0)];
321      else if (m_bytenum >= BYTE_DATA_0 && m_bytenum <= BYTE_DATA_255)
322         byteval = static_cast<UINT8 *>(*region())[blocknum * 256 + (m_bytenum - BYTE_DATA_0)];
312323
313324      /* CRC MSB */
314      else if (tape->bytenum == BYTE_CRC16_MSB)
315         byteval = tape->crc16[blocknum] >> 8;
325      else if (m_bytenum == BYTE_CRC16_MSB)
326         byteval = m_crc16[blocknum] >> 8;
316327
317328      /* CRC LSB */
318      else if (tape->bytenum == BYTE_CRC16_LSB)
319         byteval = tape->crc16[blocknum];
329      else if (m_bytenum == BYTE_CRC16_LSB)
330         byteval = m_crc16[blocknum];
320331
321332      /* select the appropriate bit from the byte and move to the upper bit */
322      if ((byteval >> tape->bitnum) & 1)
333      if ((byteval >> m_bitnum) & 1)
323334         tape_bits |= 0x80;
324335   }
325336   return tape_bits;
r24773r24774
331342    present
332343-------------------------------------------------*/
333344
334UINT8 tape_is_present(device_t *device)
345UINT8 decocass_tape_device::is_present()
335346{
336   return device->region() != NULL;
347   return region() != NULL;
337348}
338349
339350
r24773r24774
342353    playback
343354-------------------------------------------------*/
344355
345void tape_change_speed(device_t *device, INT8 newspeed)
356void decocass_tape_device::change_speed(INT8 newspeed)
346357{
347   tape_state *tape = get_safe_token(device);
348358   attotime newperiod;
349359   INT8 absnewspeed;
350360
351361   /* do nothing if speed has not changed */
352   if (tape->speed == newspeed)
362   if (m_speed == newspeed)
353363      return;
354364
355365   /* compute how fast to run the tape timer */
r24773r24774
360370      newperiod = attotime::from_hz(TAPE_CLOCKRATE * absnewspeed);
361371
362372   /* set the new speed */
363   tape->timer->adjust(newperiod, 0, newperiod);
364   tape->speed = newspeed;
373   m_tape_timer->adjust(newperiod, 0, newperiod);
374   m_speed = newspeed;
365375}
366
367
368/*-------------------------------------------------
369    device start callback
370-------------------------------------------------*/
371
372static DEVICE_START( decocass_tape )
373{
374   tape_state *tape = get_safe_token(device);
375   int curblock, offs, numblocks;
376
377   /* validate some basic stuff */
378   assert(device != NULL);
379   assert(device->static_config() == NULL);
380
381   /* fetch the data pointer */
382   tape->timer = device->machine().scheduler().timer_alloc(FUNC(tape_clock_callback), (void *)device);
383   if (device->region() == NULL)
384      return;
385   UINT8 *regionbase = *device->region();
386
387   /* scan for the first non-empty block in the image */
388   for (offs = device->region()->bytes() - 1; offs >= 0; offs--)
389      if (regionbase[offs] != 0)
390         break;
391   numblocks = ((offs | 0xff) + 1) / 256;
392   assert(numblocks < ARRAY_LENGTH(tape->crc16));
393
394   /* compute the total length */
395   tape->numclocks = REGION_BOT_GAP_END_CLOCK + numblocks * BYTE_BLOCK_TOTAL * 16 + REGION_BOT_GAP_END_CLOCK;
396
397   /* compute CRCs for each block */
398   for (curblock = 0; curblock < numblocks; curblock++)
399   {
400      UINT16 crc = 0;
401      int testval;
402
403      /* first CRC the 256 bytes of data */
404      for (offs = 256 * curblock; offs < 256 * curblock + 256; offs++)
405         crc = tape_crc16_byte(crc, regionbase[offs]);
406
407      /* then find a pair of bytes that will bring the CRC to 0 (any better way than brute force?) */
408      for (testval = 0; testval < 0x10000; testval++)
409         if (tape_crc16_byte(tape_crc16_byte(crc, testval >> 8), testval) == 0)
410            break;
411      tape->crc16[curblock] = testval;
412   }
413
414   /* register states */
415   device->save_item(NAME(tape->speed));
416   device->save_item(NAME(tape->bitnum));
417   device->save_item(NAME(tape->clockpos));
418}
419
420
421/*-------------------------------------------------
422    device reset callback
423-------------------------------------------------*/
424
425static DEVICE_RESET( decocass_tape )
426{
427   /* turn the tape off */
428   tape_change_speed(device, 0);
429}
430
431
432const device_type DECOCASS_TAPE = &device_creator<decocass_tape_device>;
433
434decocass_tape_device::decocass_tape_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
435   : device_t(mconfig, DECOCASS_TAPE, "DECO Cassette Tape", tag, owner, clock, "decocass_tape", __FILE__)
436{
437   m_token = global_alloc_clear(tape_state);
438}
439
440//-------------------------------------------------
441//  device_config_complete - perform any
442//  operations now that the configuration is
443//  complete
444//-------------------------------------------------
445
446void decocass_tape_device::device_config_complete()
447{
448}
449
450//-------------------------------------------------
451//  device_start - device-specific startup
452//-------------------------------------------------
453
454void decocass_tape_device::device_start()
455{
456   DEVICE_START_NAME( decocass_tape )(this);
457}
458
459//-------------------------------------------------
460//  device_reset - device-specific reset
461//-------------------------------------------------
462
463void decocass_tape_device::device_reset()
464{
465   DEVICE_RESET_NAME( decocass_tape )(this);
466}
trunk/src/mame/machine/decocass_tape.h
r24773r24774
55{
66public:
77   decocass_tape_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
8   ~decocass_tape_device() { global_free(m_token); }
8   ~decocass_tape_device() {}
99
10   // access to legacy token
11   void *token() const { assert(m_token != NULL); return m_token; }
10   UINT8 get_status_bits();
11   UINT8 is_present();
12   void change_speed(INT8 newspeed);
13   
1214protected:
1315   // device-level overrides
1416   virtual void device_config_complete();
1517   virtual void device_start();
1618   virtual void device_reset();
19   
1720private:
21   /* regions within the virtual tape */
22   enum tape_region
23   {
24      REGION_LEADER,              /* in clear leader section */
25      REGION_LEADER_GAP,          /* in gap between leader and BOT */
26      REGION_BOT,                 /* in BOT hole */
27      REGION_BOT_GAP,             /* in gap between BOT hole and data */
28      REGION_DATA_BLOCK_0,        /* in data block 0 */
29      REGION_DATA_BLOCK_255 = REGION_DATA_BLOCK_0 + 255,
30      REGION_EOT_GAP,             /* in gap between data and EOT hole */
31      REGION_EOT,                 /* in EOT hole */
32      REGION_TRAILER_GAP,         /* in gap between trailer and EOT */
33      REGION_TRAILER              /* in clear trailer section */
34   };
35
36
37   /* bytes within a data block on a virtual tape */
38   enum tape_byte
39   {
40      BYTE_PRE_GAP_0,             /* 34 bytes of gap, clock held to 0, no data */
41      BYTE_PRE_GAP_33 = BYTE_PRE_GAP_0 + 33,
42      BYTE_LEADIN,                /* 1 leadin byte, clocked value 0x00 */
43      BYTE_HEADER,                /* 1 header byte, clocked value 0xAA */
44      BYTE_DATA_0,                /* 256 bytes of data, clocked */
45      BYTE_DATA_255 = BYTE_DATA_0 + 255,
46      BYTE_CRC16_MSB,             /* 2 bytes of CRC, clocked MSB first, then LSB */
47      BYTE_CRC16_LSB,
48      BYTE_TRAILER,               /* 1 trailer byte, clocked value 0xAA */
49      BYTE_LEADOUT,               /* 1 leadout byte, clocked value 0x00 */
50      BYTE_LONGCLOCK,             /* 1 longclock byte, clock held to 1, no data */
51      BYTE_POSTGAP_0,             /* 34 bytes of gap, no clock, no data */
52      BYTE_POSTGAP_33 = BYTE_POSTGAP_0 + 33,
53      BYTE_BLOCK_TOTAL            /* total number of bytes in block */
54   };
55   
1856   // internal state
19   void *m_token;
57   emu_timer *         m_tape_timer;              /* timer for running the tape */
58   INT8                m_speed;              /* speed: <-1=fast rewind, -1=reverse, 0=stopped, 1=normal, >1=fast forward */
59   tape_region         m_region;             /* current region */
60   tape_byte           m_bytenum;            /* byte number within a datablock */
61   UINT8               m_bitnum;             /* bit number within a byte */
62   UINT32              m_clockpos;           /* the current clock position of the tape */
63   UINT32              m_numclocks;          /* total number of clocks on the entire tape */
64   UINT16              m_crc16[256];         /* CRC16 for each block */
65   
66   const char *describe_state();
67   TIMER_CALLBACK_MEMBER( tape_clock_callback );
2068};
2169
2270extern const device_type DECOCASS_TAPE;
2371
24UINT8 tape_get_status_bits(device_t *device);
25UINT8 tape_is_present(device_t *device);
26void tape_change_speed(device_t *device, INT8 newspeed);
27
28
2972#define MCFG_DECOCASS_TAPE_ADD(_tag) \
3073   MCFG_DEVICE_ADD(_tag, DECOCASS_TAPE, 0)
3174
trunk/src/mame/machine/decocass.c
r24773r24774
932932   /* E5x2-E5x3 and mirrors */
933933   if (2 == (offset & E5XX_MASK))
934934   {
935      UINT8 bot_eot = (tape_get_status_bits(m_cassette) >> 5) & 1;
935      UINT8 bot_eot = (m_cassette->get_status_bits() >> 5) & 1;
936936
937937      data =
938938         (BIT(m_i8041_p1, 7)   << 0) |   /* D0 = P17 - REQ/ */
r24773r24774
942942         ((bot_eot)            << 4) |   /* D4 = BOT/EOT (direct from drive) */
943943         (1                    << 5) |   /* D5 floating input */
944944         (1                    << 6) |   /* D6 floating input */
945         (!tape_is_present(m_cassette) << 7);    /* D7 = cassette present */
945         (!m_cassette->is_present() << 7);    /* D7 = cassette present */
946946
947947      LOG(4,("%10s 6502-PC: %04x decocass_e5xx_r(%02x): $%02x <- STATUS (%s%s%s%s%s%s%s%s)\n",
948948         space.machine().time().as_string(6),
r24773r24774
14681468         newspeed = (data & 0x04) ? -1 : -7;
14691469      else if ((data & 0x30) == 0x10)
14701470         newspeed = (data & 0x04) ? 1 : 7;
1471      tape_change_speed(m_cassette, newspeed);
1471      m_cassette->change_speed(newspeed);
14721472   }
14731473
14741474   m_i8041_p1 = data;
r24773r24774
15221522{
15231523   UINT8 data;
15241524
1525   data = (m_i8041_p2 & ~0xe0) | tape_get_status_bits(m_cassette);
1525   data = (m_i8041_p2 & ~0xe0) | m_cassette->get_status_bits();
15261526
15271527   if (data != m_i8041_p2_read_latch)
15281528   {

Previous 199869 Revisions Next


© 1997-2024 The MAME Team