2016-08-20 03:40:12 +02:00
/* Copyright holders: Tenshi
see COPYING for more details
*/
# include "ibm.h"
# include "disc.h"
2016-08-31 22:49:56 +02:00
# include "disc_86f.h"
2016-09-07 20:59:08 +02:00
# include "disc_random.h"
2016-09-03 18:07:46 +02:00
# include "fdc.h"
2016-08-20 03:40:12 +02:00
# include "fdd.h"
# define MAX_SECTORS 256
enum
{
STATE_IDLE ,
STATE_READ_FIND_SECTOR ,
STATE_READ_SECTOR ,
2016-09-03 18:07:46 +02:00
STATE_READ_SECTOR_CRC ,
STATE_READ_SECTOR_GAP3 ,
2016-08-20 03:40:12 +02:00
STATE_READ_FIND_FIRST_SECTOR ,
STATE_READ_FIRST_SECTOR ,
2016-09-03 18:07:46 +02:00
STATE_READ_FIRST_SECTOR_CRC ,
STATE_READ_FIRST_SECTOR_GAP3 ,
2016-08-20 03:40:12 +02:00
STATE_READ_FIND_NEXT_SECTOR ,
STATE_READ_NEXT_SECTOR ,
2016-09-03 18:07:46 +02:00
STATE_READ_NEXT_SECTOR_CRC ,
STATE_READ_NEXT_SECTOR_GAP3 ,
2016-08-20 03:40:12 +02:00
STATE_WRITE_FIND_SECTOR ,
STATE_WRITE_SECTOR ,
2016-09-03 18:07:46 +02:00
STATE_WRITE_SECTOR_CRC ,
STATE_WRITE_SECTOR_GAP3 ,
2016-08-20 03:40:12 +02:00
STATE_READ_FIND_ADDRESS ,
STATE_READ_ADDRESS ,
STATE_FORMAT_FIND ,
STATE_FORMAT ,
2016-09-03 18:07:46 +02:00
STATE_SEEK ,
2016-08-20 03:40:12 +02:00
} ;
2016-09-03 18:07:46 +02:00
static uint16_t CRCTable [ 256 ] ;
2016-08-20 03:40:12 +02:00
static int d86f_drive ;
2016-09-03 18:07:46 +02:00
typedef union {
uint16_t word ;
uint8_t bytes [ 2 ] ;
} crc_t ;
typedef struct
{
uint8_t c ;
uint8_t h ;
uint8_t r ;
uint8_t n ;
} sector_id_fields_t ;
typedef union
{
uint32_t dword ;
uint8_t byte_array [ 4 ] ;
sector_id_fields_t id ;
} sector_id_t ;
2016-08-20 03:40:12 +02:00
static struct
{
FILE * f ;
2016-09-05 22:03:33 +02:00
uint16_t version ;
2016-08-31 22:49:56 +02:00
uint8_t disk_flags ;
2016-09-05 21:58:28 +02:00
uint8_t track_data [ 2 ] [ 50000 ] ;
uint8_t track_layout [ 2 ] [ 50000 ] ;
2016-08-31 22:49:56 +02:00
uint8_t track_flags ;
2016-09-05 22:10:04 +02:00
uint8_t side_flags [ 2 ] ;
2016-09-07 21:03:46 +02:00
uint16_t index_hole_pos [ 2 ] ;
2016-08-31 22:49:56 +02:00
uint8_t track_in_file ;
2016-09-03 18:07:46 +02:00
uint32_t track_offset [ 256 ] ;
2016-09-01 18:52:23 +02:00
uint32_t file_size ;
2016-09-03 18:07:46 +02:00
sector_id_t format_sector_id ;
sector_id_t rw_sector_id ;
sector_id_t last_sector ;
sector_id_t req_sector ;
uint32_t index_count ;
uint8_t state ;
uint8_t fill ;
uint16_t track_pos ;
uint16_t datac ;
uint16_t id_pos ;
uint16_t section_pos ;
crc_t calc_crc ;
crc_t track_crc ;
uint8_t track_byte ;
uint8_t track_index ;
2016-09-14 23:18:14 +02:00
uint8_t track_fuzzy ;
uint8_t track_data_byte ;
2016-09-03 18:07:46 +02:00
uint8_t old_track_byte ;
uint8_t old_track_index ;
2016-09-14 23:18:14 +02:00
uint8_t old_track_fuzzy ;
uint8_t old_track_data_byte ;
2016-09-04 03:50:06 +02:00
uint8_t cur_track ;
2016-09-07 20:59:08 +02:00
uint8_t side_flag_bytes ;
2016-08-20 03:40:12 +02:00
} d86f [ 2 ] ;
/* Needed for formatting! */
2016-09-04 03:50:06 +02:00
int d86f_is_40_track ( int drive )
{
return ( d86f [ drive ] . disk_flags & 1 ) ? 0 : 1 ;
}
2016-08-20 03:40:12 +02:00
int d86f_realtrack ( int drive , int track )
{
2016-09-04 03:50:06 +02:00
if ( d86f_is_40_track ( drive ) & & fdd_doublestep_40 ( drive ) )
2016-08-20 03:40:12 +02:00
track / = 2 ;
return track ;
}
2016-08-31 22:49:56 +02:00
static void d86f_setupcrc ( uint16_t poly , uint16_t rvalue )
{
int c = 256 , bc ;
uint16_t crctemp ;
while ( c - - )
{
crctemp = c < < 8 ;
bc = 8 ;
while ( bc - - )
{
if ( crctemp & 0x8000 )
{
crctemp = ( crctemp < < 1 ) ^ poly ;
}
else
{
crctemp < < = 1 ;
}
}
CRCTable [ c ] = crctemp ;
}
}
static void d86f_calccrc ( int drive , uint8_t byte )
{
2016-09-03 18:07:46 +02:00
d86f [ drive ] . calc_crc . word = ( d86f [ drive ] . calc_crc . word < < 8 ) ^ CRCTable [ ( d86f [ drive ] . calc_crc . word > > 8 ) ^ byte ] ;
2016-08-31 22:49:56 +02:00
}
2016-08-20 03:40:12 +02:00
void d86f_init ( )
{
2016-09-07 20:59:08 +02:00
disc_random_init ( ) ;
2016-08-20 03:40:12 +02:00
memset ( d86f , 0 , sizeof ( d86f ) ) ;
2016-08-31 22:49:56 +02:00
d86f_setupcrc ( 0x1021 , 0xcdb4 ) ;
2016-08-20 03:40:12 +02:00
}
2016-09-05 21:58:28 +02:00
int d86f_get_sides ( int drive )
{
return ( d86f [ drive ] . disk_flags & 8 ) ? 2 : 1 ;
}
int d86f_get_array_size ( int drive )
{
int pos = 25002 ;
switch ( d86f_hole ( drive ) )
{
case 0 :
pos = 7500 ;
break ;
case 1 :
pos = 12500 ;
break ;
case 2 :
pos = 50000 ;
break ;
}
2016-09-07 00:40:29 +02:00
return pos ;
2016-09-05 21:58:28 +02:00
}
int d86f_valid_bit_rate ( int drive )
{
int rate = fdc_get_bit_rate ( ) ;
switch ( d86f_hole ( drive ) )
{
case 0 : /* DD */
if ( ( rate < 1 ) | | ( rate > 2 ) ) return 0 ;
return 1 ;
case 1 : /* HD */
if ( rate ! = 0 ) return 0 ;
return 1 ;
case 2 : /* ED */
if ( rate < 3 ) return 0 ;
return 1 ;
}
return 1 ;
}
2016-08-20 03:40:12 +02:00
void d86f_load ( int drive , char * fn )
{
uint32_t magic = 0 ;
uint32_t len = 0 ;
2016-08-31 22:49:56 +02:00
int i = 0 ;
int j = 0 ;
2016-09-07 20:59:08 +02:00
uint8_t temp = 0 ;
2016-08-20 03:40:12 +02:00
writeprot [ drive ] = 0 ;
d86f [ drive ] . f = fopen ( fn , " rb+ " ) ;
if ( ! d86f [ drive ] . f )
{
d86f [ drive ] . f = fopen ( fn , " rb " ) ;
if ( ! d86f [ drive ] . f )
return ;
writeprot [ drive ] = 1 ;
}
fwriteprot [ drive ] = writeprot [ drive ] ;
fseek ( d86f [ drive ] . f , 0 , SEEK_END ) ;
2016-08-31 22:49:56 +02:00
len = ftell ( d86f [ drive ] . f ) ;
2016-08-20 03:40:12 +02:00
fseek ( d86f [ drive ] . f , 0 , SEEK_SET ) ;
if ( len < 52056 )
{
/* File too small, abort. */
fclose ( d86f [ drive ] . f ) ;
return ;
}
fread ( & magic , 4 , 1 , d86f [ drive ] . f ) ;
2016-08-31 22:49:56 +02:00
if ( magic ! = 0x46423638 )
2016-08-20 03:40:12 +02:00
{
/* File is not of the valid format, abort. */
2016-08-31 22:49:56 +02:00
pclog ( " 86F: Unrecognized magic bytes: %08X \n " , magic ) ;
2016-08-20 03:40:12 +02:00
fclose ( d86f [ drive ] . f ) ;
return ;
}
2016-09-05 22:03:33 +02:00
fread ( & ( d86f [ drive ] . version ) , 2 , 1 , d86f [ drive ] . f ) ;
2016-08-20 03:40:12 +02:00
2016-09-07 20:59:08 +02:00
if ( ( d86f [ drive ] . version ! = 0x0100 ) & & ( d86f [ drive ] . version ! = 0x010A ) & & ( d86f [ drive ] . version ! = 0x0114 ) )
2016-08-20 03:40:12 +02:00
{
2016-08-31 22:49:56 +02:00
/* File is not of a recognized format version abort. */
2016-09-05 22:03:33 +02:00
pclog ( " 86F: Unrecognized file version: %i.%02i \n " , d86f [ drive ] . version > > 8 , d86f [ drive ] . version & 0xFF ) ;
2016-08-20 03:40:12 +02:00
fclose ( d86f [ drive ] . f ) ;
return ;
}
2016-09-05 21:58:28 +02:00
else
{
2016-09-05 22:03:33 +02:00
pclog ( " 86F: Recognized file version: %i.%02i \n " , d86f [ drive ] . version > > 8 , d86f [ drive ] . version & 0xFF ) ;
2016-09-05 21:58:28 +02:00
}
2016-08-20 03:40:12 +02:00
2016-08-31 22:49:56 +02:00
fread ( & ( d86f [ drive ] . disk_flags ) , 1 , 1 , d86f [ drive ] . f ) ;
2016-08-20 03:40:12 +02:00
2016-08-31 22:49:56 +02:00
if ( ( ( d86f [ drive ] . disk_flags > > 1 ) & 3 ) = = 3 )
2016-08-20 03:40:12 +02:00
{
2016-08-31 22:49:56 +02:00
/* Invalid disk hole. */
pclog ( " 86F: Unrecognized disk hole type 3 \n " ) ;
fclose ( d86f [ drive ] . f ) ;
return ;
2016-08-20 03:40:12 +02:00
}
2016-08-31 22:49:56 +02:00
if ( ! writeprot [ drive ] )
2016-08-20 03:40:12 +02:00
{
2016-08-31 22:49:56 +02:00
writeprot [ drive ] = ( d86f [ drive ] . disk_flags & 0x10 ) ? 1 : 0 ;
fwriteprot [ drive ] = writeprot [ drive ] ;
2016-08-20 03:40:12 +02:00
}
2016-09-03 18:07:46 +02:00
fread ( d86f [ drive ] . track_offset , 1 , 1024 , d86f [ drive ] . f ) ;
2016-08-20 03:40:12 +02:00
2016-09-03 18:07:46 +02:00
if ( ! ( d86f [ drive ] . track_offset [ 0 ] ) )
2016-08-20 03:40:12 +02:00
{
2016-08-31 22:49:56 +02:00
/* File has no track 0, abort. */
pclog ( " 86F: No Track 0 \n " ) ;
fclose ( d86f [ drive ] . f ) ;
return ;
2016-08-20 03:40:12 +02:00
}
2016-08-31 22:49:56 +02:00
/* Load track 0 flags as default. */
2016-09-07 20:59:08 +02:00
d86f [ drive ] . side_flag_bytes = d86f_get_sides ( drive ) ;
if ( ( d86f [ drive ] . version = = 0x010A ) | | ( d86f [ drive ] . version = = 0x0114 ) )
2016-09-05 21:58:28 +02:00
{
2016-09-07 20:59:08 +02:00
if ( ( d86f [ drive ] . version = = 0x010A ) & & ( d86f_get_sides ( drive ) = = 1 ) )
{
/* This is needed to detect the early variant of 86F version 1.10 images and handle it correctly. */
fseek ( d86f [ drive ] . f , d86f [ drive ] . track_offset [ 0 ] + 3 , SEEK_SET ) ;
fread ( & temp , 1 , 1 , d86f [ drive ] . f ) ;
if ( temp & 0x80 ) d86f [ drive ] . side_flag_bytes = 2 ;
}
2016-09-05 21:58:28 +02:00
fseek ( d86f [ drive ] . f , d86f [ drive ] . track_offset [ 0 ] , SEEK_SET ) ;
fread ( & ( d86f [ drive ] . side_flags [ 0 ] ) , 1 , 1 , d86f [ drive ] . f ) ;
2016-09-06 02:17:05 +02:00
if ( d86f_get_sides ( drive ) = = 2 )
{
fread ( & ( d86f [ drive ] . side_flags [ 1 ] ) , 1 , 1 , d86f [ drive ] . f ) ;
}
2016-09-05 21:58:28 +02:00
}
else
{
fseek ( d86f [ drive ] . f , d86f [ drive ] . track_offset [ 0 ] , SEEK_SET ) ;
fread ( & ( d86f [ drive ] . track_flags ) , 1 , 1 , d86f [ drive ] . f ) ;
}
2016-09-01 18:52:23 +02:00
fseek ( d86f [ drive ] . f , 0 , SEEK_END ) ;
d86f [ drive ] . file_size = ftell ( d86f [ drive ] . f ) ;
2016-08-31 22:49:56 +02:00
fseek ( d86f [ drive ] . f , 0 , SEEK_SET ) ;
2016-08-20 03:40:12 +02:00
drives [ drive ] . seek = d86f_seek ;
2016-08-31 22:49:56 +02:00
drives [ drive ] . readsector = d86f_readsector ;
drives [ drive ] . writesector = d86f_writesector ;
drives [ drive ] . readaddress = d86f_readaddress ;
2016-08-20 03:40:12 +02:00
drives [ drive ] . hole = d86f_hole ;
drives [ drive ] . byteperiod = d86f_byteperiod ;
2016-08-31 22:49:56 +02:00
drives [ drive ] . poll = d86f_poll ;
drives [ drive ] . format = d86f_format ;
2016-08-20 03:40:12 +02:00
drives [ drive ] . realtrack = d86f_realtrack ;
2016-08-31 22:49:56 +02:00
drives [ drive ] . stop = d86f_stop ;
2016-08-20 03:40:12 +02:00
}
int d86f_hole ( int drive )
{
2016-08-31 22:49:56 +02:00
return ( d86f [ drive ] . disk_flags > > 1 ) & 3 ;
2016-08-20 03:40:12 +02:00
}
2016-09-05 21:58:28 +02:00
uint8_t d86f_flags ( int drive )
{
int side = fdd_get_head ( drive ) ;
2016-09-07 20:59:08 +02:00
if ( ( d86f [ drive ] . version = = 0x010A ) | | ( d86f [ drive ] . version = = 0x0114 ) )
2016-09-05 21:58:28 +02:00
{
return d86f [ drive ] . side_flags [ side ] ;
}
else
{
return d86f [ drive ] . track_flags ;
}
}
2016-09-04 19:37:08 +02:00
uint8_t d86f_track_flags ( int drive )
2016-08-20 03:40:12 +02:00
{
2016-09-05 21:58:28 +02:00
uint8_t tf = d86f_flags ( drive ) ;
2016-09-04 19:37:08 +02:00
uint8_t rr = tf & 0x27 ;
2016-09-04 22:20:32 +02:00
uint8_t dr = fdd_get_flags ( drive ) & 7 ;
2016-09-04 19:37:08 +02:00
tf & = ~ 0x27 ;
switch ( rr )
2016-08-20 03:40:12 +02:00
{
2016-09-04 19:37:08 +02:00
case 0x02 :
case 0x21 :
/* 1 MB unformatted medium, treat these two as equivalent. */
switch ( dr )
2016-08-31 22:49:56 +02:00
{
2016-09-04 19:37:08 +02:00
case 0x06 :
/* 5.25" Single-RPM HD drive, treat as 300 kbps, 360 rpm. */
tf | = 0x21 ;
break ;
default :
/* Any other drive, treat as 250 kbps, 300 rpm. */
tf | = 0x02 ;
break ;
2016-08-31 22:49:56 +02:00
}
2016-09-04 19:37:08 +02:00
break ;
default :
tf | = rr ;
break ;
}
return tf ;
}
double d86f_byteperiod ( int drive )
{
switch ( d86f_track_flags ( drive ) & 0x0f )
{
case 0x02 : /* 125 kbps, FM */
2016-08-31 22:49:56 +02:00
return 64.0 ;
case 0x01 : /* 150 kbps, FM */
return 320.0 / 6.0 ;
case 0x0A : /* 250 kbps, MFM */
case 0x00 : /* 250 kbps, FM */
return 32.0 ;
case 0x09 : /* 300 kbps, MFM */
return 160.0 / 6.0 ;
case 0x08 : /* 500 kbps, MFM */
return 16.0 ;
case 0x0B : /* 1000 kbps, MFM */
return 8.0 ;
case 0x0D : /* 2000 kbps, MFM */
return 4.0 ;
default :
return 32.0 ;
2016-08-20 03:40:12 +02:00
}
2016-08-31 22:49:56 +02:00
return 32.0 ;
2016-08-20 03:40:12 +02:00
}
void d86f_close ( int drive )
{
if ( d86f [ drive ] . f )
fclose ( d86f [ drive ] . f ) ;
d86f [ drive ] . f = NULL ;
}
2016-08-31 22:49:56 +02:00
int d86f_is_mfm ( int drive )
{
2016-09-05 21:58:28 +02:00
return ( d86f_track_flags ( drive ) & 8 ) ? 1 : 0 ;
2016-08-31 22:49:56 +02:00
}
uint16_t d86f_get_raw_size ( int drive )
{
double rate = 0.0 ;
int mfm = d86f_is_mfm ( drive ) ;
2016-09-04 19:37:08 +02:00
double rpm = ( d86f_track_flags ( drive ) & 0x20 ) ? 360.0 : 300.0 ;
2016-08-31 22:49:56 +02:00
double size = 6250.0 ;
2016-09-04 19:37:08 +02:00
switch ( d86f_track_flags ( drive ) & 7 )
2016-08-31 22:49:56 +02:00
{
case 0 :
rate = 500.0 ;
break ;
case 1 :
rate = 300.0 ;
break ;
case 2 :
rate = 250.0 ;
break ;
case 3 :
rate = 1000.0 ;
break ;
case 5 :
rate = 2000.0 ;
break ;
}
if ( ! mfm ) rate / = 2.0 ;
size = ( size / 250.0 ) * rate ;
size = ( size * 300.0 ) / rpm ;
return ( uint16_t ) size ;
}
2016-08-20 03:40:12 +02:00
void d86f_seek ( int drive , int track )
{
2016-08-31 22:49:56 +02:00
int sides = d86f_get_sides ( drive ) ;
2016-08-20 03:40:12 +02:00
int side ;
2016-09-05 21:58:28 +02:00
int full_size = 25000 ;
int store_size = 50000 ;
int flag_bytes = 2 ;
2016-09-07 20:59:08 +02:00
if ( ( d86f [ drive ] . version = = 0x010A ) | | ( d86f [ drive ] . version = = 0x0114 ) )
2016-09-05 21:58:28 +02:00
{
full_size = d86f_get_array_size ( drive ) ;
store_size = full_size < < 1 ;
2016-09-07 20:59:08 +02:00
if ( d86f [ drive ] . side_flag_bytes = = 2 ) flag_bytes + + ;
if ( d86f [ drive ] . version = = 0x0114 ) flag_bytes + = 4 ;
2016-09-05 21:58:28 +02:00
}
2016-08-20 03:40:12 +02:00
2016-08-31 22:49:56 +02:00
if ( d86f_is_40_track ( drive ) & & fdd_doublestep_40 ( drive ) )
2016-08-20 03:40:12 +02:00
track / = 2 ;
2016-09-03 18:07:46 +02:00
for ( side = 0 ; side < d86f_get_sides ( drive ) ; side + + )
2016-08-20 03:40:12 +02:00
{
2016-09-06 23:52:08 +02:00
memset ( d86f [ drive ] . track_layout [ side ] , BYTE_GAP4 , 50000 ) ;
memset ( d86f [ drive ] . track_data [ side ] , 0xFF , 50000 ) ;
2016-08-20 03:40:12 +02:00
}
2016-08-31 22:49:56 +02:00
2016-09-04 03:50:06 +02:00
d86f [ drive ] . cur_track = track ;
2016-09-03 18:07:46 +02:00
if ( ! ( d86f [ drive ] . track_offset [ track ] ) )
2016-08-31 22:49:56 +02:00
{
/* Track does not exist in the image, initialize it as unformatted. */
d86f [ drive ] . track_in_file = 0 ;
2016-09-07 20:59:08 +02:00
if ( ( d86f [ drive ] . version = = 0x010A ) | | ( d86f [ drive ] . version = = 0x0114 ) )
2016-09-05 21:58:28 +02:00
{
2016-09-07 00:40:29 +02:00
for ( side = 0 ; side < d86f_get_sides ( drive ) ; side + + )
2016-09-06 02:17:05 +02:00
{
2016-09-07 00:40:29 +02:00
d86f [ drive ] . side_flags [ side ] = 0x0A ; /* 300 rpm, MFM, 250 kbps */
2016-09-06 02:17:05 +02:00
}
2016-09-05 21:58:28 +02:00
}
else
{
d86f [ drive ] . track_flags = 0x0A ; /* 300 rpm, MFM, 250 kbps */
}
2016-08-31 22:49:56 +02:00
return ;
2016-08-20 03:40:12 +02:00
}
2016-08-31 22:49:56 +02:00
d86f [ drive ] . track_in_file = 1 ;
2016-09-03 18:07:46 +02:00
fseek ( d86f [ drive ] . f , d86f [ drive ] . track_offset [ track ] , SEEK_SET ) ;
2016-08-31 22:49:56 +02:00
2016-09-07 20:59:08 +02:00
if ( ( d86f [ drive ] . version = = 0x010A ) | | ( d86f [ drive ] . version = = 0x0114 ) )
2016-09-05 21:58:28 +02:00
{
2016-09-07 20:59:08 +02:00
for ( side = 0 ; side < d86f [ drive ] . side_flag_bytes ; side + + )
2016-09-06 02:17:05 +02:00
{
2016-09-07 00:40:29 +02:00
fread ( & ( d86f [ drive ] . side_flags [ side ] ) , 1 , 1 , d86f [ drive ] . f ) ;
2016-09-06 02:17:05 +02:00
}
2016-09-07 20:59:08 +02:00
if ( d86f [ drive ] . version = = 0x0114 )
{
for ( side = 0 ; side < d86f [ drive ] . side_flag_bytes ; side + + )
{
fread ( & ( d86f [ drive ] . index_hole_pos [ side ] ) , 2 , 1 , d86f [ drive ] . f ) ;
}
}
2016-09-05 21:58:28 +02:00
}
else
{
fread ( & ( d86f [ drive ] . track_flags ) , 1 , 1 , d86f [ drive ] . f ) ;
}
2016-08-31 22:49:56 +02:00
2016-09-03 18:07:46 +02:00
for ( side = 0 ; side < d86f_get_sides ( drive ) ; side + + )
2016-08-20 03:40:12 +02:00
{
2016-09-05 21:58:28 +02:00
fseek ( d86f [ drive ] . f , d86f [ drive ] . track_offset [ track ] + ( side * store_size ) + flag_bytes , SEEK_SET ) ;
2016-09-03 18:07:46 +02:00
fread ( d86f [ drive ] . track_layout [ side ] , 1 , d86f_get_raw_size ( drive ) , d86f [ drive ] . f ) ;
2016-09-05 21:58:28 +02:00
fseek ( d86f [ drive ] . f , d86f [ drive ] . track_offset [ track ] + ( side * store_size ) + full_size + flag_bytes , SEEK_SET ) ;
2016-09-03 18:07:46 +02:00
fread ( d86f [ drive ] . track_data [ side ] , 1 , d86f_get_raw_size ( drive ) , d86f [ drive ] . f ) ;
2016-08-20 03:40:12 +02:00
}
}
2016-09-04 03:50:06 +02:00
void d86f_writeback ( int drive )
2016-08-20 03:40:12 +02:00
{
2016-09-04 03:50:06 +02:00
int track = d86f [ drive ] . cur_track ;
2016-09-07 20:59:08 +02:00
uint8_t track_id = track ;
2016-09-03 18:07:46 +02:00
int side ;
2016-09-05 21:58:28 +02:00
int full_size = 25000 ;
int store_size = 50000 ;
int flag_bytes = 2 ;
2016-09-07 20:59:08 +02:00
if ( ( d86f [ drive ] . version = = 0x010A ) | | ( d86f [ drive ] . version = = 0x0114 ) )
2016-09-05 21:58:28 +02:00
{
full_size = d86f_get_array_size ( drive ) ;
2016-09-07 20:59:08 +02:00
store_size = full_size < < 1 ;
if ( d86f [ drive ] . side_flag_bytes = = 2 ) flag_bytes + + ;
if ( d86f [ drive ] . version = = 0x0114 ) flag_bytes + = 4 ;
2016-09-05 21:58:28 +02:00
}
2016-09-03 18:07:46 +02:00
2016-08-20 03:40:12 +02:00
if ( ! d86f [ drive ] . f )
return ;
2016-08-31 22:49:56 +02:00
if ( ! d86f [ drive ] . track_in_file )
2016-08-20 03:40:12 +02:00
return ; /*Should never happen*/
2016-09-03 18:07:46 +02:00
fseek ( d86f [ drive ] . f , 7 , SEEK_SET ) ;
fwrite ( d86f [ drive ] . track_offset , 1 , 1024 , d86f [ drive ] . f ) ;
2016-08-31 22:49:56 +02:00
2016-09-03 18:07:46 +02:00
fseek ( d86f [ drive ] . f , d86f [ drive ] . track_offset [ track ] , SEEK_SET ) ;
2016-09-07 20:59:08 +02:00
if ( ( d86f [ drive ] . version = = 0x010A ) | | ( d86f [ drive ] . version = = 0x0114 ) )
2016-09-05 21:58:28 +02:00
{
2016-09-07 20:59:08 +02:00
for ( side = 0 ; side < d86f [ drive ] . side_flag_bytes ; side + + )
2016-09-06 02:17:05 +02:00
{
2016-09-07 00:40:29 +02:00
fwrite ( & ( d86f [ drive ] . side_flags [ side ] ) , 1 , 1 , d86f [ drive ] . f ) ;
2016-09-06 02:17:05 +02:00
}
2016-09-07 20:59:08 +02:00
if ( d86f [ drive ] . version = = 0x0114 )
{
for ( side = 0 ; side < d86f [ drive ] . side_flag_bytes ; side + + )
{
fwrite ( & ( d86f [ drive ] . index_hole_pos [ side ] ) , 2 , 1 , d86f [ drive ] . f ) ;
}
}
2016-09-05 21:58:28 +02:00
}
else
{
fwrite ( & ( d86f [ drive ] . track_flags ) , 1 , 1 , d86f [ drive ] . f ) ;
}
2016-09-07 20:59:08 +02:00
fwrite ( & track_id , 1 , 1 , d86f [ drive ] . f ) ;
2016-08-31 22:49:56 +02:00
2016-09-03 18:07:46 +02:00
for ( side = 0 ; side < d86f_get_sides ( drive ) ; side + + )
2016-08-31 22:49:56 +02:00
{
2016-09-05 21:58:28 +02:00
fseek ( d86f [ drive ] . f , d86f [ drive ] . track_offset [ track ] + ( side * store_size ) + flag_bytes , SEEK_SET ) ;
2016-09-03 18:07:46 +02:00
fwrite ( d86f [ drive ] . track_layout [ side ] , 1 , d86f_get_raw_size ( drive ) , d86f [ drive ] . f ) ;
2016-09-05 21:58:28 +02:00
fseek ( d86f [ drive ] . f , d86f [ drive ] . track_offset [ track ] + ( side * store_size ) + full_size + flag_bytes , SEEK_SET ) ;
2016-09-03 18:07:46 +02:00
fwrite ( d86f [ drive ] . track_data [ side ] , 1 , d86f_get_raw_size ( drive ) , d86f [ drive ] . f ) ;
2016-08-31 22:49:56 +02:00
}
2016-09-03 18:07:46 +02:00
// pclog("d86f_writeback(): %08X\n", d86f[drive].track_offset[track]);
2016-08-20 03:40:12 +02:00
}
void d86f_reset ( int drive , int side )
{
if ( side = = 0 )
{
2016-09-03 18:07:46 +02:00
d86f [ drive ] . index_count = 0 ;
d86f [ drive ] . state = STATE_SEEK ;
2016-08-20 03:40:12 +02:00
}
}
2016-09-04 19:37:08 +02:00
static int d86f_get_bitcell_period ( int drive )
2016-08-20 03:40:12 +02:00
{
2016-08-31 22:49:56 +02:00
double rate = 0.0 ;
2016-09-04 19:37:08 +02:00
int mfm = ( d86f_track_flags ( drive ) & 8 ) ? 1 : 0 ;
double rpm = ( d86f_track_flags ( drive ) & 0x20 ) ? 360.0 : 300.0 ;
2016-08-31 22:49:56 +02:00
double size = 8000.0 ;
2016-09-04 19:37:08 +02:00
switch ( d86f_track_flags ( drive ) & 7 )
2016-08-31 22:49:56 +02:00
{
case 0 :
rate = 500.0 ;
break ;
case 1 :
rate = 300.0 ;
break ;
case 2 :
rate = 250.0 ;
break ;
case 3 :
rate = 1000.0 ;
break ;
case 5 :
rate = 2000.0 ;
break ;
}
if ( ! mfm ) rate / = 2.0 ;
size = ( size * 250.0 ) / rate ;
size = ( size * 300.0 ) / rpm ;
2016-09-07 03:00:52 +02:00
size = ( size * fdd_getrpm ( drive ^ fdd_swap ) ) / 300.0 ;
2016-08-31 22:49:56 +02:00
return ( int ) size ;
2016-08-20 03:40:12 +02:00
}
void d86f_readsector ( int drive , int sector , int track , int side , int rate , int sector_size )
{
2016-09-04 19:37:08 +02:00
// pclog("d86f_readsector: fdc_period=%i img_period=%i rate=%i sector=%i track=%i side=%i\n", fdc_get_bitcell_period(), d86f_get_bitcell_period(drive), rate, sector, track, side);
2016-08-20 03:40:12 +02:00
2016-09-03 18:07:46 +02:00
d86f [ drive ] . req_sector . id . c = track ;
d86f [ drive ] . req_sector . id . h = side ;
2016-08-31 22:49:56 +02:00
2016-09-07 20:59:08 +02:00
if ( fdd_get_head ( drive ) & & ( d86f_get_sides ( drive ) = = 1 ) )
2016-08-31 22:49:56 +02:00
{
fdc_notfound ( ) ;
2016-09-03 18:07:46 +02:00
d86f [ drive ] . state = STATE_IDLE ;
d86f [ drive ] . index_count = 0 ;
2016-08-31 22:49:56 +02:00
return ;
}
2016-08-20 03:40:12 +02:00
d86f_drive = drive ;
2016-09-07 20:59:08 +02:00
if ( sector = = SECTOR_FIRST )
d86f [ drive ] . req_sector . id . r = 1 ;
else if ( sector = = SECTOR_NEXT )
d86f [ drive ] . req_sector . id . r + + ;
else
d86f [ drive ] . req_sector . id . r = sector ;
2016-09-03 18:07:46 +02:00
d86f [ drive ] . req_sector . id . n = sector_size ;
d86f [ drive ] . index_count = 0 ;
2016-09-07 20:59:08 +02:00
d86f [ drive ] . state = STATE_READ_FIND_SECTOR ;
2016-08-20 03:40:12 +02:00
}
void d86f_writesector ( int drive , int sector , int track , int side , int rate , int sector_size )
{
2016-09-03 18:07:46 +02:00
d86f [ drive ] . req_sector . id . c = track ;
d86f [ drive ] . req_sector . id . h = side ;
d86f [ drive ] . req_sector . id . r = sector ;
d86f [ drive ] . req_sector . id . n = sector_size ;
2016-08-20 03:40:12 +02:00
2016-09-04 19:37:08 +02:00
// pclog("d86f_writesector: drive=%c: fdc_period=%i img_period=%i rate=%i chrn=%08X\n", drive + 0x41, fdc_get_bitcell_period(), d86f_get_bitcell_period(drive), rate, d86f[drive].req_sector.dword);
2016-08-31 22:49:56 +02:00
2016-09-07 20:59:08 +02:00
if ( fdd_get_head ( drive ) & & ( d86f_get_sides ( drive ) = = 1 ) )
2016-08-31 22:49:56 +02:00
{
2016-09-17 20:22:02 +02:00
pclog ( " Wrong side \n " ) ;
2016-08-31 22:49:56 +02:00
fdc_notfound ( ) ;
2016-09-03 18:07:46 +02:00
d86f [ drive ] . state = STATE_IDLE ;
d86f [ drive ] . index_count = 0 ;
2016-08-31 22:49:56 +02:00
return ;
}
2016-08-20 03:40:12 +02:00
d86f_drive = drive ;
2016-09-03 18:07:46 +02:00
d86f [ drive ] . index_count = 0 ;
d86f [ drive ] . state = STATE_WRITE_FIND_SECTOR ;
2016-08-20 03:40:12 +02:00
}
void d86f_readaddress ( int drive , int track , int side , int rate )
{
2016-09-04 19:37:08 +02:00
// pclog("d86f_readaddress: fdc_period=%i img_period=%i rate=%i track=%i side=%i\n", fdc_get_bitcell_period(), d86f_get_bitcell_period(drive), rate, track, side);
2016-08-20 03:40:12 +02:00
2016-09-03 18:07:46 +02:00
d86f [ drive ] . req_sector . id . c = track ;
d86f [ drive ] . req_sector . id . h = side ;
2016-08-20 03:40:12 +02:00
2016-09-07 20:59:08 +02:00
if ( fdd_get_head ( drive ) & & ( d86f_get_sides ( drive ) = = 1 ) )
2016-08-31 22:49:56 +02:00
{
fdc_notfound ( ) ;
2016-09-03 18:07:46 +02:00
d86f [ drive ] . state = STATE_IDLE ;
d86f [ drive ] . index_count = 0 ;
2016-08-31 22:49:56 +02:00
return ;
}
2016-08-20 03:40:12 +02:00
2016-08-31 22:49:56 +02:00
d86f_drive = drive ;
2016-09-03 18:07:46 +02:00
d86f [ drive ] . index_count = 0 ;
d86f [ drive ] . state = STATE_READ_FIND_ADDRESS ;
2016-08-20 03:40:12 +02:00
}
void d86f_prepare_track_layout ( int drive , int side )
{
int i = 0 ;
int j = 0 ;
2016-09-17 20:22:02 +02:00
int perp_wg = fdc_get_perp ( ) & 3 ;
2016-08-31 22:49:56 +02:00
int real_gap0_len = d86f_is_mfm ( drive ) ? 80 : 40 ;
int sync_len = d86f_is_mfm ( drive ) ? 12 : 6 ;
int am_len = d86f_is_mfm ( drive ) ? 4 : 1 ;
int real_gap1_len = d86f_is_mfm ( drive ) ? 50 : 26 ;
2016-09-17 20:22:02 +02:00
int real_gap2_len = ( perp_wg = = 3 ) ? 41 : 22 ;
2016-08-31 22:49:56 +02:00
int real_gap3_len = fdc_get_gap ( ) ;
2016-09-03 18:07:46 +02:00
2016-08-31 22:49:56 +02:00
memset ( d86f [ drive ] . track_layout [ side ] , BYTE_GAP4 , d86f_get_raw_size ( drive ) ) ;
2016-08-20 03:40:12 +02:00
i = 0 ;
2016-09-03 18:07:46 +02:00
memset ( d86f [ drive ] . track_layout [ side ] + i , BYTE_GAP0 , real_gap0_len ) ;
i + = real_gap0_len ;
memset ( d86f [ drive ] . track_layout [ side ] + i , BYTE_I_SYNC , sync_len ) ;
i + = sync_len ;
if ( d86f_is_mfm ( drive ) )
2016-08-20 03:40:12 +02:00
{
2016-09-03 18:07:46 +02:00
memset ( d86f [ drive ] . track_layout [ side ] + i , BYTE_IAM_SYNC , 3 ) ;
i + = 3 ;
2016-08-20 03:40:12 +02:00
}
2016-09-03 18:07:46 +02:00
memset ( d86f [ drive ] . track_layout [ side ] + i , BYTE_IAM , 1 ) ;
i + + ;
memset ( d86f [ drive ] . track_layout [ side ] + i , BYTE_GAP1 , real_gap1_len ) ;
i + = real_gap1_len ;
2016-09-07 20:59:08 +02:00
if ( ( d86f [ drive ] . version = = 0x0100 ) | | ( d86f [ drive ] . version = = 0x010A ) )
{
d86f [ drive ] . track_layout [ side ] [ 0 ] | = BYTE_INDEX_HOLE ;
}
2016-08-31 22:49:56 +02:00
for ( j = 0 ; j < fdc_get_format_sectors ( ) ; j + + )
2016-08-20 03:40:12 +02:00
{
2016-08-31 22:49:56 +02:00
memset ( d86f [ drive ] . track_layout [ side ] + i , BYTE_ID_SYNC , sync_len ) ;
2016-08-20 03:40:12 +02:00
i + = sync_len ;
2016-08-31 22:49:56 +02:00
if ( d86f_is_mfm ( drive ) )
2016-08-20 03:40:12 +02:00
{
2016-08-31 22:49:56 +02:00
memset ( d86f [ drive ] . track_layout [ side ] + i , BYTE_IDAM_SYNC , 3 ) ;
2016-08-20 03:40:12 +02:00
i + = 3 ;
}
2016-08-31 22:49:56 +02:00
memset ( d86f [ drive ] . track_layout [ side ] + i , BYTE_IDAM , 1 ) ;
2016-08-20 03:40:12 +02:00
i + + ;
2016-08-31 22:49:56 +02:00
memset ( d86f [ drive ] . track_layout [ side ] + i , BYTE_ID , 4 ) ;
2016-08-20 03:40:12 +02:00
i + = 4 ;
2016-08-31 22:49:56 +02:00
memset ( d86f [ drive ] . track_layout [ side ] + i , BYTE_ID_CRC , 2 ) ;
2016-08-20 03:40:12 +02:00
i + = 2 ;
2016-08-31 22:49:56 +02:00
memset ( d86f [ drive ] . track_layout [ side ] + i , BYTE_GAP2 , real_gap2_len ) ;
i + = real_gap2_len ;
memset ( d86f [ drive ] . track_layout [ side ] + i , BYTE_DATA_SYNC , sync_len ) ;
2016-08-20 03:40:12 +02:00
i + = sync_len ;
2016-08-31 22:49:56 +02:00
if ( d86f_is_mfm ( drive ) )
2016-08-20 03:40:12 +02:00
{
2016-08-31 22:49:56 +02:00
memset ( d86f [ drive ] . track_layout [ side ] + i , BYTE_DATAAM_SYNC , 3 ) ;
2016-08-20 03:40:12 +02:00
i + = 3 ;
}
2016-08-31 22:49:56 +02:00
memset ( d86f [ drive ] . track_layout [ side ] + i , BYTE_DATAAM , 1 ) ;
2016-08-20 03:40:12 +02:00
i + + ;
2016-08-31 22:49:56 +02:00
memset ( d86f [ drive ] . track_layout [ side ] + i , BYTE_DATA , ( 128 < < fdc_get_format_n ( ) ) ) ;
i + = ( 128 < < fdc_get_format_n ( ) ) ;
memset ( d86f [ drive ] . track_layout [ side ] + i , BYTE_DATA_CRC , 2 ) ;
2016-08-20 03:40:12 +02:00
i + = 2 ;
2016-08-31 22:49:56 +02:00
memset ( d86f [ drive ] . track_layout [ side ] + i , BYTE_GAP3 , real_gap3_len ) ;
i + = real_gap3_len ;
2016-08-20 03:40:12 +02:00
}
2016-08-31 22:49:56 +02:00
}
2016-09-17 20:22:02 +02:00
int d86f_can_format ( int drive )
{
int temp ;
temp = ! writeprot [ drive ] ;
temp = temp & & ! swwp ;
temp = temp & & fdd_can_read_medium ( drive ^ fdd_swap ) ;
temp = temp & & d86f_valid_bit_rate ( drive ) ;
pclog ( " Bit rate is %svalid \n " , d86f_valid_bit_rate ( drive ) ? " " : " not " ) ;
return temp ;
}
2016-08-31 22:49:56 +02:00
void d86f_format ( int drive , int track , int side , int rate , uint8_t fill )
{
2016-09-05 21:58:28 +02:00
int full_size = 25000 ;
int store_size = 50000 ;
int flag_bytes = 2 ;
2016-09-07 20:59:08 +02:00
if ( ( d86f [ drive ] . version = = 0x010A ) | | ( d86f [ drive ] . version = = 0x0114 ) )
2016-09-05 21:58:28 +02:00
{
full_size = d86f_get_array_size ( drive ) ;
store_size = full_size < < 1 ;
2016-09-07 20:59:08 +02:00
if ( d86f [ drive ] . side_flag_bytes = = 2 ) flag_bytes + + ;
if ( d86f [ drive ] . version = = 0x0114 ) flag_bytes + = 4 ;
2016-09-05 21:58:28 +02:00
}
2016-09-04 03:50:06 +02:00
d86f [ drive ] . req_sector . id . c = d86f [ drive ] . cur_track ;
2016-09-03 18:07:46 +02:00
d86f [ drive ] . req_sector . id . h = side ;
2016-08-20 03:40:12 +02:00
2016-09-17 20:22:02 +02:00
if ( ( side & & ( d86f_get_sides ( drive ) = = 1 ) ) | | ! ( d86f_can_format ( drive ) ) )
2016-08-31 22:49:56 +02:00
{
2016-09-17 20:22:02 +02:00
if ( side & & ( d86f_get_sides ( drive ) = = 1 ) ) pclog ( " Wrong side \n " ) ;
if ( ! ( d86f_can_format ( drive ) ) ) pclog ( " Can't format \n " ) ;
2016-08-31 22:49:56 +02:00
fdc_notfound ( ) ;
2016-09-03 18:07:46 +02:00
d86f [ drive ] . state = STATE_IDLE ;
d86f [ drive ] . index_count = 0 ;
2016-08-31 22:49:56 +02:00
return ;
}
2016-08-20 03:40:12 +02:00
2016-09-04 03:50:06 +02:00
if ( ( d86f [ drive ] . cur_track < 0 ) | | ( d86f [ drive ] . cur_track > 256 ) )
2016-09-01 18:52:23 +02:00
{
2016-09-17 20:22:02 +02:00
pclog ( " Track below 0 or above 256 \n " ) ;
2016-09-01 18:52:23 +02:00
fdc_writeprotect ( ) ;
2016-09-03 18:07:46 +02:00
d86f [ drive ] . state = STATE_IDLE ;
d86f [ drive ] . index_count = 0 ;
2016-09-01 18:52:23 +02:00
return ;
}
2016-08-31 22:49:56 +02:00
d86f_drive = drive ;
2016-09-03 18:07:46 +02:00
d86f [ drive ] . fill = fill ;
d86f [ drive ] . index_count = 0 ;
2016-08-31 22:49:56 +02:00
/* Let's prepare the track space and layout before filling. */
d86f [ drive ] . track_flags & = 0xc0 ;
d86f [ drive ] . track_flags | = ( fdd_getrpm ( drive ^ fdd_swap ) = = 360 ) ? 0x20 : 0 ;
d86f [ drive ] . track_flags | = fdc_get_bit_rate ( ) ;
d86f [ drive ] . track_flags | = fdc_is_mfm ( ) ? 8 : 0 ;
2016-09-08 00:04:04 +02:00
if ( ( d86f [ drive ] . version = = 0x010A ) | | ( d86f [ drive ] . version = = 0x0114 ) )
2016-09-05 21:58:28 +02:00
{
d86f [ drive ] . side_flags [ side ] = d86f [ drive ] . track_flags ;
2016-09-08 00:04:04 +02:00
if ( d86f [ drive ] . version = = 0x0114 )
{
d86f [ drive ] . index_hole_pos [ side ] = 0 ;
}
2016-09-07 20:59:08 +02:00
}
2016-09-05 21:58:28 +02:00
memset ( d86f [ drive ] . track_data [ side ] , 0xFF , full_size ) ;
2016-08-31 22:49:56 +02:00
d86f_prepare_track_layout ( drive , side ) ;
2016-09-01 18:52:23 +02:00
if ( ! d86f [ drive ] . track_in_file )
{
/* Track is absent from the file, let's add it. */
2016-09-04 03:50:06 +02:00
d86f [ drive ] . track_offset [ d86f [ drive ] . cur_track ] = d86f [ drive ] . file_size ;
2016-09-05 21:58:28 +02:00
d86f [ drive ] . file_size + = store_size + flag_bytes ;
2016-09-01 18:52:23 +02:00
if ( d86f_get_sides ( drive ) = = 2 )
{
2016-09-05 21:58:28 +02:00
d86f [ drive ] . file_size + = store_size ;
2016-09-01 18:52:23 +02:00
}
d86f [ drive ] . track_in_file = 1 ;
}
2016-09-03 18:07:46 +02:00
d86f [ drive ] . state = STATE_FORMAT_FIND ;
2016-08-20 03:40:12 +02:00
}
2016-08-31 22:49:56 +02:00
void d86f_stop ( int drive )
2016-08-20 03:40:12 +02:00
{
2016-09-03 18:07:46 +02:00
d86f [ drive ] . state = STATE_IDLE ;
2016-08-20 03:40:12 +02:00
}
2016-08-31 22:49:56 +02:00
static void index_pulse ( int drive )
2016-08-20 03:40:12 +02:00
{
2016-09-03 18:07:46 +02:00
if ( d86f [ drive ] . state ! = STATE_IDLE ) fdc_indexpulse ( ) ;
2016-08-20 03:40:12 +02:00
}
2016-08-31 22:49:56 +02:00
uint32_t d86f_get_data_len ( int drive )
{
2016-09-03 18:07:46 +02:00
if ( d86f [ drive ] . req_sector . id . n )
2016-08-20 03:40:12 +02:00
{
2016-09-03 18:07:46 +02:00
return ( 128 < < ( ( uint32_t ) d86f [ drive ] . req_sector . id . n ) ) ;
2016-08-31 22:49:56 +02:00
}
else
{
if ( fdc_get_dtl ( ) < 128 )
{
return fdc_get_dtl ( ) ;
}
else
{
2016-09-03 18:07:46 +02:00
return ( 128 < < ( ( uint32_t ) d86f [ drive ] . req_sector . id . n ) ) ;
2016-08-31 22:49:56 +02:00
}
2016-08-20 03:40:12 +02:00
}
}
int d86f_can_read_address ( int drive )
{
int temp ;
2016-09-04 19:37:08 +02:00
temp = ( fdc_get_bitcell_period ( ) = = d86f_get_bitcell_period ( drive ) ) ;
2016-08-20 03:40:12 +02:00
temp = temp & & fdd_can_read_medium ( drive ^ fdd_swap ) ;
2016-08-31 22:49:56 +02:00
temp = temp & & ( fdc_is_mfm ( ) = = d86f_is_mfm ( drive ) ) ;
2016-08-20 03:40:12 +02:00
return temp ;
}
2016-09-14 23:18:14 +02:00
int d86f_should_write_am ( int drive )
{
int temp ;
temp = ( d86f [ drive ] . state = = STATE_WRITE_FIND_SECTOR ) ;
temp = temp & & ( d86f [ drive ] . req_sector . dword = = d86f [ drive ] . last_sector . dword ) ;
temp = temp & & d86f_can_read_address ( drive ) ;
return temp ;
}
2016-09-03 18:07:46 +02:00
int d86f_find_state_nf ( int drive )
{
int temp ;
temp = ( d86f [ drive ] . state = = STATE_READ_FIND_SECTOR ) ;
temp = temp | | ( d86f [ drive ] . state = = STATE_READ_FIND_FIRST_SECTOR ) ;
temp = temp | | ( d86f [ drive ] . state = = STATE_READ_FIND_NEXT_SECTOR ) ;
temp = temp | | ( d86f [ drive ] . state = = STATE_WRITE_FIND_SECTOR ) ;
temp = temp | | ( d86f [ drive ] . state = = STATE_READ_FIND_ADDRESS ) ;
return temp ;
}
2016-08-20 03:40:12 +02:00
int d86f_find_state ( int drive )
{
int temp ;
2016-09-03 18:07:46 +02:00
temp = d86f_find_state_nf ( drive ) ;
temp = temp | | ( d86f [ drive ] . state = = STATE_FORMAT_FIND ) ;
2016-08-20 03:40:12 +02:00
return temp ;
}
2016-09-03 18:07:46 +02:00
int d86f_read_state_data ( int drive )
2016-08-31 22:49:56 +02:00
{
int temp ;
2016-09-03 18:07:46 +02:00
temp = ( d86f [ drive ] . state = = STATE_READ_SECTOR ) ;
temp = temp | | ( d86f [ drive ] . state = = STATE_READ_FIRST_SECTOR ) ;
temp = temp | | ( d86f [ drive ] . state = = STATE_READ_NEXT_SECTOR ) ;
2016-08-31 22:49:56 +02:00
return temp ;
}
2016-09-03 18:07:46 +02:00
int d86f_read_state_crc ( int drive )
{
int temp ;
temp = ( d86f [ drive ] . state = = STATE_READ_SECTOR_CRC ) ;
temp = temp | | ( d86f [ drive ] . state = = STATE_READ_FIRST_SECTOR_CRC ) ;
temp = temp | | ( d86f [ drive ] . state = = STATE_READ_NEXT_SECTOR_CRC ) ;
return temp ;
}
int d86f_read_state_gap3 ( int drive )
2016-08-20 03:40:12 +02:00
{
int temp ;
2016-09-03 18:07:46 +02:00
temp = ( d86f [ drive ] . state = = STATE_READ_SECTOR_GAP3 ) ;
temp = temp | | ( d86f [ drive ] . state = = STATE_READ_FIRST_SECTOR_GAP3 ) ;
temp = temp | | ( d86f [ drive ] . state = = STATE_READ_NEXT_SECTOR_GAP3 ) ;
2016-08-20 03:40:12 +02:00
return temp ;
}
2016-09-03 18:07:46 +02:00
int d86f_write_state ( int drive )
{
int temp ;
temp = ( d86f [ drive ] . state = = STATE_WRITE_SECTOR ) ;
temp = temp | | ( d86f [ drive ] . state = = STATE_WRITE_SECTOR_CRC ) ;
temp = temp | | ( d86f [ drive ] . state = = STATE_WRITE_SECTOR_GAP3 ) ;
return temp ;
}
2016-08-31 22:49:56 +02:00
2016-09-03 18:07:46 +02:00
int d86f_read_state ( int drive )
{
int temp ;
temp = d86f_read_state_data ( drive ) ;
temp = temp | | d86f_read_state_crc ( drive ) ;
temp = temp | | d86f_read_state_gap3 ( drive ) ;
return temp ;
}
2016-08-31 22:49:56 +02:00
int d86f_data_size ( int drive )
{
int temp ;
2016-09-03 18:07:46 +02:00
temp = d86f [ drive ] . req_sector . id . n ;
2016-08-31 22:49:56 +02:00
temp = 128 < < temp ;
return temp ;
}
2016-09-03 18:07:46 +02:00
void d86f_poll_write_crc ( int drive , int side )
2016-08-31 22:49:56 +02:00
{
2016-09-03 18:07:46 +02:00
if ( d86f [ drive ] . state ! = STATE_FORMAT ) return ;
d86f [ drive ] . id_pos = d86f [ drive ] . track_pos - d86f [ drive ] . section_pos ;
2016-09-14 23:18:14 +02:00
d86f [ drive ] . track_data [ side ] [ d86f [ drive ] . track_pos ] = d86f [ drive ] . track_data_byte = d86f [ drive ] . calc_crc . bytes [ d86f [ drive ] . id_pos ^ 1 ] ;
2016-09-03 18:07:46 +02:00
}
2016-08-31 22:49:56 +02:00
2016-09-03 18:07:46 +02:00
void d86f_poll_advancebyte ( int drive , int side )
{
d86f [ drive ] . old_track_byte = d86f [ drive ] . track_byte ;
d86f [ drive ] . old_track_index = d86f [ drive ] . track_index ;
2016-09-14 23:18:14 +02:00
d86f [ drive ] . old_track_data_byte = d86f [ drive ] . track_data_byte ;
if ( d86f [ drive ] . version = = 0x0114 )
{
d86f [ drive ] . old_track_fuzzy = d86f [ drive ] . track_fuzzy ;
}
2016-08-31 22:49:56 +02:00
2016-09-03 18:07:46 +02:00
d86f [ drive ] . track_pos + + ;
d86f [ drive ] . track_pos % = d86f_get_raw_size ( drive ) ;
2016-08-31 22:49:56 +02:00
2016-09-07 20:59:08 +02:00
if ( ( d86f [ drive ] . version = = 0x0100 ) | | ( d86f [ drive ] . version = = 0x010A ) )
{
d86f [ drive ] . track_byte = d86f [ drive ] . track_layout [ side ] [ d86f [ drive ] . track_pos ] & ~ BYTE_INDEX_HOLE ;
d86f [ drive ] . track_index = d86f [ drive ] . track_layout [ side ] [ d86f [ drive ] . track_pos ] & BYTE_INDEX_HOLE ;
2016-09-14 23:18:14 +02:00
d86f [ drive ] . track_data_byte = d86f [ drive ] . track_data [ side ] [ d86f [ drive ] . track_pos ] ;
2016-09-07 20:59:08 +02:00
}
else if ( d86f [ drive ] . version = = 0x0114 )
{
d86f [ drive ] . track_byte = d86f [ drive ] . track_layout [ side ] [ d86f [ drive ] . track_pos ] & ~ BYTE_IS_FUZZY ;
d86f [ drive ] . track_index = ( d86f [ drive ] . track_pos = = d86f [ drive ] . index_hole_pos [ side ] ) ;
2016-09-14 23:18:14 +02:00
d86f [ drive ] . track_fuzzy = d86f [ drive ] . track_layout [ side ] [ d86f [ drive ] . track_pos ] & BYTE_IS_FUZZY ;
if ( d86f [ drive ] . track_fuzzy )
{
d86f [ drive ] . track_data_byte = disc_random_generate ( ) ;
}
else
{
d86f [ drive ] . track_data_byte = d86f [ drive ] . track_data [ side ] [ d86f [ drive ] . track_pos ] ;
}
2016-09-07 20:59:08 +02:00
}
2016-09-03 18:07:46 +02:00
}
2016-08-31 22:49:56 +02:00
2016-09-03 18:07:46 +02:00
void d86f_poll_reset ( int drive , int side )
2016-08-20 03:40:12 +02:00
{
2016-09-03 18:07:46 +02:00
d86f [ drive ] . state = STATE_IDLE ;
d86f [ drive ] . index_count = 0 ;
2016-09-15 03:59:49 +02:00
d86f [ drive ] . datac = 0 ;
2016-09-03 18:07:46 +02:00
d86f_poll_advancebyte ( drive , side ) ;
}
2016-08-20 03:40:12 +02:00
2016-09-03 18:07:46 +02:00
int d86f_poll_check_notfound ( int drive )
{
if ( d86f [ drive ] . index_count > 1 )
{
/* The index hole has been hit twice and we're still in a find state.
This means sector finding has failed for whatever reason .
Abort with sector not found and set state to idle . */
2016-09-17 20:22:02 +02:00
pclog ( " d86f_poll(): Sector not found (%i %i %i %i) (%i, %i) \n " , d86f [ drive ] . req_sector . id . c , d86f [ drive ] . req_sector . id . h , d86f [ drive ] . req_sector . id . r , d86f [ drive ] . req_sector . id . n , fdc_get_bitcell_period ( ) , d86f_get_bitcell_period ( drive ) ) ;
2016-09-03 18:07:46 +02:00
fdc_notfound ( ) ;
d86f [ drive ] . state = STATE_IDLE ;
d86f [ drive ] . index_count = 0 ;
return 1 ;
}
else
{
return 0 ;
}
}
2016-08-31 22:49:56 +02:00
2016-09-03 18:07:46 +02:00
void d86f_poll_finish ( int drive , int side )
{
d86f_poll_reset ( drive , side ) ;
d86f [ drive ] . last_sector . dword = 0xFFFFFFFF ;
}
2016-08-31 22:49:56 +02:00
2016-09-07 20:59:08 +02:00
int d86f_mark_index_hole ( int drive )
{
int temp = ( d86f [ drive ] . version = = 0x0100 ) ;
temp = temp | | ( d86f [ drive ] . version = = 0x010A ) ;
return temp ;
}
2016-09-14 23:18:14 +02:00
void d86f_poll_write ( int drive , int side , uint8_t data , uint8_t type )
{
d86f [ drive ] . track_data [ side ] [ d86f [ drive ] . track_pos ] = d86f [ drive ] . track_data_byte = data ;
d86f [ drive ] . track_layout [ side ] [ d86f [ drive ] . track_pos ] = type ;
if ( ! d86f [ drive ] . track_pos & & d86f_mark_index_hole ( drive ) ) d86f [ drive ] . track_layout [ side ] [ d86f [ drive ] . track_pos ] | = BYTE_INDEX_HOLE ;
}
2016-09-03 18:07:46 +02:00
void d86f_poll_readwrite ( int drive , int side )
{
int data ;
uint16_t max_len ;
2016-08-31 22:49:56 +02:00
2016-09-03 18:07:46 +02:00
if ( d86f_read_state_data ( drive ) )
2016-08-20 03:40:12 +02:00
{
2016-09-03 18:07:46 +02:00
max_len = d86f_data_size ( drive ) ;
2016-09-14 23:18:14 +02:00
data = d86f [ drive ] . track_data_byte ;
2016-09-03 18:07:46 +02:00
if ( d86f [ drive ] . datac < d86f_get_data_len ( drive ) )
{
2016-09-07 20:59:08 +02:00
fdc_data ( data ) ;
2016-09-03 18:07:46 +02:00
}
2016-09-07 20:59:08 +02:00
d86f_calccrc ( drive , data ) ;
2016-08-20 03:40:12 +02:00
}
2016-09-03 18:07:46 +02:00
else if ( d86f [ drive ] . state = = STATE_WRITE_SECTOR )
2016-08-20 03:40:12 +02:00
{
2016-09-03 18:07:46 +02:00
max_len = d86f_data_size ( drive ) ;
if ( d86f [ drive ] . datac < d86f_get_data_len ( drive ) )
2016-08-20 03:40:12 +02:00
{
2016-09-03 18:07:46 +02:00
data = fdc_getdata ( d86f [ drive ] . datac = = ( ( 128 < < ( ( uint32_t ) d86f [ drive ] . last_sector . id . n ) ) - 1 ) ) ;
if ( data = = - 1 )
2016-08-20 03:40:12 +02:00
{
2016-09-03 18:07:46 +02:00
data = 0 ;
2016-08-20 03:40:12 +02:00
}
}
2016-09-03 18:07:46 +02:00
else
2016-08-20 03:40:12 +02:00
{
2016-09-03 18:07:46 +02:00
data = 0 ;
2016-08-20 03:40:12 +02:00
}
2016-09-03 18:07:46 +02:00
if ( ! disable_write )
2016-08-20 03:40:12 +02:00
{
2016-09-14 23:18:14 +02:00
d86f_poll_write ( drive , side , data , BYTE_DATA ) ;
2016-08-20 03:40:12 +02:00
}
2016-09-14 23:18:14 +02:00
d86f_calccrc ( drive , d86f [ drive ] . track_data_byte ) ;
2016-09-03 18:07:46 +02:00
}
else if ( d86f_read_state_crc ( drive ) )
{
max_len = 2 ;
2016-09-14 23:18:14 +02:00
d86f [ drive ] . track_crc . bytes [ d86f [ drive ] . datac ^ 1 ] = d86f [ drive ] . track_data_byte ;
2016-09-03 18:07:46 +02:00
}
else if ( d86f [ drive ] . state = = STATE_WRITE_SECTOR_CRC )
{
max_len = 2 ;
if ( ! disable_write )
2016-08-20 03:40:12 +02:00
{
2016-09-14 23:18:14 +02:00
d86f_poll_write ( drive , side , d86f [ drive ] . calc_crc . bytes [ d86f [ drive ] . datac ^ 1 ] , BYTE_DATA_CRC ) ;
2016-08-20 03:40:12 +02:00
}
}
2016-09-03 18:07:46 +02:00
else if ( d86f_read_state_gap3 ( drive ) )
2016-08-20 03:40:12 +02:00
{
2016-09-03 18:07:46 +02:00
max_len = fdc_get_gap ( ) ;
if ( d86f [ drive ] . datac = = ( fdc_get_gap ( ) - 1 ) )
2016-08-20 03:40:12 +02:00
{
2016-09-03 18:07:46 +02:00
d86f_poll_finish ( drive , side ) ;
if ( d86f [ drive ] . track_crc . word ! = d86f [ drive ] . calc_crc . word )
2016-08-20 03:40:12 +02:00
{
2016-09-14 23:18:14 +02:00
// pclog("d86f_poll(): Data CRC error (%i %i %i %i) (%04X %04X)\n", d86f[drive].req_sector.id.c, d86f[drive].req_sector.id.h, d86f[drive].req_sector.id.r, d86f[drive].req_sector.id.n, d86f[drive].track_crc.word, d86f[drive].calc_crc.word);
2016-09-03 18:07:46 +02:00
fdc_finishread ( ) ;
fdc_datacrcerror ( ) ;
2016-08-20 03:40:12 +02:00
}
2016-09-03 18:07:46 +02:00
else
2016-08-20 03:40:12 +02:00
{
2016-09-03 18:07:46 +02:00
fdc_sector_finishread ( ) ;
2016-08-20 03:40:12 +02:00
}
2016-09-03 18:07:46 +02:00
return ;
}
}
else if ( d86f [ drive ] . state = = STATE_WRITE_SECTOR_GAP3 )
{
max_len = fdc_get_gap ( ) ;
2016-09-15 03:59:49 +02:00
if ( ! disable_write & & ! d86f [ drive ] . datac )
{
d86f_poll_write ( drive , side , fdc_is_mfm ( ) ? 0x4E : 0xFF , BYTE_GAP3 ) ;
}
if ( d86f [ drive ] . datac = = ( max_len - 1 ) )
2016-09-03 18:07:46 +02:00
{
2016-09-15 03:59:49 +02:00
d86f_poll_finish ( drive , side ) ;
2016-09-14 23:18:14 +02:00
if ( ! disable_write )
{
d86f_writeback ( drive ) ;
}
2016-09-03 18:07:46 +02:00
fdc_sector_finishread ( drive ) ;
return ;
}
}
2016-08-31 22:49:56 +02:00
2016-09-03 18:07:46 +02:00
d86f [ drive ] . datac + + ;
d86f_poll_advancebyte ( drive , side ) ;
2016-08-31 22:49:56 +02:00
2016-09-03 18:07:46 +02:00
if ( d86f [ drive ] . datac > = max_len )
{
d86f [ drive ] . datac = 0 ;
d86f [ drive ] . state + + ;
}
}
void d86f_poll_find_nf ( int drive , int side )
{
2016-09-07 20:59:08 +02:00
uint8_t data = 0 ;
2016-09-03 18:07:46 +02:00
if ( d86f [ drive ] . track_index )
{
// pclog("d86f_poll_find_nf(): Index pulse\n");
index_pulse ( drive ) ;
d86f [ drive ] . index_count + + ;
}
switch ( d86f [ drive ] . track_byte )
{
2016-09-14 23:18:14 +02:00
case BYTE_DATAAM_SYNC :
if ( d86f_should_write_am ( drive ) )
{
d86f_poll_write ( drive , side , 0xA1 , BYTE_DATAAM_SYNC ) ;
}
case BYTE_IDAM_SYNC :
if ( d86f_is_mfm ( drive ) )
{
d86f_calccrc ( drive , d86f [ drive ] . track_data_byte ) ;
}
2016-09-03 18:07:46 +02:00
break ;
case BYTE_DATAAM :
2016-09-14 23:18:14 +02:00
if ( d86f_should_write_am ( drive ) )
2016-08-31 22:49:56 +02:00
{
2016-09-14 23:18:14 +02:00
d86f_poll_write ( drive , side , 0xFB , BYTE_DATAAM ) ;
2016-08-31 22:49:56 +02:00
}
2016-09-14 23:18:14 +02:00
case BYTE_IDAM :
d86f_calccrc ( drive , d86f [ drive ] . track_data_byte ) ;
2016-09-03 18:07:46 +02:00
break ;
2016-09-14 23:18:14 +02:00
2016-09-03 18:07:46 +02:00
case BYTE_ID :
d86f [ drive ] . id_pos = d86f [ drive ] . track_pos - d86f [ drive ] . section_pos ;
2016-09-15 03:59:49 +02:00
d86f [ drive ] . rw_sector_id . byte_array [ d86f [ drive ] . id_pos ] = d86f [ drive ] . track_data_byte ;
d86f_calccrc ( drive , d86f [ drive ] . track_data_byte ) ;
2016-09-03 18:07:46 +02:00
break ;
case BYTE_ID_CRC :
d86f [ drive ] . id_pos = d86f [ drive ] . track_pos - d86f [ drive ] . section_pos ;
2016-09-14 23:18:14 +02:00
d86f [ drive ] . track_crc . bytes [ d86f [ drive ] . id_pos ^ 1 ] = d86f [ drive ] . track_data_byte ;
2016-09-03 18:07:46 +02:00
break ;
}
2016-08-31 22:49:56 +02:00
2016-09-03 18:07:46 +02:00
d86f_poll_advancebyte ( drive , side ) ;
if ( d86f_poll_check_notfound ( drive ) ) return ;
if ( d86f [ drive ] . track_byte ! = d86f [ drive ] . old_track_byte )
{
d86f [ drive ] . section_pos = d86f [ drive ] . track_pos ;
switch ( d86f [ drive ] . track_byte )
{
2016-09-14 23:18:14 +02:00
case BYTE_IDAM_SYNC :
case BYTE_DATAAM_SYNC :
if ( d86f_is_mfm ( drive ) )
{
d86f [ drive ] . calc_crc . word = 0xffff ;
}
break ;
case BYTE_IDAM :
case BYTE_DATAAM :
if ( ! d86f_is_mfm ( drive ) )
{
d86f [ drive ] . calc_crc . word = 0xffff ;
}
break ;
2016-09-03 18:07:46 +02:00
case BYTE_GAP2 :
if ( d86f_can_read_address ( drive ) )
2016-08-31 22:49:56 +02:00
{
2016-09-14 23:18:14 +02:00
if ( ( d86f [ drive ] . req_sector . dword = = d86f [ drive ] . rw_sector_id . dword ) | | ( d86f [ drive ] . state = = STATE_READ_FIND_ADDRESS ) )
2016-09-03 18:07:46 +02:00
{
if ( d86f [ drive ] . track_crc . word ! = d86f [ drive ] . calc_crc . word )
{
2016-09-14 23:18:14 +02:00
if ( d86f [ drive ] . state ! = STATE_READ_FIND_ADDRESS )
{
// pclog("d86f_poll(): Header CRC error (%i %i %i %i) (%04X %04X)\n", d86f[drive].req_sector.id.c, d86f[drive].req_sector.id.h, d86f[drive].req_sector.id.r, d86f[drive].req_sector.id.n, d86f[drive].track_crc.word, d86f[drive].calc_crc.word);
fdc_finishread ( ) ;
fdc_headercrcerror ( ) ;
d86f [ drive ] . state = STATE_IDLE ;
d86f [ drive ] . index_count = 0 ;
return ;
}
2016-09-03 18:07:46 +02:00
}
2016-09-07 00:40:29 +02:00
else
{
d86f [ drive ] . last_sector . dword = d86f [ drive ] . rw_sector_id . dword ;
d86f [ drive ] . rw_sector_id . dword = 0xFFFFFFFF ;
// pclog("Read sector ID in find state: %i %i %i %i (sought: %i, %i, %i, %i)\n", d86f[drive].last_sector.id.c, d86f[drive].last_sector.id.h, d86f[drive].last_sector.id.r, d86f[drive].last_sector.id.n, d86f[drive].req_sector.id.c, d86f[drive].req_sector.id.h, d86f[drive].req_sector.id.r, d86f[drive].req_sector.id.n);
2016-09-07 01:02:21 +02:00
if ( ( d86f [ drive ] . state = = STATE_READ_FIND_ADDRESS ) & & ( d86f [ drive ] . last_sector . dword ! = 0xFFFFFFFF ) )
2016-09-07 00:40:29 +02:00
{
2016-09-14 23:18:14 +02:00
// pclog("Reading sector ID (%i %i %i %i)...\n", d86f[drive].last_sector.id.c, d86f[drive].last_sector.id.h, d86f[drive].last_sector.id.r, d86f[drive].last_sector.id.n);
2016-09-07 00:40:29 +02:00
fdc_sectorid ( d86f [ drive ] . last_sector . id . c , d86f [ drive ] . last_sector . id . h , d86f [ drive ] . last_sector . id . r , d86f [ drive ] . last_sector . id . n , 0 , 0 ) ;
d86f [ drive ] . state = STATE_IDLE ;
d86f [ drive ] . index_count = 0 ;
}
}
}
2016-08-20 03:40:12 +02:00
}
2016-09-03 18:07:46 +02:00
break ;
case BYTE_DATA :
d86f [ drive ] . datac = 0 ;
switch ( d86f [ drive ] . state )
{
case STATE_READ_FIND_SECTOR :
case STATE_WRITE_FIND_SECTOR :
2016-09-06 23:52:08 +02:00
if ( ( d86f [ drive ] . req_sector . dword = = d86f [ drive ] . last_sector . dword ) & & d86f_can_read_address ( drive ) )
2016-09-03 18:07:46 +02:00
{
d86f [ drive ] . state + + ;
}
break ;
case STATE_READ_FIND_FIRST_SECTOR :
case STATE_READ_FIND_NEXT_SECTOR :
if ( d86f_can_read_address ( drive ) )
{
d86f [ drive ] . state + + ;
}
break ;
}
break ;
2016-08-31 22:49:56 +02:00
}
2016-09-03 18:07:46 +02:00
}
}
2016-08-31 22:49:56 +02:00
2016-09-03 18:07:46 +02:00
void d86f_poll_find_format ( int drive , int side )
{
2016-09-14 23:18:14 +02:00
d86f_poll_advancebyte ( drive , side ) ;
if ( d86f [ drive ] . track_index )
2016-09-03 18:07:46 +02:00
{
2016-09-17 20:22:02 +02:00
pclog ( " Index hole hit, formatting track... \n " ) ;
2016-09-03 18:07:46 +02:00
d86f [ drive ] . state = STATE_FORMAT ;
return ;
}
}
void d86f_poll_format ( int drive , int side )
{
int data ;
2016-08-31 22:49:56 +02:00
2016-09-03 18:07:46 +02:00
switch ( d86f [ drive ] . track_byte )
2016-08-20 03:40:12 +02:00
{
2016-08-31 22:49:56 +02:00
case BYTE_GAP0 :
case BYTE_GAP1 :
case BYTE_GAP2 :
case BYTE_GAP3 :
case BYTE_GAP4 :
2016-09-14 23:18:14 +02:00
if ( ! disable_write )
{
d86f [ drive ] . track_data [ side ] [ d86f [ drive ] . track_pos ] = d86f [ drive ] . track_data_byte = fdc_is_mfm ( ) ? 0x4E : 0xFF ;
}
2016-08-31 22:49:56 +02:00
break ;
case BYTE_IAM_SYNC :
2016-09-14 23:18:14 +02:00
if ( ! disable_write )
{
d86f [ drive ] . track_data [ side ] [ d86f [ drive ] . track_pos ] = d86f [ drive ] . track_data_byte = 0xC2 ;
}
2016-08-31 22:49:56 +02:00
break ;
case BYTE_IAM :
2016-09-14 23:18:14 +02:00
if ( ! disable_write )
{
d86f [ drive ] . track_data [ side ] [ d86f [ drive ] . track_pos ] = d86f [ drive ] . track_data_byte = 0xFC ;
}
2016-08-31 22:49:56 +02:00
break ;
case BYTE_ID_SYNC :
2016-09-03 18:07:46 +02:00
d86f [ drive ] . id_pos = d86f [ drive ] . track_pos - d86f [ drive ] . section_pos ;
2016-09-17 20:22:02 +02:00
if ( d86f [ drive ] . id_pos < = 3 )
2016-09-03 18:07:46 +02:00
{
2016-09-17 20:22:02 +02:00
data = fdc_getdata ( 0 ) ;
if ( ( data = = - 1 ) & & ( d86f [ drive ] . id_pos < 3 ) )
{
data = 0 ;
}
d86f [ drive ] . format_sector_id . byte_array [ d86f [ drive ] . id_pos ] = data & 0xff ;
// pclog("format_sector_id[%i] = %i\n", cur_id_pos, d86f[drive].format_sector_id.byte_array[d86f[drive].id_pos]);
if ( d86f [ drive ] . id_pos = = 3 )
{
fdc_stop_id_request ( ) ;
// pclog("Formatting sector: %08X...\n", d86f[drive].format_sector_id.dword);
}
2016-08-31 22:49:56 +02:00
}
2016-09-17 20:22:02 +02:00
2016-08-31 22:49:56 +02:00
case BYTE_I_SYNC :
case BYTE_DATA_SYNC :
2016-09-14 23:18:14 +02:00
if ( ! disable_write )
{
d86f [ drive ] . track_data [ side ] [ d86f [ drive ] . track_pos ] = d86f [ drive ] . track_data_byte = 0 ;
}
2016-08-31 22:49:56 +02:00
break ;
case BYTE_IDAM_SYNC :
case BYTE_DATAAM_SYNC :
2016-09-14 23:18:14 +02:00
if ( ! disable_write )
{
d86f [ drive ] . track_data [ side ] [ d86f [ drive ] . track_pos ] = d86f [ drive ] . track_data_byte = 0xA1 ;
}
if ( d86f_is_mfm ( drive ) )
{
d86f_calccrc ( drive , d86f [ drive ] . track_data_byte ) ;
}
2016-08-31 22:49:56 +02:00
break ;
case BYTE_IDAM :
case BYTE_DATAAM :
2016-09-03 18:07:46 +02:00
// pclog("CRC reset: %02X\n", d86f[drive].track_byte);
2016-09-14 23:18:14 +02:00
if ( ! disable_write )
{
d86f [ drive ] . track_data [ side ] [ d86f [ drive ] . track_pos ] = d86f [ drive ] . track_data_byte = ( d86f [ drive ] . track_byte = = BYTE_IDAM ) ? 0xFE : 0xFB ;
}
d86f_calccrc ( drive , d86f [ drive ] . track_data_byte ) ;
2016-08-31 22:49:56 +02:00
break ;
case BYTE_ID :
2016-09-03 18:07:46 +02:00
d86f [ drive ] . id_pos = d86f [ drive ] . track_pos - d86f [ drive ] . section_pos ;
if ( ! disable_write )
2016-08-31 22:49:56 +02:00
{
2016-09-14 23:18:14 +02:00
d86f [ drive ] . track_data [ side ] [ d86f [ drive ] . track_pos ] = d86f [ drive ] . track_data_byte = d86f [ drive ] . format_sector_id . byte_array [ d86f [ drive ] . id_pos ] ;
2016-08-31 22:49:56 +02:00
}
2016-09-14 23:18:14 +02:00
d86f_calccrc ( drive , d86f [ drive ] . track_data_byte ) ;
2016-08-31 22:49:56 +02:00
break ;
case BYTE_DATA :
2016-09-03 18:07:46 +02:00
if ( ! disable_write )
2016-08-31 22:49:56 +02:00
{
2016-09-14 23:18:14 +02:00
d86f [ drive ] . track_data [ side ] [ d86f [ drive ] . track_pos ] = d86f [ drive ] . track_data_byte = d86f [ drive ] . fill ;
2016-08-31 22:49:56 +02:00
}
2016-09-14 23:18:14 +02:00
d86f_calccrc ( drive , d86f [ drive ] . track_data_byte ) ;
2016-08-31 22:49:56 +02:00
break ;
case BYTE_ID_CRC :
case BYTE_DATA_CRC :
2016-09-03 18:07:46 +02:00
d86f_poll_write_crc ( drive , side ) ;
2016-08-31 22:49:56 +02:00
break ;
2016-08-20 03:40:12 +02:00
}
2016-08-31 22:49:56 +02:00
2016-09-03 18:07:46 +02:00
d86f_poll_advancebyte ( drive , side ) ;
2016-08-31 22:49:56 +02:00
2016-09-14 23:18:14 +02:00
if ( d86f [ drive ] . track_index )
{
2016-09-17 20:22:02 +02:00
pclog ( " Index hole hit again, format finished \n " ) ;
2016-09-14 23:18:14 +02:00
d86f [ drive ] . state = STATE_IDLE ;
if ( ! disable_write ) d86f_writeback ( drive ) ;
fdc_sector_finishread ( drive ) ;
d86f [ drive ] . index_count = 0 ;
return ;
}
2016-09-03 18:07:46 +02:00
if ( d86f [ drive ] . track_byte ! = d86f [ drive ] . old_track_byte )
2016-08-20 03:40:12 +02:00
{
2016-09-03 18:07:46 +02:00
// pclog("Track byte: %02X, old: %02X\n", track_byte, old_track_byte);
d86f [ drive ] . section_pos = d86f [ drive ] . track_pos ;
switch ( d86f [ drive ] . track_byte & ~ BYTE_INDEX_HOLE )
2016-08-20 03:40:12 +02:00
{
2016-09-14 23:18:14 +02:00
case BYTE_IDAM :
case BYTE_DATAAM :
if ( ! d86f_is_mfm ( drive ) )
{
d86f [ drive ] . calc_crc . word = 0xffff ;
}
break ;
case BYTE_IDAM_SYNC :
case BYTE_DATAAM_SYNC :
if ( d86f_is_mfm ( drive ) )
{
d86f [ drive ] . calc_crc . word = 0xffff ;
}
break ;
2016-09-03 18:07:46 +02:00
case BYTE_ID_SYNC :
// pclog("Requesting next sector ID...\n");
fdc_request_next_sector_id ( ) ;
break ;
case BYTE_GAP2 :
d86f [ drive ] . last_sector . dword = d86f [ drive ] . format_sector_id . dword ;
break ;
case BYTE_DATA :
d86f [ drive ] . datac = 0 ;
break ;
2016-08-20 03:40:12 +02:00
}
}
2016-09-03 18:07:46 +02:00
}
2016-08-31 22:49:56 +02:00
2016-09-03 18:07:46 +02:00
void d86f_poll ( )
{
int drive = d86f_drive ;
2016-09-05 20:53:46 +02:00
int side = fdd_get_head ( drive ) ;
2016-08-31 22:49:56 +02:00
2016-09-03 18:07:46 +02:00
if ( d86f [ drive ] . state = = STATE_FORMAT )
2016-08-20 03:40:12 +02:00
{
2016-09-03 18:07:46 +02:00
d86f_poll_format ( drive , side ) ;
return ;
}
2016-08-31 22:49:56 +02:00
2016-09-03 18:07:46 +02:00
if ( d86f [ drive ] . state = = STATE_FORMAT_FIND )
{
d86f_poll_find_format ( drive , side ) ;
return ;
}
2016-08-31 22:49:56 +02:00
2016-09-03 18:07:46 +02:00
if ( d86f_find_state_nf ( drive ) )
{
d86f_poll_find_nf ( drive , side ) ;
return ;
}
2016-08-31 22:49:56 +02:00
2016-09-03 18:07:46 +02:00
if ( d86f_read_state ( drive ) | | d86f_write_state ( drive ) )
{
d86f_poll_readwrite ( drive , side ) ;
return ;
}
2016-08-31 22:49:56 +02:00
2016-09-03 18:07:46 +02:00
if ( ( d86f [ drive ] . state = = STATE_SEEK ) | | ( d86f [ drive ] . state = = STATE_IDLE ) )
{
d86f_poll_advancebyte ( drive , side ) ;
return ;
2016-08-20 03:40:12 +02:00
}
}