Previous 199869 Revisions Next

r18976 Thursday 15th November, 2012 at 20:19:53 UTC by O. Galibert
(mess) floppy: Add IMD support [O. Galibert]
[src/lib/formats]flopimg.c flopimg.h imd_dsk.c
[src/mess/drivers]apc.c

trunk/src/lib/formats/imd_dsk.c
r18975r18976
273273   return FLOPPY_ERROR_SUCCESS;
274274}
275275
276
277/***************************************************************************
278
279    Copyright Olivier Galibert
280    All rights reserved.
281
282    Redistribution and use in source and binary forms, with or without
283    modification, are permitted provided that the following conditions are
284    met:
285
286        * Redistributions of source code must retain the above copyright
287          notice, this list of conditions and the following disclaimer.
288        * Redistributions in binary form must reproduce the above copyright
289          notice, this list of conditions and the following disclaimer in
290          the documentation and/or other materials provided with the
291          distribution.
292        * Neither the name 'MAME' nor the names of its contributors may be
293          used to endorse or promote products derived from this software
294          without specific prior written permission.
295
296    THIS SOFTWARE IS PROVIDED BY AARON GILES ''AS IS'' AND ANY EXPRESS OR
297    IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
298    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
299    DISCLAIMED. IN NO EVENT SHALL AARON GILES BE LIABLE FOR ANY DIRECT,
300    INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
301    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
302    SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
303    HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
304    STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
305    IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
306    POSSIBILITY OF SUCH DAMAGE.
307
308****************************************************************************/
309
310/*********************************************************************
311
312    formats/imd_dsk.h
313
314    IMD disk images
315
316*********************************************************************/
317
318#include "emu.h"
319#include "imd_dsk.h"
320
321imd_format::imd_format()
322{
323}
324
325const char *imd_format::name() const
326{
327   return "imd";
328}
329
330const char *imd_format::description() const
331{
332   return "IMD disk image";
333}
334
335const char *imd_format::extensions() const
336{
337   return "imd";
338}
339
340void imd_format::fixnum(char *start, char *end) const
341{
342   end--;
343   if(*end != '0')
344      return;
345   while(end > start) {
346      end--;
347      if(*end == ' ')
348         *end = '0';
349      else if(*end != '0')
350         return;
351   };
352}
353
354int imd_format::identify(io_generic *io, UINT32 form_factor)
355{
356   char h[32];
357
358   io_generic_read(io, h, 0, 31);
359   h[31] = 0;
360   for(int i=0; i != 31; i++)
361      if(h[i] >= '0' && h[i] <= '9')\
362         h[i] = '0';
363
364   fixnum(h+10, h+12);
365   fixnum(h+13, h+15);
366   fixnum(h+16, h+20);
367   fixnum(h+21, h+23);
368   fixnum(h+24, h+26);
369   fixnum(h+27, h+29);
370
371   if(!strcmp(h, "IMD 0.00: 00/00/0000 00:00:00\015\012"))
372      return 100;
373
374   return 0;
375}
376
377//  1.1.1.1.1.1.0.0  - fc
378// 1.1.0.1.0.1.1.1
379// f77a
380
381//  1.1.1.1.1.1.1.0  - fe
382// 1.1.0.0.0.1.1.1
383// f57e
384
385//  1.1.1.1.1.0.1.1  - fb
386// 1.1.0.0.0.1.1.1
387// f56f
388
389//  1.1.1.1.1.0.0.0  - f8
390// 1.1.0.0.0.1.1.1
391// f56a
392
393bool imd_format::load(io_generic *io, UINT32 form_factor, floppy_image *image)
394{
395   int size = io_generic_size(io);
396   UINT8 *img = global_alloc_array(UINT8, size);
397   io_generic_read(io, img, 0, size);
398
399   int pos;
400   for(pos=0; pos < size && img[pos] != 0x1a; pos++);
401   pos++;
402
403   if(pos >= size)
404      return false;
405
406   while(pos < size) {
407      UINT8 mode = img[pos++];
408      UINT8 track = img[pos++];
409      UINT8 head = img[pos++];
410      UINT8 sector_count = img[pos++];
411      UINT8 ssize = img[pos++];
412
413      if(ssize == 0xff)
414         throw emu_fatalerror("imd_format: Unsupported variable sector size on track %d head %d", track, head);
415
416      UINT32 size = ssize < 7 ? 128 << ssize : 8192;
417
418      static const int rates[3] = { 500000, 300000, 250000 };
419      bool fm = mode < 3;
420      int rate = rates[mode % 3];
421      int rpm = form_factor == floppy_image::FF_8 || (floppy_image::FF_525 && rate >= 300) ? 360 : 300;
422      int cell_count = (fm ? 1 : 2)*rate*60/rpm;
423
424      const UINT8 *snum = img+pos;
425      pos += sector_count;
426      const UINT8 *tnum = head & 0x80 ? img+pos : NULL;
427      if(tnum)
428         pos += sector_count;
429      const UINT8 *hnum = head & 0x40 ? img+pos : NULL;
430      if(hnum)
431         pos += sector_count;
432
433      head &= 0x3f;
434
435      UINT32 *track_data = global_alloc_array(UINT32, cell_count+10000);
436      int tpos = 0;
437
438      // gap 4a , IAM and gap 1
439      if(fm) {
440         for(int i=0; i<40; i++) fm_w(track_data, tpos, 8, 0xff);
441         for(int i=0; i< 6; i++) fm_w(track_data, tpos, 8, 0x00);
442         raw_w(track_data, tpos, 16, 0xf77a);
443         for(int i=0; i<26; i++) fm_w(track_data, tpos, 8, 0xff);
444      } else {
445         for(int i=0; i<80; i++) mfm_w(track_data, tpos, 8, 0x4e);
446         for(int i=0; i<12; i++) mfm_w(track_data, tpos, 8, 0x00);
447         for(int i=0; i< 3; i++) raw_w(track_data, tpos, 16, 0x5224);
448         mfm_w(track_data, tpos, 8, 0xfc);
449         for(int i=0; i<50; i++) mfm_w(track_data, tpos, 8, 0x4e);
450      }
451
452      // Compute the available and expected size for gap3
453      int gap3 = form_factor == floppy_image::FF_8 ? 25 :
454         ssize < 512 ?
455         (form_factor == floppy_image::FF_35 ? 54 : 50) :
456         (form_factor == floppy_image::FF_35 ? 84 : 80);
457
458      int etpos = tpos;
459      if(fm)
460         etpos += sector_count*(6+5+2+11+6+1+ssize+2)*16;
461      else
462         etpos += sector_count*(12+3+5+2+22+12+3+1+ssize+2)*16;
463
464      if(etpos > cell_count)
465         throw emu_fatalerror("imd_format: Incorrect layout on track %d head %d, expected_size=%d, current_size=%d", track, head, cell_count, etpos);
466
467      if(etpos + gap3*16*(sector_count-1) > cell_count)
468         gap3 = (cell_count - etpos) / 16 / (sector_count-1);
469
470      // Build the track
471      if(fm) {
472         for(int i=0; i<sector_count; i++) {
473            UINT8 stype = img[pos++];
474
475            int cpos;
476            UINT16 crc;
477            // sync and IDAM and gap 2
478            for(int j=0; j< 6; j++) fm_w(track_data, tpos, 8, 0xff);
479            cpos = tpos;
480            raw_w(track_data, tpos, 8, 0xf57e);
481            fm_w (track_data, tpos, 8, tnum ? tnum[i] : track);
482            fm_w (track_data, tpos, 8, hnum ? hnum[i] : head);
483            fm_w (track_data, tpos, 8, snum[i]);
484            fm_w (track_data, tpos, 8, ssize);
485            crc = calc_crc_ccitt(track_data, cpos, tpos);
486            fm_w (track_data, tpos, 16, crc);
487            for(int j=0; j<11; j++) fm_w(track_data, tpos, 8, 0xff);
488
489            if(stype == 0 || stype > 8)
490               for(int j=0; j<6+1+size+2+gap3; j++) fm_w(track_data, tpos, 8, 0xff);
491
492            else {
493               // sync, DAM, data and gap 3
494               for(int j=0; j< 6; j++) fm_w(track_data, tpos, 8, 0xff);
495               cpos = tpos;
496               raw_w(track_data, tpos, 8, stype == 3 || stype == 4 || stype == 7 || stype == 8 ? 0xf56a : 0xf56f);
497               if(stype == 2 || stype == 4 || stype == 6 || stype == 8) {
498                  for(int j=0; j<size; j++) fm_w(track_data, tpos, 8, img[pos]);
499                  pos++;
500               } else
501                  for(int j=0; j<size; j++) fm_w(track_data, tpos, 8, img[pos++]);
502               crc = calc_crc_ccitt(track_data, cpos, tpos);
503               if(stype == 5 || stype == 6 || stype == 7 || stype == 8)
504                  crc = 0xffff^crc;
505               fm_w(track_data, tpos, 16, crc);
506               for(int j=0; j<gap3; j++) fm_w(track_data, tpos, 8, 0xff);
507            }
508         }
509
510         // Gap 4b
511
512         while(tpos < cell_count-15) fm_w(track_data, tpos, 8, 0xff);
513         raw_w(track_data, tpos, cell_count-tpos, 0xffff >> (16+tpos-cell_count));
514
515      } else {
516         for(int i=0; i<sector_count; i++) {
517            UINT8 stype = img[pos++];
518
519            int cpos;
520            UINT16 crc;
521            // sync and IDAM and gap 2
522            for(int j=0; j<12; j++) mfm_w(track_data, tpos, 8, 0x00);
523            cpos = tpos;
524            for(int j=0; j< 3; j++) raw_w(track_data, tpos, 16, 0x4489);
525            mfm_w(track_data, tpos, 8, 0xfe);
526            mfm_w(track_data, tpos, 8, tnum ? tnum[i] : track);
527            mfm_w(track_data, tpos, 8, hnum ? hnum[i] : head);
528            mfm_w(track_data, tpos, 8, snum[i]);
529            mfm_w(track_data, tpos, 8, ssize);
530            crc = calc_crc_ccitt(track_data, cpos, tpos);
531            mfm_w(track_data, tpos, 16, crc);
532            for(int j=0; j<22; j++) mfm_w(track_data, tpos, 8, 0x4e);
533
534            if(stype == 0 || stype > 8)
535               for(int j=0; j<12+4+size+2+gap3; j++) mfm_w(track_data, tpos, 8, 0x4e);
536
537            else {
538               // sync, DAM, data and gap 3
539               for(int j=0; j<12; j++) mfm_w(track_data, tpos, 8, 0x00);
540               cpos = tpos;
541               for(int j=0; j< 3; j++) raw_w(track_data, tpos, 16, 0x4489);
542               mfm_w(track_data, tpos, 8, stype == 3 || stype == 4 || stype == 7 || stype == 8 ? 0xf8 : 0xfb);
543               if(stype == 2 || stype == 4 || stype == 6 || stype == 8) {
544                  for(int j=0; j<size; j++) mfm_w(track_data, tpos, 8, img[pos]);
545                  pos++;
546               } else
547                  for(int j=0; j<size; j++) mfm_w(track_data, tpos, 8, img[pos++]);
548               if(stype == 5 || stype == 6 || stype == 7 || stype == 8)
549                  crc = 0xffff^crc;
550               crc = calc_crc_ccitt(track_data, cpos, tpos);
551               mfm_w(track_data, tpos, 16, crc);
552               for(int j=0; j<gap3; j++) mfm_w(track_data, tpos, 8, 0x4e);
553            }
554         }
555
556         // Gap 4b
557
558         while(tpos < cell_count-15) mfm_w(track_data, tpos, 8, 0x4e);
559         raw_w(track_data, tpos, cell_count-tpos, 0x9254 >> (16+tpos-cell_count));
560      }
561
562      generate_track_from_levels(track, head, track_data, cell_count, 0, image);
563      global_free(track_data);
564   }
565
566   global_free(img);
567   return true;
568}
569
570
571bool imd_format::supports_save() const
572{
573   return false;
574}
575
576const floppy_format_type FLOPPY_IMD_FORMAT = &floppy_image_format_creator<imd_format>;
trunk/src/lib/formats/flopimg.c
r18975r18976
11901190   }
11911191}
11921192
1193void floppy_image_format_t::fm_w(UINT32 *buffer, int &offset, int n, UINT32 val, UINT32 size)
1194{
1195   int prec = offset ? bit_r(buffer, offset-1) : 0;
1196   for(int i=n-1; i>=0; i--) {
1197      int bit = (val >> i) & 1;
1198      bit_w(buffer, offset++, true);
1199      bit_w(buffer, offset++, bit, size);
1200      prec = bit;
1201   }
1202}
1203
11931204void floppy_image_format_t::mfm_half_w(UINT32 *buffer, int &offset, int start_bit, UINT32 val, UINT32 size)
11941205{
11951206   int prec = offset ? bit_r(buffer, offset-1) : 0;
trunk/src/lib/formats/flopimg.h
r18975r18976
510510   UINT16 calc_crc_ccitt(const UINT32 *buffer, int start, int end);
511511   //! Write a series of (raw) bits and increment the offset.
512512   void raw_w(UINT32 *buffer, int &offset, int n, UINT32 val, UINT32 size = 1000);
513   //! FM-encode and write a series of bits
514   void fm_w(UINT32 *buffer, int &offset, int n, UINT32 val, UINT32 size = 1000);
513515   //! MFM-encode and write a series of bits
514516   void mfm_w(UINT32 *buffer, int &offset, int n, UINT32 val, UINT32 size = 1000);
515517   //! MFM-encode every two bits and write
trunk/src/mess/drivers/apc.c
r18975r18976
6060#include "imagedev/flopdrv.h"
6161#include "formats/mfi_dsk.h"
6262#include "formats/d88_dsk.h"
63#include "formats/imd_dsk.h"
6364//#include "sound/ay8910.h"
6465
6566class apc_state : public driver_device
r18975r18976
606607
607608static const floppy_format_type apc_floppy_formats[] = {
608609   FLOPPY_D88_FORMAT,
610   FLOPPY_IMD_FORMAT,
609611   FLOPPY_MFI_FORMAT,
610   NULL // TODO: IMD
612   NULL
611613};
612614
613615static SLOT_INTERFACE_START( apc_floppies )
r18975r18976
647649   MCFG_SCREEN_REFRESH_RATE(60)
648650   MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(2500))
649651   MCFG_SCREEN_UPDATE_DRIVER(apc_state, screen_update)
650   MCFG_SCREEN_SIZE(32*8, 32*8)
651   MCFG_SCREEN_VISIBLE_AREA(0*8, 32*8-1, 0*8, 32*8-1)
652   MCFG_SCREEN_SIZE(640, 494)
653   MCFG_SCREEN_VISIBLE_AREA(0*8, 640-1, 0*8, 494-1)
652654
653655   MCFG_GFXDECODE(apc)
654656

Previous 199869 Revisions Next


© 1997-2024 The MAME Team