~ubuntu-branches/ubuntu/precise/mame/precise-proposed

« back to all changes in this revision

Viewing changes to src/lib/formats/ami_dsk.c

  • Committer: Package Import Robot
  • Author(s): Cesare Falco
  • Date: 2011-11-30 18:50:10 UTC
  • mfrom: (1.1.4)
  • Revision ID: package-import@ubuntu.com-20111130185010-02hcxybht1mn082w
Tags: 0.144-0ubuntu1
* New upstream release (LP: #913550)
* mame.install:
  - Added artwork/ images to be used with -effect switch
  - Be more selective with hash/ contents
* contrib/mame.ini: added /usr/share/games/mame/artwork/ to artpath

Show diffs side-by-side

added added

removed removed

Lines of Context:
6
6
 
7
7
*********************************************************************/
8
8
 
9
 
 
10
 
#include <string.h>
11
 
 
12
9
#include "formats/ami_dsk.h"
13
 
#include "formats/basicdsk.h"
14
 
 
15
 
 
16
 
 
17
 
/*****************************************************************************
18
 
 Amiga floppy core functions
19
 
*****************************************************************************/
20
 
 
21
 
 
22
 
static FLOPPY_IDENTIFY( amiga_dsk_identify )
23
 
{
24
 
        UINT64 size;
25
 
 
26
 
        *vote = 100;
27
 
 
28
 
        /* first check the size of the image */
29
 
        size = floppy_image_size(floppy);
30
 
        if ((size != 901120) && (size != 1802240))
31
 
                *vote = 0;
32
 
 
33
 
        return FLOPPY_ERROR_SUCCESS;
34
 
}
35
 
 
36
 
 
37
 
static FLOPPY_CONSTRUCT( amiga_dsk_construct )
38
 
{
39
 
        struct basicdsk_geometry geometry;
40
 
 
41
 
        /* setup geometry with standard values */
42
 
        memset(&geometry, 0, sizeof(geometry));
43
 
        geometry.heads = 2;
44
 
        geometry.tracks = 80;
45
 
        geometry.first_sector_id = 0;
46
 
        geometry.sector_length = 512;
47
 
 
48
 
        if (params)
49
 
        {
50
 
                /* create */
51
 
                geometry.sectors = option_resolution_lookup_int(params, PARAM_SECTORS);
52
 
        }
53
 
        else
54
 
        {
55
 
                /* open */
56
 
                UINT64 size = floppy_image_size(floppy);
57
 
                geometry.sectors = size/512/80/2;
58
 
                if (geometry.sectors != 11 && geometry.sectors != 22)
59
 
                        return FLOPPY_ERROR_INVALIDIMAGE;
60
 
        }
61
 
 
62
 
        return basicdsk_construct(floppy, &geometry);
63
 
}
64
 
 
65
 
 
66
 
 
67
 
/*****************************************************************************
68
 
 Amiga floppy options
69
 
*****************************************************************************/
70
 
 
71
 
 
72
 
FLOPPY_OPTIONS_START( amiga )
73
 
        FLOPPY_OPTION(
74
 
                ami_dsk,
75
 
                "adf",
76
 
                "Amiga floppy disk image",
77
 
                amiga_dsk_identify,
78
 
                amiga_dsk_construct,
79
 
                NULL,
80
 
                HEADS([2])
81
 
                TRACKS([80])
82
 
                SECTORS([11]/22)
83
 
        )
84
 
FLOPPY_OPTIONS_END
85
 
 
86
 
FLOPPY_OPTIONS_START( amiga_only )
87
 
        FLOPPY_OPTION(
88
 
                ami_dsk,
89
 
                "adf",
90
 
                "Amiga floppy disk image",
91
 
                amiga_dsk_identify,
92
 
                amiga_dsk_construct,
93
 
                NULL,
94
 
                HEADS([2])
95
 
                TRACKS([80])
96
 
                SECTORS([11]/22)
97
 
        )
98
 
FLOPPY_OPTIONS_END0
 
10
 
 
11
adf_format::adf_format() : floppy_image_format_t()
 
12
{
 
13
}
 
14
 
 
15
const char *adf_format::name() const
 
16
{
 
17
        return "adf";
 
18
}
 
19
 
 
20
const char *adf_format::description() const
 
21
{
 
22
        return "Amiga ADF floppy disk image";
 
23
}
 
24
 
 
25
const char *adf_format::extensions() const
 
26
{
 
27
        return "adf";
 
28
}
 
29
 
 
30
bool adf_format::supports_save() const
 
31
{
 
32
        return true;
 
33
}
 
34
 
 
35
int adf_format::identify(io_generic *io)
 
36
{
 
37
        UINT64 size = io_generic_size(io);
 
38
        if ((size == 901120) || (size == 1802240))
 
39
        {
 
40
                return 50;
 
41
        }
 
42
        return 0;
 
43
}
 
44
 
 
45
bool adf_format::load(io_generic *io, floppy_image *image)
 
46
{
 
47
        desc_s sectors[11];
 
48
        UINT8 sectdata[512*11];
 
49
        for(int i=0; i<11; i++) {
 
50
                sectors[i].data = sectdata + 512*i;
 
51
                sectors[i].size = 512;
 
52
                sectors[i].sector_id = i;
 
53
        }
 
54
 
 
55
        for(int track=0; track < 80; track++) {
 
56
                for(int side=0; side < 2; side++) {
 
57
                        io_generic_read(io, sectdata, (track*2 + side)*512*11, 512*11);
 
58
                        generate_track(amiga_11, track, side, sectors, 11, 100000, image);
 
59
                }
 
60
        }
 
61
 
 
62
        return true;
 
63
}
 
64
 
 
65
UINT32 adf_format::g32(const UINT8 *trackbuf, int track_size, int pos)
 
66
{
 
67
        if(pos >= 0 && track_size-pos >= 40) {
 
68
                int pp = pos >> 3;
 
69
                int dp = pos & 7;
 
70
                return
 
71
                        (trackbuf[pp] << (24+dp)) |
 
72
                        (trackbuf[pp+1] << (16+dp)) |
 
73
                        (trackbuf[pp+2] << (8+dp)) |
 
74
                        (trackbuf[pp+3] << dp) |
 
75
                        (trackbuf[pp+4] >> (8-dp));
 
76
        } else {
 
77
                UINT32 res = 0;
 
78
                for(int i=0; i<32; i++) {
 
79
                        int pp = (pos+i) % track_size;
 
80
                        if(trackbuf[pp>>3] & (0x80 >> (pp & 7)))
 
81
                                res |= 0x80000000 >> i;
 
82
                }
 
83
                return res;
 
84
        }
 
85
}
 
86
 
 
87
UINT32 adf_format::checksum(const UINT8 *trackbuf, int track_size, int pos, int long_count)
 
88
{
 
89
        UINT32 check = 0;
 
90
        for(int i=0; i<long_count; i++)
 
91
                check ^= g32(trackbuf, track_size, pos+32*i);
 
92
        return check & 0x55555555;
 
93
}
 
94
 
 
95
bool adf_format::save(io_generic *io, floppy_image *image)
 
96
{
 
97
        // TODO: HD support
 
98
        UINT8 sectdata[512*11];
 
99
        UINT8 trackbuf[150000/8];
 
100
        for(int track=0; track < 80; track++) {
 
101
                for(int side=0; side < 2; side++) {
 
102
                        int track_size;
 
103
                        generate_bitstream_from_track(track, side, 2000, trackbuf, track_size, image);
 
104
 
 
105
                        for(int i=0; i<track_size; i++)
 
106
                                if(g32(trackbuf, track_size, i) == 0x44894489 &&
 
107
                                   (g32(trackbuf, track_size, i+384) & 0x55555555) == checksum(trackbuf, track_size, i+32, 10) &&
 
108
                                   (g32(trackbuf, track_size, i+448) & 0x55555555) == checksum(trackbuf, track_size, i+480, 256)) {
 
109
 
 
110
                                        UINT32 head = ((g32(trackbuf, track_size, i+32) & 0x55555555) << 1) | (g32(trackbuf, track_size, i+64) & 0x55555555);
 
111
                                        int sect = (head >> 8) & 0xff;
 
112
                                        if(sect > 11)
 
113
                                                continue;
 
114
 
 
115
                                        UINT8 *dest = sectdata + 512*sect;
 
116
                                        for(int j=0; j<128; j++) {
 
117
                                                UINT32 val = ((g32(trackbuf, track_size, i+480+32*j) & 0x55555555) << 1) | (g32(trackbuf, track_size, i+4576+32*j) & 0x55555555);
 
118
                                                *dest++ = val >> 24;
 
119
                                                *dest++ = val >> 16;
 
120
                                                *dest++ = val >> 8;
 
121
                                                *dest++ = val;
 
122
                                        }
 
123
 
 
124
                                        io_generic_write(io, sectdata, (track*2 + side)*512*11, 512*11);
 
125
                                }
 
126
                }
 
127
        }
 
128
        return true;
 
129
}
 
130
 
 
131
const floppy_format_type FLOPPY_ADF_FORMAT = &floppy_image_format_creator<adf_format>;