diff options
author | Olivier Galibert <galibert@pobox.com> | 2011-09-03 20:51:25 +0000 |
---|---|---|
committer | Olivier Galibert <galibert@pobox.com> | 2011-09-03 20:51:25 +0000 |
commit | e2a6f1fee2673486260a084609489decfc13b483 (patch) | |
tree | d761fae7a026d10c975c5cece46a7e6b9c4026bf | |
parent | bbef8c906300016c0aa5df4bdfb4bd1d4c2f5d5f (diff) |
st_dsk: Add the easy ST formats [O. Galibert]
-rw-r--r-- | src/lib/formats/flopimg.h | 1 | ||||
-rw-r--r-- | src/lib/formats/st_dsk.c | 195 | ||||
-rw-r--r-- | src/lib/formats/st_dsk.h | 40 |
3 files changed, 234 insertions, 2 deletions
diff --git a/src/lib/formats/flopimg.h b/src/lib/formats/flopimg.h index 2827e67ba76..ff6a697eb94 100644 --- a/src/lib/formats/flopimg.h +++ b/src/lib/formats/flopimg.h @@ -387,7 +387,6 @@ private: UINT16 tracks; UINT8 sides; - UINT16 rpm; UINT32 *cell_data[MAX_FLOPPY_SIDES * MAX_FLOPPY_TRACKS]; UINT32 track_size[MAX_FLOPPY_SIDES * MAX_FLOPPY_TRACKS]; diff --git a/src/lib/formats/st_dsk.c b/src/lib/formats/st_dsk.c index 0208116459a..b91173d7021 100644 --- a/src/lib/formats/st_dsk.c +++ b/src/lib/formats/st_dsk.c @@ -8,7 +8,7 @@ #include "formats/st_dsk.h" -st_gen_format::st_gen_format() : floppy_image_format_t() +st_gen_format::st_gen_format() { } @@ -602,3 +602,196 @@ const floppy_image_format_t::desc_e *const st_gen_format::desc_fcp_11[] = { desc_fcp_11_9, desc_fcp_11_10, }; + +void st_gen_format::generate(int track, int head, int track_count, int head_count, UINT8 *buffer, int sector_count, floppy_image *image) +{ + desc_s sectors[11]; + for(int i=0; i<sector_count; i++) { + sectors[i].data = buffer + 512*i; + sectors[i].size = 512; + } + + const desc_e *desc = 0; + switch(sector_count) { + case 9: + desc = desc_fcp_9; + break; + case 10: + desc = desc_fcp_10[(track*head_count + head) % 10]; + break; + case 11: + desc = desc_fcp_11[(track*head_count + head) % 11]; + break; + } + + generate_track(desc, track, head, sectors, sector_count, 100000, image); +} + +st_format::st_format() +{ +} + +const char *st_format::name() const +{ + return "st"; +} + +const char *st_format::description() const +{ + return "Atari ST floppy disk image"; +} + +const char *st_format::extensions() const +{ + return "st"; +} + +bool st_format::supports_save() const +{ + return false; +} + +void st_format::find_size(floppy_image *image, int &track_count, int &head_count, int §or_count) +{ + int size = image->image_size(); + for(track_count=80; track_count <= 82; track_count++) + for(head_count=1; head_count <= 2; head_count++) + for(sector_count=9; sector_count <= 11; sector_count++) + if(size == 512*track_count*head_count*sector_count) + return; + track_count = head_count = sector_count = 0; +} + +int st_format::identify(floppy_image *image) +{ + int track_count, head_count, sector_count; + find_size(image, track_count, head_count, sector_count); + + if(track_count) + return 50; + return 0; +} + +bool st_format::load(floppy_image *image) +{ + UINT8 sectdata[11*512]; + int track_count, head_count, sector_count; + find_size(image, track_count, head_count, sector_count); + + image->set_meta_data(track_count, head_count); + int track_size = sector_count*512; + for(int track=0; track < track_count; track++) { + for(int side=0; side < head_count; side++) { + image->image_read(sectdata, (track*head_count + side)*track_size, track_size); + generate(track, side, track_count, head_count, sectdata, sector_count, image); + } + } + + return TRUE; +} + +msa_format::msa_format() +{ +} + +const char *msa_format::name() const +{ + return "msa"; +} + +const char *msa_format::description() const +{ + return "Atari MSA floppy disk image"; +} + +const char *msa_format::extensions() const +{ + return "msa"; +} + +bool msa_format::supports_save() const +{ + return false; +} + +void msa_format::read_header(floppy_image *image, UINT16 &sign, UINT16 §, UINT16 &head, UINT16 &strack, UINT16 &etrack) +{ + UINT8 h[10]; + image->image_read(h, 0, 10); + sign = (h[0] << 8) | h[1]; + sect = (h[2] << 8) | h[3]; + head = (h[4] << 8) | h[5]; + strack = (h[6] << 8) | h[7]; + etrack = (h[8] << 8) | h[9]; +} + +bool msa_format::uncompress(UINT8 *buffer, int csize, int usize) +{ + UINT8 sectdata[11*512]; + int src=0, dst=0; + while(src<csize && dst<usize) { + unsigned char c = buffer[src++]; + if(c == 0xe5) { + if(csize-src < 3) + return false; + c = buffer[src++]; + int count = (buffer[src] << 8) | buffer[src+1]; + if(usize-dst < count) + return false; + for(int i=0; i<count; i++) + sectdata[dst++] = c; + } else + sectdata[dst++] = c; + } + if(src != csize || dst != usize) + return false; + memcpy(buffer, sectdata, usize); + return true; +} + +int msa_format::identify(floppy_image *image) +{ + UINT16 sign, sect, head, strack, etrack; + read_header(image, sign, sect, head, strack, etrack); + + if(sign == 0x0e0f && + (sect >=9 && sect <= 11) && + (head == 0 || head == 1) && + strack <= etrack && + etrack < 82) + return 100; + return 0; +} + +bool msa_format::load(floppy_image *image) +{ + UINT16 sign, sect, head, strack, etrack; + read_header(image, sign, sect, head, strack, etrack); + image->set_meta_data(etrack+1, head+1); + + UINT8 sectdata[11*512]; + UINT8 th[2]; + + int pos = 10; + int track_size = sect*512; + + for(int track=strack; track <= etrack; track++) { + for(int side=0; side <= head; side++) { + image->image_read(th, pos, 2); + pos += 2; + int tsize = (th[0] << 8) | th[1]; + image->image_read(sectdata, pos, tsize); + pos += tsize; + if(tsize < track_size) { + if(!uncompress(sectdata, tsize, track_size)) + return FALSE; + } + generate(track, side, etrack+1, head+1, sectdata, sect, image); + } + } + + return TRUE; +} + +const floppy_format_type FLOPPY_ST_FORMAT = &floppy_image_format_creator<st_format>; +const floppy_format_type FLOPPY_MSA_FORMAT = &floppy_image_format_creator<msa_format>; diff --git a/src/lib/formats/st_dsk.h b/src/lib/formats/st_dsk.h index 01c33dbeddd..3a153a83b5d 100644 --- a/src/lib/formats/st_dsk.h +++ b/src/lib/formats/st_dsk.h @@ -42,6 +42,46 @@ public: static const desc_e desc_fcp_11_9[]; static const desc_e desc_fcp_11_10[]; static const desc_e *const desc_fcp_11[]; + + void generate(int track, int head, int track_count, int head_count, UINT8 *buffer, int sector_count, floppy_image *image); +}; + +class st_format : public st_gen_format +{ +public: + st_format(); + + virtual int identify(floppy_image *image); + virtual bool load(floppy_image *image); + + virtual const char *name() const; + virtual const char *description() const; + virtual const char *extensions() const; + virtual bool supports_save() const; + +private: + void find_size(floppy_image *image, int &track_count, int &head_count, int §or_count); }; +class msa_format : public st_gen_format +{ +public: + msa_format(); + + virtual int identify(floppy_image *image); + virtual bool load(floppy_image *image); + + virtual const char *name() const; + virtual const char *description() const; + virtual const char *extensions() const; + virtual bool supports_save() const; + +private: + bool uncompress(UINT8 *buffer, int csize, int usize); + void read_header(floppy_image *image, UINT16 &sign, UINT16 §, UINT16 &head, UINT16 &strack, UINT16 &etrack); +}; + +extern const floppy_format_type FLOPPY_ST_FORMAT; +extern const floppy_format_type FLOPPY_MSA_FORMAT; + #endif /*ST_DSK_H_*/ |