Previous 15994 Revisions Next

r7490 Friday 5th March, 2010 at 00:23:15 UTC by Stefano Priore
[MICROTAN] Moved snapshot & quickload code to formats/
[src/mess/drivers]microtan.c
[src/mess/machine]microtan.c

src/mess/machine/microtan.c
r7489r7490
2424
2525/* Devices */
2626#include "devices/cassette.h"
27#include "devices/snapquik.h"
27//#include "devices/snapquik.h"
2828
2929
3030#ifndef VERBOSE
r7489r7490
416416    }
417417}
418418
419static int microtan_varify_snapshot(UINT8 *data, int size)
420{
421   if (size == 8263)
422   {
423      LOG(("microtan_snapshot_id: magic size %d found\n", size));
424      return IMAGE_VERIFY_PASS;
425   }
426   else
427   {
428      if (4 + data[2] + 256 * data[3] + 1 + 16 + 16 + 16 + 1 + 1 + 16 + 16 + 64 + 7 == size)
429      {
430         LOG(("microtan_snapshot_id: header RAM size + structures matches filesize %d\n", size));
431         return IMAGE_VERIFY_PASS;
432      }
433   }
434
435    return IMAGE_VERIFY_FAIL;
436}
437
438static int parse_intel_hex(UINT8 *snapshot_buff, char *src)
439{
440    char line[128];
441    int /*row = 0,*/ column = 0, last_addr = 0, last_size = 0;
442
443    while (*src)
444    {
445        if (*src == '\r' || *src == '\n')
446        {
447            if (column)
448            {
449                unsigned int size, addr, null, b[32], cs, n;
450
451                line[column] = '\0';
452                /*row++;*/
453                n = sscanf(line, ":%02x%04x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x",
454                    &size, &addr, &null,
455                    &b[ 0], &b[ 1], &b[ 2], &b[ 3], &b[ 4], &b[ 5], &b[ 6], &b[ 7],
456                    &b[ 8], &b[ 9], &b[10], &b[11], &b[12], &b[13], &b[14], &b[15],
457                    &b[16], &b[17], &b[18], &b[19], &b[20], &b[21], &b[22], &b[23],
458                    &b[24], &b[25], &b[26], &b[27], &b[28], &b[29], &b[30], &b[31],
459                    &cs);
460                if (n == 0)
461                {
462                    LOG(("parse_intel_hex: malformed line [%s]\n", line));
463                }
464                else if (n == 1)
465                {
466                    LOG(("parse_intel_hex: only size found [%s]\n", line));
467                }
468                else if (n == 2)
469                {
470                    LOG(("parse_intel_hex: only size and addr found [%s]\n", line));
471                }
472                else if (n == 3)
473                {
474                    LOG(("parse_intel_hex: only size, addr and null found [%s]\n", line));
475                }
476                else
477                if (null != 0)
478                {
479                    LOG(("parse_intel_hex: warning null byte is != 0 [%s]\n", line));
480                }
481                else
482                {
483                    int i, sum;
484
485                    n -= 3;
486
487                    sum = size + (addr & 0xff) + ((addr >> 8) & 0xff);
488                    if (n != 32 + 1)
489                        cs = b[n-1];
490
491                    last_addr = addr;
492                    last_size = n-1;
493                    LOG(("parse_intel_hex: %04X", addr));
494                    for (i = 0; i < n-1; i++)
495                    {
496                        sum += b[i];
497                        snapshot_buff[addr++] = b[i];
498                    }
499                    LOG(("-%04X checksum %02X+%02X = %02X\n", addr-1, cs, sum & 0xff, (cs + sum) & 0xff));
500                }
501            }
502            column = 0;
503        }
504        else
505        {
506            line[column++] = *src;
507        }
508        src++;
509    }
510    /* register preset? */
511    if (last_size == 7)
512    {
513        LOG(("parse_intel_hex: registers (?) at %04X\n", last_addr));
514        memcpy(&snapshot_buff[8192+64], &snapshot_buff[last_addr], last_size);
515    }
516    return INIT_PASS;
517}
518
519static int parse_zillion_hex(UINT8 *snapshot_buff, char *src)
520{
521    char line[128];
522    int parsing = 0, /*row = 0,*/ column = 0;
523
524    while (*src)
525    {
526        if (parsing)
527        {
528            if (*src == '}')
529                parsing = 0;
530            else
531            {
532                if (*src == '\r' || *src == '\n')
533                {
534                    if (column)
535                    {
536                        unsigned int addr, b[8], n;
537
538                        line[column] = '\0';
539                        /*row++;*/
540                        n = sscanf(line, "%x %x %x %x %x %x %x %x %x", &addr, &b[0], &b[1], &b[2], &b[3], &b[4], &b[5], &b[6], &b[7]);
541                        if (n == 0)
542                        {
543                            LOG(("parse_zillion_hex: malformed line [%s]\n", line));
544                        }
545                        else if (n == 1)
546                        {
547                            LOG(("parse_zillion_hex: only addr found [%s]\n", line));
548                        }
549                        else
550                        {
551                            int i;
552
553                            LOG(("parse_zillion_hex: %04X", addr));
554                            for (i = 0; i < n-1; i++)
555                                snapshot_buff[addr++] = b[i];
556                            LOG(("-%04X\n", addr-1));
557                        }
558                    }
559                    column = 0;
560                }
561                else
562                {
563                    line[column++] = *src;
564                }
565            }
566        }
567        else
568        {
569            if (*src == '\r' || *src == '\n')
570            {
571                if (column)
572                {
573                    int addr, n;
574
575                    /*row++;*/
576                    line[column] = '\0';
577                    n = sscanf(line, "G%x", (unsigned int *) &addr);
578                    if (n == 1 && !snapshot_buff[8192+64+1] && !snapshot_buff[8192+64+1])
579                    {
580                        LOG(("microtan_hexfile_init: go addr %04X\n", addr));
581                        snapshot_buff[8192+64+0] = addr & 0xff;
582                        snapshot_buff[8192+64+1] = (addr >> 8) & 0xff;
583                    }
584                }
585                column = 0;
586            }
587            else
588            {
589                line[column++] = *src;
590            }
591            if (*src == '{')
592            {
593                parsing = 1;
594                column = 0;
595            }
596        }
597        src++;
598    }
599    return INIT_PASS;
600}
601
602419static void store_key(running_machine *machine, int key)
603420{
604421    LOG(("microtan: store key '%c'\n", key));
r7489r7490
697514    }
698515}
699516
700static void microtan_set_cpu_regs(running_machine *machine,const UINT8 *snapshot_buff, int base)
701{
702    LOG(("microtan_snapshot_copy: PC:%02X%02X P:%02X A:%02X X:%02X Y:%02X SP:1%02X",
703        snapshot_buff[base+1], snapshot_buff[base+0], snapshot_buff[base+2], snapshot_buff[base+3],
704        snapshot_buff[base+4], snapshot_buff[base+5], snapshot_buff[base+6]);
705    cpu_set_reg(devtag_get_device(machine, "maincpu"), M6502_PC, snapshot_buff[base+0] + 256 * snapshot_buff[base+1]));
706    cpu_set_reg(devtag_get_device(machine, "maincpu"), M6502_P, snapshot_buff[base+2]);
707    cpu_set_reg(devtag_get_device(machine, "maincpu"), M6502_A, snapshot_buff[base+3]);
708    cpu_set_reg(devtag_get_device(machine, "maincpu"), M6502_X, snapshot_buff[base+4]);
709    cpu_set_reg(devtag_get_device(machine, "maincpu"), M6502_Y, snapshot_buff[base+5]);
710    cpu_set_reg(devtag_get_device(machine, "maincpu"), M6502_S, snapshot_buff[base+6]);
711}
712
713static void microtan_snapshot_copy(running_machine *machine, UINT8 *snapshot_buff, int snapshot_size)
714{
715    UINT8 *RAM = memory_region(machine, "maincpu");
716   const address_space *space = cputag_get_address_space(machine, "maincpu", ADDRESS_SPACE_PROGRAM);
717   running_device *via_0 = devtag_get_device(machine, "via6522_0");
718   running_device *via_1 = devtag_get_device(machine, "via6522_1");
719   running_device *ay8910 = devtag_get_device(machine, "ay8910.1");
720
721    /* check for .DMP file format */
722    if (snapshot_size == 8263)
723    {
724        int i, base;
725        /********** DMP format
726         * Lower 8k of RAM (0000 to 1fff)
727         * 64 bytes of chunky graphics bits (first byte bit is for character at 0200, bit 1=0201, etc)
728         * 7 bytes of CPU registers (PCL, PCH, PSW, A, IX, IY, SP)
729         */
730        LOG(("microtan_snapshot_copy: magic size %d found, assuming *.DMP format\n", snapshot_size));
731
732        base = 0;
733        /* 8K of RAM from 0000 to 1fff */
734        memcpy(RAM, &snapshot_buff[base], 8192);
735        base += 8192;
736        /* 64 bytes of chunky graphics info */
737        for (i = 0; i < 32*16; i++)
738        {
739            microtan_chunky_buffer[i] = (snapshot_buff[base+i/8] >> (i&7)) & 1;
740        }
741        base += 64;
742        microtan_set_cpu_regs(machine, snapshot_buff, base);
743    }
744    else
745    {
746        int i, ramend, base;
747        /********** M65 format ************************************
748         *  2 bytes: File version
749         *  2 bytes: RAM size
750         *  n bytes: RAM (0000 to RAM Size)
751         * 16 bytes: 1st 6522 (0xbfc0 to 0xbfcf)
752         * 16 bytes: 2ns 6522 (0xbfe0 to 0xbfef)
753         * 16 bytes: Microtan IO (0xbff0 to 0xbfff)
754         *  1 byte : Invaders sound (0xbc04)
755         *  1 byte : Chunky graphics state (0=off, 1=on)
756         * 16 bytes: 1st AY8910 registers
757         * 16 bytes: 2nd AY8910 registers
758         * 64 bytes: Chunky graphics bits (first byte bit 0 is for character at 0200, bit 1=0201, etc)
759         *  7 bytes: CPU registers (PCL, PCH, PSW, A, IX, IY, SP)
760         */
761        ramend = snapshot_buff[2] + 256 * snapshot_buff[3];
762        if (2 + 2 + ramend + 1 + 16 + 16 + 16 + 1 + 1 + 16 + 16 + 64 + 7 != snapshot_size)
763        {
764            LOG(("microtan_snapshot_copy: size %d doesn't match RAM size %d + structure size\n", snapshot_size, ramend+1));
765            return;
766        }
767
768        LOG(("microtan_snapshot_copy: size %d found, assuming *.M65 format\n", snapshot_size));
769        base = 4;
770        memcpy(RAM, &snapshot_buff[base], snapshot_buff[2] + 256 * snapshot_buff[3] + 1);
771        base += ramend + 1;
772
773        /* first set of VIA6522 registers */
774        for (i = 0; i < 16; i++ )
775            via_w(via_0, i, snapshot_buff[base++]);
776
777        /* second set of VIA6522 registers */
778        for (i = 0; i < 16; i++ )
779            via_w(via_1, i, snapshot_buff[base++]);
780
781        /* microtan IO bff0-bfff */
782        for (i = 0; i < 16; i++ )
783        {
784            RAM[0xbff0+i] = snapshot_buff[base++];
785            if (i < 4)
786                microtan_bffx_w(space, i, RAM[0xbff0+i]);
787        }
788
789        microtan_sound_w(space, 0, snapshot_buff[base++]);
790        microtan_chunky_graphics = snapshot_buff[base++];
791
792        /* first set of AY8910 registers */
793        for (i = 0; i < 16; i++ )
794        {
795            ay8910_address_w(ay8910, 0, i);
796            ay8910_data_w(ay8910, 0, snapshot_buff[base++]);
797        }
798
799        /* second set of AY8910 registers */
800        for (i = 0; i < 16; i++ )
801        {
802            ay8910_address_w(ay8910, 0, i);
803            ay8910_data_w(ay8910, 0, snapshot_buff[base++]);
804        }
805
806        for (i = 0; i < 32*16; i++)
807        {
808            microtan_chunky_buffer[i] = (snapshot_buff[base+i/8] >> (i&7)) & 1;
809        }
810        base += 64;
811
812        microtan_set_cpu_regs(machine, snapshot_buff, base);
813    }
814}
815
816SNAPSHOT_LOAD( microtan )
817{
818   UINT8 *snapshot_buff;
819
820   snapshot_buff = (UINT8*)image_ptr(image);
821   if (!snapshot_buff)
822      return INIT_FAIL;
823
824   if (microtan_varify_snapshot(snapshot_buff, snapshot_size)==IMAGE_VERIFY_FAIL)
825      return INIT_FAIL;
826
827   microtan_snapshot_copy(image->machine, snapshot_buff, snapshot_size);
828   return INIT_PASS;
829}
830
831QUICKLOAD_LOAD( microtan_hexfile )
832{
833   int snapshot_size;
834   UINT8 *snapshot_buff;
835   char *buff;
836   int rc;
837
838   snapshot_size = 8263;   /* magic size */
839   snapshot_buff = (UINT8*)malloc(snapshot_size);
840   if (!snapshot_buff)
841   {
842      LOG(("microtan_hexfile_load: could not allocate %d bytes of buffer\n", snapshot_size));
843      return INIT_FAIL;
844   }
845   memset(snapshot_buff, 0, snapshot_size);
846
847   buff = (char*)malloc(quickload_size + 1);
848   if (!buff)
849   {
850      free(snapshot_buff);
851      LOG(("microtan_hexfile_load: could not allocate %d bytes of buffer\n", quickload_size));
852      return INIT_FAIL;
853   }
854   image_fread(image, buff, quickload_size);
855
856    buff[quickload_size] = '\0';
857
858    if (buff[0] == ':')
859        rc = parse_intel_hex(snapshot_buff, buff);
860   else
861      rc = parse_zillion_hex(snapshot_buff, buff);
862   if (rc == INIT_PASS)
863      microtan_snapshot_copy(image->machine, snapshot_buff, snapshot_size);
864   free(snapshot_buff);
865   return rc;
866}
867
868517DRIVER_INIT( microtan )
869518{
870519    UINT8 *dst = memory_region(machine, "gfx2");
src/mess/drivers/microtan.c
r7489r7490
4949
5050/* Devices */
5151#include "devices/cassette.h"
52#include "formats/m65_snqk.h"
5253
5354
5455static ADDRESS_MAP_START( microtan_map, ADDRESS_SPACE_PROGRAM, 8 )
r7489r7490
251252
252253   /* snapshot/quickload */
253254   MDRV_SNAPSHOT_ADD("snapshot", microtan, "m65", 0.5)
254   MDRV_QUICKLOAD_ADD("quickload", microtan_hexfile, "hex", 0.5)
255   MDRV_QUICKLOAD_ADD("quickload", microtan, "hex", 0.5)
255256
256257   /* cassette */
257258   MDRV_CASSETTE_ADD( "cassette", default_cassette_config )

Previous 15994 Revisions Next


© 1998-2018 The MESS Team