summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author Miodrag Milanovic <mmicko@gmail.com>2011-07-22 12:33:00 +0000
committer Miodrag Milanovic <mmicko@gmail.com>2011-07-22 12:33:00 +0000
commit72a4eed7275a024b5ca0c9dca405b4ad36fe71ce (patch)
tree6d10162e10adfe3c2cd7ae2bcc3ce982cb453c31
parent115c33e1fd52f8d89bdaadcd22dc48629e99ae88 (diff)
Amiga ADF disk support (no whatsnew)
-rw-r--r--src/lib/formats/ami_dsk.c231
-rw-r--r--src/lib/formats/ami_dsk.h12
2 files changed, 162 insertions, 81 deletions
diff --git a/src/lib/formats/ami_dsk.c b/src/lib/formats/ami_dsk.c
index 0e6b44245a5..cb4e95f37af 100644
--- a/src/lib/formats/ami_dsk.c
+++ b/src/lib/formats/ami_dsk.c
@@ -6,93 +6,166 @@
*********************************************************************/
-
-#include <string.h>
-
#include "formats/ami_dsk.h"
-#include "formats/basicdsk.h"
-
-
-
-/*****************************************************************************
- Amiga floppy core functions
-*****************************************************************************/
-
-static FLOPPY_IDENTIFY( amiga_dsk_identify )
+adf_format::adf_format(const char *name,const char *extensions,const char *description,const char *param_guidelines) :
+ floppy_image_format_t(name,extensions,description,param_guidelines)
{
- UINT64 size;
-
- *vote = 100;
-
- /* first check the size of the image */
- size = floppy_image_size(floppy);
- if ((size != 901120) && (size != 1802240))
- *vote = 0;
-
- return FLOPPY_ERROR_SUCCESS;
}
-
-static FLOPPY_CONSTRUCT( amiga_dsk_construct )
+int adf_format::identify(floppy_image *image)
{
- struct basicdsk_geometry geometry;
-
- /* setup geometry with standard values */
- memset(&geometry, 0, sizeof(geometry));
- geometry.heads = 2;
- geometry.tracks = 80;
- geometry.first_sector_id = 0;
- geometry.sector_length = 512;
-
- if (params)
+ UINT64 size = image->image_size();
+ if ((size == 901120) || (size == 1802240))
{
- /* create */
- geometry.sectors = option_resolution_lookup_int(params, PARAM_SECTORS);
+ return 100;
}
- else
- {
- /* open */
- UINT64 size = floppy_image_size(floppy);
- geometry.sectors = size/512/80/2;
- if (geometry.sectors != 11 && geometry.sectors != 22)
- return FLOPPY_ERROR_INVALIDIMAGE;
- }
-
- return basicdsk_construct(floppy, &geometry);
+ return 0;
}
+#define MAX_TRACK_BYTES 12500
+#define ACTUAL_TRACK_BYTES 11968
+#define GAP_TRACK_BYTES ( MAX_TRACK_BYTES - ACTUAL_TRACK_BYTES )
+#define ONE_SECTOR_BYTES (544*2)
+#define ONE_REV_TIME 200 /* ms */
+#define MAX_WORDS_PER_DMA_CYCLE 32 /* 64 bytes per dma cycle */
+#define DISK_DETECT_DELAY 1
+#define MAX_TRACKS 160
+#define MAX_MFM_TRACK_LEN 16384
+
+bool adf_format::load(floppy_image *image)
+{
+ UINT8 *mfm = NULL;
+ UINT8 temp_cyl[512*11];
+ UINT16 sector_len = 512*11;
+ image->set_meta_data(80,2,300,(UINT16)253360);
+ for(int track=0; track < 80; track++) {
+ for(int side=0; side < 2; side++) {
+ UINT16 offset = ((track<<1)+side);
+ mfm = image->get_buffer(track,side);
+ image->set_track_size(track, side, MAX_MFM_TRACK_LEN);
+ image->image_read(temp_cyl, offset*sector_len, sector_len);
+ memset( &mfm[ONE_SECTOR_BYTES*11], 0xaa, GAP_TRACK_BYTES );
+
+ for (int sector = 0; sector < 11; sector++ ) {
+ int x;
+ UINT8 *dest = ( &mfm[(ONE_SECTOR_BYTES*sector)] );
+ UINT8 *src = &temp_cyl[sector*512];
+ UINT32 tmp;
+ UINT32 even, odd;
+ UINT32 hck = 0, dck = 0;
+
+ /* Preamble and sync */
+ *(dest + 0) = 0xaa;
+ *(dest + 1) = 0xaa;
+ *(dest + 2) = 0xaa;
+ *(dest + 3) = 0xaa;
+ *(dest + 4) = 0x44;
+ *(dest + 5) = 0x89;
+ *(dest + 6) = 0x44;
+ *(dest + 7) = 0x89;
+
+ /* Track and sector info */
+
+ tmp = 0xff000000 | (offset<<16) | (sector<<8) | (11 - sector);
+ odd = (tmp & 0x55555555) | 0xaaaaaaaa;
+ even = ( ( tmp >> 1 ) & 0x55555555 ) | 0xaaaaaaaa;
+ *(dest + 8) = (UINT8) ((even & 0xff000000)>>24);
+ *(dest + 9) = (UINT8) ((even & 0xff0000)>>16);
+ *(dest + 10) = (UINT8) ((even & 0xff00)>>8);
+ *(dest + 11) = (UINT8) ((even & 0xff));
+ *(dest + 12) = (UINT8) ((odd & 0xff000000)>>24);
+ *(dest + 13) = (UINT8) ((odd & 0xff0000)>>16);
+ *(dest + 14) = (UINT8) ((odd & 0xff00)>>8);
+ *(dest + 15) = (UINT8) ((odd & 0xff));
+
+ /* Fill unused space */
+
+ for (x = 16 ; x < 48; x++)
+ *(dest + x) = 0xaa;
+
+ /* Encode data section of sector */
+
+ for (x = 64 ; x < 576; x++)
+ {
+ tmp = *(src + x - 64);
+ odd = (tmp & 0x55);
+ even = (tmp>>1) & 0x55;
+ *(dest + x) = (UINT8) (even | 0xaa);
+ *(dest + x + 512) = (UINT8) (odd | 0xaa);
+ }
+
+ /* Calculate checksum for unused space */
+
+ for(x = 8; x < 48; x += 4)
+ hck ^= (((UINT32) *(dest + x))<<24) | (((UINT32) *(dest + x + 1))<<16) |
+ (((UINT32) *(dest + x + 2))<<8) | ((UINT32) *(dest + x + 3));
+
+ even = odd = hck;
+ odd >>= 1;
+ even |= 0xaaaaaaaa;
+ odd |= 0xaaaaaaaa;
+
+ *(dest + 48) = (UINT8) ((odd & 0xff000000)>>24);
+ *(dest + 49) = (UINT8) ((odd & 0xff0000)>>16);
+ *(dest + 50) = (UINT8) ((odd & 0xff00)>>8);
+ *(dest + 51) = (UINT8) (odd & 0xff);
+ *(dest + 52) = (UINT8) ((even & 0xff000000)>>24);
+ *(dest + 53) = (UINT8) ((even & 0xff0000)>>16);
+ *(dest + 54) = (UINT8) ((even & 0xff00)>>8);
+ *(dest + 55) = (UINT8) (even & 0xff);
+
+ /* Calculate checksum for data section */
+
+ for(x = 64; x < 1088; x += 4)
+ dck ^= (((UINT32) *(dest + x))<<24) | (((UINT32) *(dest + x + 1))<<16) |
+ (((UINT32) *(dest + x + 2))<< 8) | ((UINT32) *(dest + x + 3));
+ even = odd = dck;
+ odd >>= 1;
+ even |= 0xaaaaaaaa;
+ odd |= 0xaaaaaaaa;
+ *(dest + 56) = (UINT8) ((odd & 0xff000000)>>24);
+ *(dest + 57) = (UINT8) ((odd & 0xff0000)>>16);
+ *(dest + 58) = (UINT8) ((odd & 0xff00)>>8);
+ *(dest + 59) = (UINT8) (odd & 0xff);
+ *(dest + 60) = (UINT8) ((even & 0xff000000)>>24);
+ *(dest + 61) = (UINT8) ((even & 0xff0000)>>16);
+ *(dest + 62) = (UINT8) ((even & 0xff00)>>8);
+ *(dest + 63) = (UINT8) (even & 0xff);
+ }
+
+ // update MFM data with proper CLK signal
+ int lastbit= 0;
+ for(int i=0;i<MAX_TRACK_BYTES ;i++)
+ {
+ UINT8 c=mfm[i];
+ UINT8 dat = 0;
+ for(int j=0;j<8;j=j+2)
+ {
+ UINT8 c1=(c>>(6-j))&0x3;
+ if(c1&0x1)
+ {
+ dat |= (0x01<<(6-j));
+ lastbit=1;
+ }
+ else
+ {
+ if(lastbit==0 && (c1&0x2))
+ {
+ dat |= (0x02<<(6-j));
+ }
+ else
+ {
+ dat |= (0x00<<(6-j));
+ }
+ lastbit=0;
+ }
+ }
+ mfm[i] = dat;
+ }
+ }
+ }
+ return TRUE;
+}
-
-/*****************************************************************************
- Amiga floppy options
-*****************************************************************************/
-
-
-LEGACY_FLOPPY_OPTIONS_START( amiga )
- LEGACY_FLOPPY_OPTION(
- ami_dsk,
- "adf",
- "Amiga floppy disk image",
- amiga_dsk_identify,
- amiga_dsk_construct,
- NULL,
- HEADS([2])
- TRACKS([80])
- SECTORS([11]/22)
- )
-LEGACY_FLOPPY_OPTIONS_END
-
-LEGACY_FLOPPY_OPTIONS_START( amiga_only )
- LEGACY_FLOPPY_OPTION(
- ami_dsk,
- "adf",
- "Amiga floppy disk image",
- amiga_dsk_identify,
- amiga_dsk_construct,
- NULL,
- HEADS([2])
- TRACKS([80])
- SECTORS([11]/22)
- )
-LEGACY_FLOPPY_OPTIONS_END0
+const floppy_format_type FLOPPY_ADF_FORMAT = &floppy_image_format_creator<adf_format>;
diff --git a/src/lib/formats/ami_dsk.h b/src/lib/formats/ami_dsk.h
index 79eb92bee4a..3377050be34 100644
--- a/src/lib/formats/ami_dsk.h
+++ b/src/lib/formats/ami_dsk.h
@@ -11,7 +11,15 @@
#include "flopimg.h"
-LEGACY_FLOPPY_OPTIONS_EXTERN(amiga);
-LEGACY_FLOPPY_OPTIONS_EXTERN(amiga_only);
+class adf_format : public floppy_image_format_t
+{
+public:
+ adf_format(const char *name,const char *extensions,const char *description,const char *param_guidelines);
+
+ virtual int identify(floppy_image *image);
+ virtual bool load(floppy_image *image);
+};
+
+extern const floppy_format_type FLOPPY_ADF_FORMAT;
#endif /*AMI_DSK_H_*/