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 - #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 ); -/***************************************************************************** - Amiga floppy options -*****************************************************************************/ + 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; -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 + /* Track and sector info */ -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 + 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>(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; +} + +const floppy_format_type FLOPPY_ADF_FORMAT = &floppy_image_format_creator; 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_*/