1 /************************************************************************/
2 /*									*/
3 /* FDC ������ �� �ǥ��������᡼�����ɤ߽�				*/
4 /*									*/
5 /************************************************************************/
6 
7 #include <stdio.h>
8 #include <stdlib.h>
9 #include <string.h>
10 
11 #include "quasi88.h"
12 #include "initval.h"
13 #include "drive.h"
14 #include "image.h"
15 #include "fdc.h"
16 
17 #include "emu.h"		/* emu_mode			*/
18 #include "pc88cpu.h"
19 
20 #include "file-op.h"
21 #include "suspend.h"
22 #include "status.h"
23 #include "event.h"
24 #include "snddrv.h"
25 
26 
27 
28 static int fdc_break_flag = FALSE;
29 
30 int	fdc_debug_mode = FALSE;	/* FDC �ǥХå��⡼�ɤΥե饰		*/
31 int	disk_exchange = FALSE;	/* �ǥ��������������ؤ��ե饰		*/
32 int	disk_ex_drv = 0;	/* �ǥ��������������ؤ��ɥ饤��		*/
33 				/*    drive 1 ... bit 0			*/
34 				/*    drive 2 ... bit 1			*/
35 /* �嵭�����ϡ�peach������ˤ�� */
36 
37 int	FDC_flag = 0;			/* FDC �����߿���		*/
38 int	fdc_wait = 0;			/* FDC �� �������� 0̵ 1ͭ	*/
39 
40 int	fdc_ignore_readonly = FALSE;	/* �ɹ����ѻ����饤�Ȥ�̵�뤹��	*/
41 
42 
43 /* FDC�Υ������������Υ��
44    Ϣ³�ǥ�����������硢����ֳ֤Dz���Ф��褦�ˤ��롣
45    ����ϥɥ饤����Υ���ʤΤ��������ޤ�������
46    ���Υ���ϡ����ơ��ȥ����֤��ʤ� */
47 static	int	fdc_sound_counter;
48 static	int	fdc_sound_skipper = 1;	/* SEEK 4����˲���Ф� */
49 
50 #define	MAX_DRIVE	(4)		/* FDC�ǰ�����ɥ饤�ֿ�	*/
51 					/* ������ NR_DRIVE(==2)�����б�	*/
52 
53 
54 
55 /*
56  * �ǥ��������᡼���˴ؤ����� (�ɥ饤��ñ��)
57  */
58 PC88_DRIVE_T	drive[ NR_DRIVE ];
59 
60 
61 /*
62  * �ǥ��������᡼�����饻�������ɤ�����ݤΡ�������Ǽ
63  */
64 static	struct{
65   Uchar   c;			/* ������ ID �� C	*/
66   Uchar   h;			/* ������ ID �� H	*/
67   Uchar   r;			/* ������ ID �� R	*/
68   Uchar   n;			/* ������ ID �� N	*/
69   Uchar   density;		/* �������ε�Ͽ̩��	*/
70   Uchar   deleted;		/* DELETED DATA �ե饰	*/
71   Uchar   status;		/* PC98 BIOS�Υ��ơ�����*/
72   Uchar   padding;
73   int     sec_nr;		/* �ȥ�å���Υ�������	*/
74   int	  size;			/* DATA ������		*/
75 
76   int	  drv;			/* ���ξ����Υɥ饤��	*/
77 } sec_buf;
78 
79 
80 /*
81  * READ / WRITE ���Υǡ����Ϥ����˥��å�
82  *	WRITE ID �Ǥϡ�4�Х��ȥǡ����ߥ������������˥��åȤ��롣
83  *	READ DIAGNOSTIC �Ǥϡ��٥��ǡ����Υ��᡼���������˺�������롣
84  */
85 
86 #define DATA_BUF_SIZE 0x4000	/* ���� 2D/2DD=6250byte��2HD=10416byte ��? */
87 
88 static	Uchar	data_buf[ DATA_BUF_SIZE ];
89 
90 
91 /*
92  * FDC �γƼ������
93  *	�ۥ��Ȥ��������ä����ޥ�ɡ�������Υ��ơ������ϡ������ˡ�
94  */
95 static	struct{
96 
97   int	command;		/* ���ޥ�� (enum��)			*/
98   int	phase;			/* PHASE (C/E/R)			*/
99   int	step;			/* PAHSE��ν������			*/
100   int	counter;		/* �Ƽ參����				*/
101   int	data_ptr;		/* �ǡ���ž���Υݥ���(data_buf��)	*/
102 
103   int	limit;			/* �ǡ���ž�������ॢ���ȥ��������� */
104   int	wait;			/* �������¹Գ��ϤޤǤΥ�������		*/
105   int	carry;			/* �������ޤǤΥ������ȷ���ۤ�ʬ	*/
106   int	gap3;			/* �������ޤǤ�GAP3�Υ�������ʬ		*/
107 
108   enum {			/* ����������				*/
109     SEEK_STAT_STOP = 0,		/* 		�������ʤ� 		*/
110     SEEK_STAT_MOVE,		/* 		��������   		*/
111     SEEK_STAT_END,		/* 		��������λ 		*/
112     SEEK_STAT_INTR		/* 		��������λ���		*/
113   }	seek_stat[MAX_DRIVE];
114   int	seek_wait[MAX_DRIVE];	/* �������ѥ�������			*/
115 
116   int	srt_clk;		/* SRT (�������ȴ���)			*/
117   int	hut_clk;		/* HUT (�������ȴ���)			*/
118   int	hlt_clk;		/* HLT (�������ȴ���)			*/
119   int	hl_stat[MAX_DRIVE];	/* �إåɥ��ɾ��֤ʤ顢��		*/
120   int	hl_wait[MAX_DRIVE];	/* �إåɥ�������ѥ�������		*/
121 
122   int	ddam_not_skipped;	/* DDAM�ʤΤ˥����åפ��ʤ��ä��顢��	*/
123 
124   byte	status;			/* STATUS		*/
125   byte	read;			/* DATA  for  FDC->MAIN */
126   byte	write;			/* DATA  for  FDC<-MAIN */
127   byte	TC;			/* TC (1 or 0 )		*/
128 
129   Uchar	sk;			/* SK �ӥå�		*/
130   Uchar	mf;			/* MF �ӥå�		*/
131   Uchar	mt;			/* MT �ӥå�		*/
132   Uchar	us;			/* US �ֹ�		*/
133   Uchar	hd;			/* HD ¦		*/
134   Uchar	c;			/* ID - C		*/
135   Uchar	h;			/* ID - H		*/
136   Uchar	r;			/* ID - R		*/
137   Uchar	n;			/* ID - N		*/
138   Uchar	eot;			/* EOT �ֹ�		*/
139   Uchar	gpl;			/* GPL Ĺ��		*/
140   Uchar	dtl;			/* DTL Ĺ��		*/
141   Uchar	d;			/* D   �ǡ���		*/
142   Uchar	sc;			/* SC  ��������		*/
143   Uchar	stp;			/* STP �ֳ�		*/
144   Uchar	ncn[MAX_DRIVE];		/* NCN ���� (4��ʬ)	*/
145   Uchar	pcn[MAX_DRIVE];		/* PCN ���� (4��ʬ)	*/
146   Uchar	st0;			/* ST0			*/
147   Uchar	st1;			/* ST1			*/
148   Uchar	st2;			/* ST2			*/
149   Uchar	st3;			/* ST3			*/
150 
151   Uchar c0;			/* C-Phase 1�Х�����	*/
152   Uchar c1;			/* C-Phase 2�Х�����	*/
153   Uchar cn;			/* C-Phase NCN		*/
154   Uchar s0;			/* C-Phase SPECIFY	*/
155   Uchar s1;			/* C-Phase SPECIFY	*/
156   Uchar r0;			/* R-Phase ST0		*/
157   Uchar r1;			/* R-Phase PCN		*/
158   Uchar	intr_unit;		/* ���ȯ������˥å�	*/
159 
160 } fdc;
161 
162 
163 /* �Ƽ�ޥ��� */
164 
165 
166 #define	disk_not_exist(drv)	(drive[drv].fp==NULL  || drive[drv].empty)
167 #define	disk_unformat(drv)	(drive[drv].sec_nr<=0 || drive[drv].empty)
168 #define disk_unformatable(drv)	(drive[drv].sec_nr<0  || drive[drv].empty)
169 
170 #define	sector_density_mismatch()					\
171 		(((sec_buf.density==DISK_DENSITY_SINGLE)&&( fdc.mf))||	\
172 		 ((sec_buf.density==DISK_DENSITY_DOUBLE)&&(!fdc.mf)) )
173 
174 #define	idr_match()							\
175 		( fdc.c==sec_buf.c && fdc.h==sec_buf.h &&		\
176 		  fdc.r==sec_buf.r && fdc.n==sec_buf.n )
177 
178 #define	printf_system_error( code )					      \
179     do{									      \
180       if     ( code==1 ) printf("FDC Read/Write Error in DRIVE %d:\n", drv+1);\
181       else if( code==2 ) printf("FDC Seek Error in DRIVE %d:\n", drv+1);      \
182       else if( code==3 ) printf("FDC Over-size Error in DRIVE %d:\n", drv+1); \
183       else               printf("Internal error !\n");			      \
184     }while(0)
185 
186 
187 /*	------ �ǥ��������᡼���Υ��ơ����� ------			*/
188 /*		�ºݤ˰�̣�Τ��륹�ơ������ϰʲ��ΤȤ���		*/
189 /*			STATUS_MA	���Υ������� ID ��̵��		*/
190 /*			STATUS_DE	ID CRC Error			*/
191 /*			STATUS_MA_MD	���Υ������� DATA ��̵��	*/
192 /*			STATUS_DE_DD	DATA CRC Error			*/
193 /*			STATUS_CM	���� (DELETED DATA ����)	*/
194 /*			����¾		����				*/
195 
196 #define	STATUS_NORMAL	(0x00)		/* Normal End			*/
197 #define	STATUS_CM	(0x10)		/* Control Mark			*/
198 #define	STATUS_ALIGN	(0x20)		/* Alignment Error		*/
199 #define	STATUS_EN	(0x30)		/* End of Cylinder		*/
200 #define STATUS_EC	(0x40)		/* Equipment Check		*/
201 #define	STATUS_OR	(0x50)		/* Over Run			*/
202 #define	STATUS_NR	(0x60)		/* Not Ready			*/
203 #define	STATUS_NW	(0x70)		/* Not Writable			*/
204 #define	STATUS_UNDEF	(0x80)		/* Another Error		*/
205 #define	STATUS_TMOUT	(0x90)		/* Time out			*/
206 #define	STATUS_DE	(0xa0)		/* Data Error (ID)		*/
207 #define	STATUS_DE_DD	(0xb0)		/* Data Error (DATA)		*/
208 #define	STATUS_ND	(0xc0)		/* No Data			*/
209 #define	STATUS_BC	(0xd0)		/* Bad Cylinder			*/
210 #define	STATUS_MA	(0xe0)		/* Missing Address Mark (ID)	*/
211 #define	STATUS_MA_MD	(0xf0)		/* Missing Address Mark (DATA)	*/
212 
213 
214 
215 
216 /* FDC �� ���ơ����� */
217 
218 #define FD0_BUSY	(0x01)
219 #define	FD1_BUSY	(0x02)
220 #define	FD2_BUSY	(0x04)
221 #define	FD3_BUSY	(0x08)
222 #define FDC_BUSY	(0x10)
223 #define NON_DMA		(0x20)
224 #define DATA_IO		(0x40)
225 #define	REQ_MASTER	(0x80)
226 
227 /* FDC �� �ꥶ��ȥ��ơ����� */
228 
229 #define	ST0_US		(0x03)		/* Unit Select			*/
230 #define	ST0_HD		(0x04)		/* Head Address			*/
231 #define	ST0_NR		(0x08)		/* Not Ready			*/
232 #define	ST0_EC		(0x10)		/* Equipment Check		*/
233 #define	ST0_SE		(0x20)		/* Seek End			*/
234 #define	ST0_IC		(0xc0)		/* Interrupt Code		*/
235 #define	ST0_IC_NT	(0x00)		/* 	Normal Terminate	*/
236 #define	ST0_IC_AT	(0x40)		/* 	Abnormal Terminate	*/
237 #define	ST0_IC_IC	(0x80)		/* 	Invalid Command		*/
238 #define	ST0_IC_AI	(0xc0)		/* 	Attention Interrupt	*/
239 
240 #define	ST1_MA		(0x01)		/* Missing Address Mark		*/
241 #define	ST1_NW		(0x02)		/* Not Writable			*/
242 #define	ST1_ND		(0x04)		/* No Data			*/
243 #define	ST1_OR		(0x10)		/* Over Run			*/
244 #define	ST1_DE		(0x20)		/* Data Error			*/
245 #define	ST1_EN		(0x80)		/* End of Cylinder		*/
246 
247 #define	ST2_MD		(0x01)		/* Missing Address Mark in Data	*/
248 #define	ST2_BC		(0x02)		/* Bad Cylinder			*/
249 #define	ST2_SN		(0x04)		/* Scan Not Satisfied		*/
250 #define	ST2_SH		(0x08)		/* Scan Equal Hit		*/
251 #define	ST2_NC		(0x10)		/* No Cylinder			*/
252 #define	ST2_DD		(0x20)		/* Data Error in Data Files	*/
253 #define	ST2_CM		(0x40)		/* Control Mark			*/
254 
255 #define	ST3_US		(0x03)		/* Unit Select			*/
256 #define	ST3_HD		(0x04)		/* Head Address			*/
257 #define	ST3_TS		(0x08)		/* Two Side			*/
258 #define	ST3_T0		(0x10)		/* Track 0			*/
259 #define	ST3_RY		(0x20)		/* Ready			*/
260 #define	ST3_WP		(0x40)		/* Write Protect		*/
261 #define	ST3_FT		(0x80)		/* Fault			*/
262 
263 
264 
265 /* FDC �� ���ޥ�� */
266 
267 enum FdcCommand
268 {
269   WAIT			= 0,		/* �����Ԥ��ξ��� */
270   READ_DATA,
271   READ_DELETED_DATA,
272   READ_DIAGNOSTIC,
273   READ_ID,
274   WRITE_DATA,		/* = 5 */
275   WRITE_DELETED_DATA,
276   WRITE_ID,
277   SCAN_EQUAL,
278   SCAN_LOW_OR_EQUAL,
279   SCAN_HIGH_OR_EQUAL,	/* = 10 */
280   SEEK,
281   RECALIBRATE,
282   SENSE_INT_STATUS,
283   SENSE_DEVICE_STATUS,
284   SPECIFY,		/* = 15 */
285   INVALID,
286   EndofFdcCmd
287 };
288 enum FdcPhase
289 {
290   C_PHASE,
291   E_PHASE,
292   R_PHASE,
293   EndofFdcPhase
294 };
295 
296 static const char *cmd_name[] =	/* �ǥХå���ɽ���ǡ��� */
297 {
298   "WAIT ------------------",
299   "READ DATA -------------",
300   "READ DELETED DATA -----",
301   "READ DIAGNOSTIC -------",
302   "READ ID ---------------",
303   "WRITE DATA ------------",
304   "WRITE DELETED DATA ----",
305   "WRITE ID --------------",
306   "SCAN EQUAL ------------",
307   "SCAN LOW OR EQUAL -----",
308   "SCAN HIGH OR EQUAL ----",
309   "SEEK ------------------",
310   "RECALIBRATE -----------",
311   "SENSE INT STATUS ------",
312   "SENSE DEVIC STATUS ----",
313   "SPECIFY ---------------",
314   "INVALID ---------------",
315 };
316 
317 
318 
319 
320 
321 
322 
323 /************************************************************************/
324 /* fdc �ǥХå�								*/
325 /************************************************************************/
326 /*
327  * FDC �ǥХå������ϡ�peach��ˤ��������ޤ�����
328  */
pc88fdc_break_point(void)329 void pc88fdc_break_point(void)
330 {
331     int i;
332     for(i = 0; i < NR_BP; i++){
333 	if (break_point_fdc[i].type != BP_NONE) {
334 	    fdc_break_flag = TRUE;
335 	    return;
336 	}
337     }
338     fdc_break_flag = FALSE;
339 }
340 
341 
342 #ifndef	USE_MONITOR
343 
344 #define	print_fdc_status(nStatus,nDrive,nTrack,nSector)
345 
346 #else	/* USE_MONITOR */
347 
print_fdc_status(int nStatus,int nDrive,int nTrack,int nSector)348 void print_fdc_status(int nStatus, int nDrive, int nTrack, int nSector)
349 {
350     static int oDrive = -1;
351     static int oTrack[2];
352     static int oSector[2];
353     static int oStatus;
354     char c = ' ';
355     int i;
356 
357     if (fdc_debug_mode == TRUE) {
358 	if (oDrive < 0 || nStatus != oStatus || nDrive != oDrive ||
359 	    nTrack != oTrack[nDrive])
360 	{
361 	    oStatus = nStatus;
362 	    oDrive = nDrive;
363 	    oTrack[oDrive] = nTrack;
364 	    oSector[oDrive] = nSector;
365 	    switch (nStatus) {
366 	    case BP_READ:  c = 'R'; break;
367 	    case BP_WRITE: c = 'W'; break;
368 	    case BP_DIAG:  c = 'D'; break;
369 	    }
370 	    printf("\n%c D:%d T:%d S:%d", c, nDrive+1, nTrack, nSector+1);
371 	    fflush(stdout);
372 	} else if (nSector != oSector[nDrive]){
373 	    oSector[nDrive] = nSector;
374 	    printf(",%d", nSector+1);
375 	    fflush(stdout);
376 	}
377     }
378 
379     if (fdc_break_flag == TRUE) {
380 	for (i = 0; i < NR_BP; i++) {
381 	    if (break_point_fdc[i].type == nStatus &&
382 	        break_point_fdc[i].drive == nDrive + 1 &&
383 		break_point_fdc[i].track == nTrack) {
384 		if (break_point_fdc[i].sector == nSector + 1 ||
385 		    break_point_fdc[i].sector < 0) {
386 		    printf( "*** Break at D:%d T:%d S:%d *** ",
387 			    nDrive + 1, nTrack, nSector + 1);
388 		    switch (nStatus) {
389 		    case BP_READ:  printf("( Read )\n"); break;
390 		    case BP_WRITE: printf("( Write )\n"); break;
391 		    case BP_DIAG:  printf("( Diag )\n"); break;
392 	 	    }
393 		    quasi88_debug();
394 		    break;
395 		}
396 	    }
397 	}
398     }
399 
400 }
401 #endif	/* USE_MONITOR */
402 
403 /************************************************************************/
404 /* �������֤�����                                                     */
405 /************************************************************************/
406 /*
407  * READ DIAG �Υ������֤Υǡ�������������ϡ�peach��ˤ��������ޤ�����
408  */
409 static int fill_sector_gap(int ptr, int drv, Uchar fdc_mf);
410 
411 
412 
413 
414 
415 
416 
417 
418 /************************************************************************/
419 /* �ɥ饤�֤ν����							*/
420 /************************************************************************/
421 static	void	fdc_init( void );
drive_init(void)422 void	drive_init( void )
423 {
424   int	i;
425 
426   fdc_init();
427 
428   for( i=0; i<NR_DRIVE; i++ ){
429     drive[ i ].fp     = NULL;
430     drive[ i ].sec_nr = -1;
431     drive[ i ].empty  = TRUE;
432     /* memset( drive[ i ].filename, 0, QUASI88_MAX_FILENAME ); */
433   }
434   disk_ex_drv = 0;
435 
436   sec_buf.drv = -1;
437 }
438 
439 
440 /************************************************************************/
441 /* �ɥ饤�֤Υꥻ�åȡ�(�������ꤵ��Ƥ��륤�᡼���˥���������)	*/
442 /************************************************************************/
drive_reset(void)443 void	drive_reset( void )
444 {
445   int	i;
446 
447   fdc_init();
448 
449   for( i=0; i<NR_DRIVE; i++ ){
450     if( drive[ i ].fp ){
451       disk_change_image( i, drive[ i ].selected_image );
452     }
453   }
454   disk_ex_drv = 0;
455 }
456 
457 
458 
459 /************************************************************************/
460 /* �ɥ饤�֤���Ū�˶��ˤ��롿��Ȥ��᤹�����ؤ��롿�ɤä��ξ��֤��Τ�	*/
461 /*	drv�ĥɥ饤��(0/1)						*/
462 /************************************************************************/
drive_set_empty(int drv)463 void	drive_set_empty( int drv )
464 {
465   drive[ drv ].empty  = TRUE;
466 }
drive_unset_empty(int drv)467 void	drive_unset_empty( int drv )
468 {
469   drive[ drv ].empty  = FALSE;
470 }
drive_change_empty(int drv)471 void	drive_change_empty( int drv )
472 {
473   drive[ drv ].empty  ^= 1;
474 }
drive_check_empty(int drv)475 int	drive_check_empty( int drv )
476 {
477   return drive[ drv ].empty;
478 }
479 
480 
481 
482 /***********************************************************************
483  * �ɥ饤�� �˥ǥ���������������
484  *	drv		�ɥ饤�� 0 / 1
485  *	filename	�ե�����̾
486  *	img		���᡼���ֹ� 0��31
487  *			�ϰϳ��ʤ���¸�ߤ��ʤ����᡼���ֹ�ξ��� 0 �Ȥ���
488  *	readonly	���ʤ顢�꡼�ɥ���꡼�ǥե��������
489  *			���ʤ顢�꡼�ɥ饤�Ȥǥե��������
490  *
491  *	���顼���ϡ��ǥ��������åȤ����� 1 ���֤���
492  ************************************************************************/
493 
494 /* ���顼ɽ��( s �ϥ�å�������\n �ϥ���)�� �ǥ������ϥ��������Ȥ���� */
495 
496 #define		DISK_ERROR( s, drv )					\
497   do {									\
498     if (quasi88_is_menu() == FALSE) {					\
499       printf( "\n" );				 			\
500       printf( "[[[ %-26s ]]]\n", s );				  	\
501       printf( "[[[   Eject Disk from drive %d: ]]]\n" "\n", drv+1 ); 	\
502     }									\
503     disk_eject( drv );							\
504   } while(0)
505 
506 /* �ٹ�ɽ��( fmt �ϡ�"%s %d \n" ��ޤ�)�� �ǥ������Ϥ��Τޤ� */
507 
508 #define		DISK_WARNING( fmt, s, n )				\
509   do {									\
510     if( verbose_proc ){							\
511       printf( fmt, s, n );						\
512     }									\
513   } while(0)
514 
515 
516 
517 
disk_insert(int drv,const char * filename,int img,int readonly)518 int	disk_insert( int drv, const char *filename, int img, int readonly )
519 {
520   int	exit_flag;
521   Uchar c[32];
522   long	offset;
523   int	num;
524 
525   int	open_as_readonly = readonly;
526 
527   		/* ���ߤΥǥ������ϥ��������� */
528 
529   disk_eject( drv );
530 
531 
532 		/* �ե�����̾��Ф��Ƥ��� */
533   /*
534   if( strlen(filename) >= QUASI88_MAX_FILENAME ){
535     DISK_ERROR( "filename too long", drv );
536     return 1;
537   }
538   strcpy( drive[ drv ].filename, filename );
539   */
540 
541 		/* "r+b" �ǥե��������������ʤ� "rb" �ǥե�������� */
542 
543   if( open_as_readonly == FALSE ){
544     drive[ drv ].fp = osd_fopen( FTYPE_DISK, filename, "r+b" );
545   }
546   if( drive[ drv ].fp == NULL ){
547     drive[ drv ].fp = osd_fopen( FTYPE_DISK, filename, "rb" );
548     open_as_readonly = TRUE;
549   }
550 
551   if( drive[ drv ].fp == NULL ){
552     DISK_ERROR( "Open failed", drv );
553     return 1;
554   }
555 
556 
557 
558 	/* ȿ��¦�Υɥ饤�֤Υե������Ʊ���ե�������ä�����	*/
559 	/*			ȿ��¦�ɥ饤�֤Υ�����ԡ�	*/
560 	/* �����Ǥʤ�����	�ɥ饤�֤Υ��������	*/
561 
562   if( drive[ drv ].fp == drive[ drv^1 ].fp ){	/* ȿ�Хɥ饤�֤�Ʊ����� */
563 
564 /*  drive[ drv ].file_size           = drive[ drv^1 ].file_size;*/
565     drive[ drv ].read_only           = drive[ drv^1 ].read_only;
566     drive[ drv ].over_image          = drive[ drv^1 ].over_image;
567     drive[ drv ].detect_broken_image = drive[ drv^1 ].detect_broken_image;
568     drive[ drv ].image_nr            = drive[ drv^1 ].image_nr;
569     memcpy( &drive[ drv   ].image,
570 	    &drive[ drv^1 ].image, sizeof(drive[ drv ].image) );
571 
572     if( drv==0 ){
573       DISK_WARNING( " (( %s : Set in drive %d: <- 2: ))\n", filename, drv+1 );
574     }else{
575       DISK_WARNING( " (( %s : Set in drive 1: -> %d: ))\n", filename, drv+1 );
576     }
577 
578 
579   }else{					/* ȿ�Хɥ饤�֤Ȱ㤦��� */
580 
581 
582     if( open_as_readonly ){
583       drive[ drv ].read_only = TRUE;
584 
585       DISK_WARNING( " (( %s : Set in drive %d: as read only ))\n",
586 		    filename, drv+1 );
587     }else{
588       drive[ drv ].read_only = FALSE;
589 
590       DISK_WARNING( " (( %s : Set in drive %d: ))\n", filename, drv+1 );
591     }
592 
593     /*
594     drive[ drv ].file_size = osd_file_size( drive[ drv ].filename );
595     if( drive[ drv ].file_size == -1 ){
596       DISK_ERROR( "Access Error(size)", drv );
597       return 1;
598     }
599     */
600 
601     drive[ drv ].over_image          = FALSE;
602     drive[ drv ].detect_broken_image = FALSE;
603 
604     num = 0;	offset = 0;
605     exit_flag = FALSE;
606 
607 
608 			/* �ƥ��᡼���Υإå���������Ƽ��� */
609     while( !exit_flag ){
610 
611       switch( d88_read_header( drive[ drv ].fp, offset, c ) ){
612 
613       case D88_SUCCESS:			/* ���᡼������������� */
614 
615 	memcpy( &drive[ drv ].image[ num ].name[0], &c[0], 16 );
616 	drive[ drv ].image[ num ].name[16] = '\0';
617 	drive[ drv ].image[ num ].protect  = c[DISK_PROTECT];
618 	drive[ drv ].image[ num ].type     = c[DISK_TYPE];
619 	drive[ drv ].image[ num ].size     = READ_SIZE_IN_HEADER( c );
620 
621 						/* ���Υ��᡼���ξ�������� */
622 	offset += drive[ drv ].image[ num ].size;
623 	num ++;
624 
625 	if( num >= MAX_NR_IMAGE ){		/* ���᡼������¿���������� */
626 	  DISK_WARNING( " (( %s : Too many images [>=%d] ))\n",
627 			filename, MAX_NR_IMAGE );
628 	  drive[ drv ].over_image = TRUE;
629 	  exit_flag = TRUE;
630 	}
631 	else if( offset < 0 ){			/* ���᡼�����������礭����? */
632 	  DISK_WARNING( " (( %s : Too big image? [%d] ))\n", filename, num+1 );
633 	  drive[ drv ].detect_broken_image = TRUE;
634 	  exit_flag = TRUE;
635 	}
636 	break;
637 
638       case D88_NO_IMAGE:		/* ����ʾ奤�᡼�����ʤ� */
639 	exit_flag = TRUE;
640 	break;
641 
642       case D88_BAD_IMAGE:		/* ���Υ��᡼���ϲ���Ƥ��� */
643 	DISK_WARNING( " (( %s : Image No. %d Broken? ))\n", filename, num+1 );
644 	drive[ drv ].detect_broken_image = TRUE;
645 	exit_flag = TRUE;
646 	break;
647 
648       default:				/* ??? */
649 	DISK_WARNING( " (( %s : Image No. %d Error? ))\n", filename, num+1 );
650 	drive[ drv ].detect_broken_image = TRUE;
651 	exit_flag = TRUE;
652 	break;
653 
654       }
655     }
656 
657     if( num==0 ){
658       DISK_ERROR( "Image not found", drv );
659       return 1;
660     }
661 
662     drive[ drv ].image_nr = num;
663 
664   }
665 
666 
667 
668 	/* disk_top ��img ���ܤΥǥ��������᡼������Ƭ������	*/
669 
670   if( img < 0 || img >= drive[ drv ].image_nr ){
671     DISK_WARNING( " (( %s : Image No. %d Not exist ))\n", filename, img+1 );
672     drive_set_empty( drv );
673   }else{
674     disk_change_image( drv, img );
675   }
676 
677 
678 
679   return 0;
680 }
681 
682 
683 
684 /***********************************************************************
685  * ȿ��¦�Υɥ饤�֤Υ��᡼�������ä��Υɥ饤�֤ˤ⥻�åȤ���
686  *	src	ȿ��¦�Υɥ饤�� 0 or 1
687  *	dst	���ä��Υɥ饤�� 1 or 0
688  *	img	���᡼���ֹ� -1, 0��31
689  *		�ϰϳ��ʤ���¸�ߤ��ʤ����᡼���ֹ�ξ��ϡ����Ȥ���
690  *
691  *	���顼���ϡ��ǥ��������åȤ����� 1 ���֤���
692  ************************************************************************/
disk_insert_A_to_B(int src,int dst,int img)693 int	disk_insert_A_to_B( int src, int dst, int img )
694 {
695 
696   disk_eject( dst );
697 
698 
699   if( drive[ src ].fp == NULL ){
700     return 0;
701   }
702 
703 
704   /* strcpy( drive[ dst ].filename, drive[ src ].filename ); */
705 
706 
707   drive[ dst ].fp = drive[ src ].fp;
708 
709 /*drive[ dst ].file_size           = drive[ src ].file_size;*/
710   drive[ dst ].read_only           = drive[ src ].read_only;
711   drive[ dst ].over_image          = drive[ src ].over_image;
712   drive[ dst ].detect_broken_image = drive[ src ].detect_broken_image;
713   drive[ dst ].image_nr            = drive[ src ].image_nr;
714 
715   memcpy( &drive[ dst ].image, &drive[ src ].image, sizeof(drive[0].image) );
716 
717 
718   if( img < 0 || img >= drive[ dst ].image_nr ){
719     drive_set_empty( dst );
720   }else{
721     disk_change_image( dst, img );
722   }
723 
724   return 0;
725 }
726 
727 
728 
729 /************************************************************************/
730 /* ���᡼�����ѹ����롣							*/
731 /*	disk_top ��img ���ܤΥǥ��������᡼������Ƭ�����ꤷ��		*/
732 /*	pcn*2 �ȥ�å�����Ƭ�˰�ư���롣				*/
733 /*	drv�ĥɥ饤��(0/1)						*/
734 /************************************************************************/
735 static void disk_now_track( int drv, int trk );
736 
disk_change_image(int drv,int img)737 int	disk_change_image( int drv, int img )
738 {
739   int	i;
740 
741   if( drive[ drv ].fp==NULL ){				/* �ɥ饤��̤���å� */
742     return 1;
743   }
744   if( img < 0 || img >= drive[ drv ].image_nr ){	/* ���ꥤ�᡼��̵�� */
745     return -1;
746   }
747 
748 		/* disk_top ��׻� */
749 
750   drive[ drv ].selected_image = img;
751   drive[ drv ].empty          = FALSE;
752 
753   drive[ drv ].disk_top = 0;
754   for( i=0; i<img; i++ ){
755     drive[ drv ].disk_top += drive[ drv ].image[ i ].size;
756   }
757   drive[ drv ].disk_end = drive[ drv ].disk_top + drive[ drv ].image[img].size;
758   drive[ drv ].protect  = drive[ drv ].image[ img ].protect;
759   drive[ drv ].type     = drive[ drv ].image[ img ].type;
760 
761 
762   if( fdc_ignore_readonly == FALSE ){
763 
764     /* ReadOnly �ǥե������������硢̵���ǥ饤�ȥץ�ƥ��Ⱦ��֤Ȥ��� */
765 
766     if( drive[ drv ].read_only ) drive[ drv ].protect = DISK_PROTECT_TRUE;
767 
768   }else{
769 
770     /* ReadOnly �ǥե�������������⡢�饤�ȥץ�ƥ��Ⱦ��֤ϥ��᡼����
771        °���ˤ������������Υ��᡼�����Ф��ƽ����ߤ�Ԥʤä���硢
772        �ºݤˤϽ����ߤϹԤʤ��ʤ�����������ェλ���֤���
773        ( ����ɥ顢�ߥ��ƥ��֥롼��ŷ�Ȥ����θ��2 �ʤɡ� ReadOnly ����
774          ��ư���餷�Ƥ���ʤ�����������˵�ư�����롣�����Τ��� ) */
775     ;
776   }
777 
778 		/* pcn*2 �ȥ�å�����Ƭ�˰�ư���� */
779 
780   disk_now_track( drv, fdc.pcn[drv]*2 );
781 
782   if (disk_exchange) disk_ex_drv |= 1 << drv;	/* �ǥ����������ؤ������ */
783 
784   return 0;
785 }
786 
787 
788 
789 /************************************************************************/
790 /* �ǥ��������������Ȥ���						*/
791 /*	2 �ɥ饤�֤Ǥ���ȸ��ꤷ��ȿ�ФΥɥ饤�֤���Ӥ��롣		*/
792 /*	Ʊ���Ǥ���С�������������㤨�С��ե�������Ĥ���		*/
793 /*	drv�ĥɥ饤��(0/1)						*/
794 /************************************************************************/
disk_eject(int drv)795 void	disk_eject( int drv )
796 {
797   if( drive[ drv ].fp ){
798     if( drive[ drv ].fp != drive[ drv^1 ].fp ){
799       osd_fclose( drive[ drv ].fp );
800     }
801   }
802   drive[ drv ].fp = NULL;
803   drive[ drv ].sec_nr = -1;
804   drive[ drv ].empty  = TRUE;
805   /* memset( drive[ drv ].filename, 0, QUASI88_MAX_FILENAME ); */
806 
807   sec_buf.drv = -1;
808 }
809 
810 
811 
812 
813 /*======================================================================*/
814 /* �إåɤ�ȥ�å�����Ƭ�˰�ư����					*/
815 /*	drv�ĥɥ饤��(0/1)  trk�ĥȥ�å��ֹ�(0��)			*/
816 /*									*/
817 /*	���顼���Ф����ϡ����Υȥ�å��ϥ���ե����ޥåȤˤʤ롣	*/
818 /*======================================================================*/
819 static int disk_now_sec( int drv );
820 
disk_now_track(int drv,int trk)821 static	void	disk_now_track( int drv, int trk )
822 {
823   int	error = 0;
824   Uchar c[4];
825   long	track_top;
826 
827 
828 
829 	/* ��������ǽ�������Υ����å� */
830 
831   if     ( drive[ drv ].type==DISK_TYPE_2D  && trk>=84  ) trk =  83;
832   else if( drive[ drv ].type==DISK_TYPE_2DD && trk>=164 ) trk = 163;
833   else if( drive[ drv ].type==DISK_TYPE_2HD && trk>=158 ) trk = 157;
834   else if( trk>=164 ) trk = 163; /* �����ޤǤΤФ��� 2DD/2HD ���б��Ǥ��� */
835 						        /* thanks peach ! */
836 
837 	/* ������� & ����� */
838 
839   drive[ drv ].track     = trk;
840   drive[ drv ].sec       = 0;
841 
842 
843 	/* �ȥ�å��Υ���ǥå����ǻ��ꤵ�줿�ե�������֤���� */
844 
845   if( osd_fseek( drive[ drv ].fp,
846 		 drive[ drv ].disk_top + DISK_TRACK + trk*4,  SEEK_SET )==0 ){
847     if( osd_fread( c, sizeof(Uchar), 4, drive[ drv ].fp )==4 ){
848 
849 	/* �ȥ�å�����ӡ���Ƭ�������ΰ��֤�����   */
850 	/* ���Υ������Υ�����������ӡ��������������� */
851 
852       track_top = (long)c[0]+((long)c[1]<<8)+((long)c[2]<<16)+((long)c[3]<<24);
853       if( track_top!=0 ){
854 	drive[ drv ].track_top =
855 	drive[ drv ].sec_pos   = drive[ drv ].disk_top + track_top;
856 	drive[ drv ].sec_nr    = disk_now_sec( drv );
857       }else{
858 	drive[ drv ].track_top =
859 	drive[ drv ].sec_pos   = drive[ drv ].disk_top;
860 	drive[ drv ].sec_nr    = -1;
861       }
862     }
863     else error = 1;
864   } else error = 2;
865 
866   if( error ){					/* SEEK / READ Error */
867     printf_system_error( error );
868   }
869 
870 	/* ���顼���ϡ�����ե����ޥå�(�ƥե����ޥå���ǽ)�ˤ��ơ���� */
871 
872   if( error ){
873     drive[ drv ].track_top =
874     drive[ drv ].sec_pos   = drive[ drv ].disk_top;
875     drive[ drv ].sec_nr    = -1;
876   }
877 
878   sec_buf.drv = drv;			/* �����оݤΥɥ饤�֤�Ф��Ƥ��� */
879   return;
880 }
881 
882 
883 
884 /*======================================================================*/
885 /* ���ꤵ�줿�ǥ������θ��ߤΥ������ξ�����ɤߤȤ�			*/
886 /*	drv�ĥɥ饤��(0/1)						*/
887 /*									*/
888 /*	���顼���ϡ����Υ������Τ� ID CRC Error ���顼�����ꤹ�롣	*/
889 /*	�֤��ͤϡ����Υ������Ρ��֥�������(DISK_SEC_NR)�פ���		*/
890 /*======================================================================*/
disk_now_sec(int drv)891 static	int	disk_now_sec( int drv )
892 {
893   int	error = 0;
894   Uchar	c[16];
895 
896 	/* �ե�������� sec_pos �� ID���� ���ɤߡ������������֤� */
897 
898   if( osd_fseek( drive[ drv ].fp,  drive[ drv ].sec_pos,  SEEK_SET )==0 ){
899     if( osd_fread( c, sizeof(Uchar), 16, drive[ drv ].fp )==16 ){
900       sec_buf.c       = c[DISK_C];
901       sec_buf.h       = c[DISK_H];
902       sec_buf.r       = c[DISK_R];
903       sec_buf.n       = c[DISK_N];
904       sec_buf.density = c[DISK_DENSITY];
905       sec_buf.deleted = c[DISK_DELETED];
906       sec_buf.status  = c[DISK_STATUS];
907       sec_buf.sec_nr  = c[DISK_SEC_NR] + (int)c[DISK_SEC_NR+1]*256;
908       sec_buf.size    = c[DISK_SEC_SZ] + (int)c[DISK_SEC_SZ+1]*256;
909       if( sec_buf.status==STATUS_CM ){
910 	sec_buf.deleted = DISK_DELETED_TRUE;
911 	sec_buf.status  = STATUS_NORMAL;
912       }
913     }
914     else error = 1;
915   } else error = 2;
916 
917   if( error ){					/* SEEK / READ Error */
918     printf_system_error( error );
919     status_message( 1, STATUS_WARN_TIME, "DiskI/O Read Error" );
920   }
921 
922 
923 
924 	/* ���Ԥ����顢ID CRC Error �ˤ���0 (==unformat) ���֤� */
925 
926   if( error ){
927     sec_buf.sec_nr  = 0;
928     sec_buf.status  = STATUS_DE;
929   }
930 
931   return ( sec_buf.sec_nr );
932 }
933 
934 
935 
936 /*======================================================================*/
937 /* ���ꤵ�줿�ǥ������μ��Υ������ξ�����ɤߤȤ�			*/
938 /*	drv�ĥɥ饤��(0/1)						*/
939 /*======================================================================*/
disk_next_sec(int drv)940 static	void	disk_next_sec( int drv )
941 {
942   int	overwrite_id;
943 
944 	/* ����ե����ޥåȻ��ϡ��ʤˤ⤷�ʤ� */
945 
946   if( disk_unformat( drv ) ) return;
947 
948 
949 	/* sec_top ���Υ������ˡ��ǽ��������λ��ϥȥ�å���Ƭ�� */
950 
951 			/* �ߥå����������������˾�����줿 ID �ο� */
952 			/* �����դ����Τ˥����å��Ǥ��ʤ����ɤ����褦 */
953 
954   if( sec_buf.size == 0x80 ||		/* sec_buf.size�� 0x80,0x100,0x200 */
955      (sec_buf.size & 0xff) == 0 ){	/* 0x400,0x800,0x1000 �ξ��(����) */
956     overwrite_id = 0;
957   }else{				/* ����ʳ��ϡ��ߥå�������������  */
958     overwrite_id = ( sec_buf.size - ( 128 << (sec_buf.n & 7)) ) / SZ_DISK_ID;
959     if( overwrite_id < 0 ) overwrite_id = 0;
960   }
961 
962 
963   drive[ drv ].sec += ( 1 + overwrite_id );
964   if( drive[ drv ].sec < drive[ drv ].sec_nr ){
965 
966     drive[ drv ].sec_pos += (sec_buf.size + SZ_DISK_ID);
967 
968   }else{
969 
970     drive[ drv ].sec = 0;
971     drive[ drv ].sec_pos = drive[ drv ].track_top;
972 
973   }
974 
975 	/* sec_pos �� ������ID���� ���ɤ� */
976 
977   disk_now_sec( drv );
978 }
979 
980 
981 
982 /************************************************************************/
983 /* FDC �ν����								*/
984 /************************************************************************/
fdc_init(void)985 static	void	fdc_init( void )
986 {
987   int	i;
988 
989   fdc.status  = 0 | REQ_MASTER;
990   fdc.read    = 0xff;
991   fdc.write   = 0xff;
992   fdc.TC      = FALSE;
993 
994   fdc.command = WAIT;
995 
996   for( i=0; i<MAX_DRIVE; i++ ){
997     fdc.seek_stat[ i ] = SEEK_STAT_STOP;
998     fdc.seek_wait[ i ] = 0;
999     fdc.ncn[ i ]  = 0;
1000     fdc.pcn[ i ]  = 0;
1001   }
1002   fdc.intr_unit = 4;
1003 }
1004 
1005 
1006 
1007 /************************************************************************/
1008 /* CPU�� FDC �˥��������������˸Ƥִؿ���				*/
1009 /*	void	fdc_write( byte data )	�ġġ� OUT A,(0FBH)		*/
1010 /*	byte	fdc_read( void )	�ġġ� IN  A,(0FBH)		*/
1011 /*	byte	fdc_status( void )	�ġġ� IN  A,(0FAH)		*/
1012 /*	void	fdc_TC( void )		�ġġ� IN  A,(0F8H)		*/
1013 /************************************************************************/
fdc_write(byte data)1014 void	fdc_write( byte data )
1015 {
1016   if( (fdc.status & DATA_IO)==0 ){
1017     fdc.status &= ~REQ_MASTER;
1018     fdc.write   = data;
1019   }
1020 }
1021 
fdc_read(void)1022 byte	fdc_read( void )
1023 {
1024   if( (fdc.status & DATA_IO) ){
1025     fdc.status &= ~REQ_MASTER;
1026     return fdc.read;
1027   }else{
1028     return 0xff;
1029   }
1030 }
1031 
fdc_status(void)1032 byte	fdc_status( void )
1033 {
1034   return fdc.status;
1035 }
1036 
fdc_TC(void)1037 void	fdc_TC( void )
1038 {
1039   fdc.TC = TRUE;
1040 }
1041 
1042 
1043 
1044 /* FDC ����CPU�ؤγ���������  */
1045 
1046 #define	fdc_occur_interrupt()	FDC_flag = TRUE
1047 #define	fdc_cancel_interrupt()	FDC_flag = FALSE
1048 
1049 
1050 /* FDC�����������Ȥ����� */
1051 
1052 #define	ICOUNT(x)	do{  fdc.wait = (x);			      }while(0)
1053 #define	REPEAT()	do{  if( fdc_wait==FALSE ){ fdc.wait = 0; }   }while(0)
1054 
1055 
1056 /*#define	logfdc	printf*/
1057 /*======================================================================
1058  * E-PHASE �ˤơ��Ƽ�������פ��륯��å������Ф���ؿ����ޥ���
1059  *======================================================================*/
1060 
1061 #if 0	/* �������Ȥ����٤����褦�Ȥ������ɡ��ʤ������������ٲ᤮��ġ� */
1062 
1063 /* GAP3/GAP4�ΥХ��ȿ������ʤ�Ŭ�������������⤫�ʤ�Ŭ���ˡ�		*/
1064 /* N = 0/1/2/3/4/5/6/7 �λ��� SC = 26/16/ 9/ 5/ 2/ 1/ 1/ 1 �Ȥ�����	*/
1065 static const int gap3_tbl[] = { 26, 54, 84, 116, 150, 186, 224, 264 };
1066 static const int gap4_tbl[] = { 488, 152, 182, 94, 1584, 1760, 2242, 4144 };
1067 
1068 #define	CLOCK_GAP0()      (128*( 80+12+(3+1)+50 ))
1069 
1070 #define	CLOCK_ID()        (128*( 12+(3+1)+4+2+22 ))
1071 #define	CLOCK_DATA(n)     (128*( 12+(3+1)+(128<<(n))+2+gap3_tbl[(n)&7] ))
1072 #define	CLOCK_SECTOR(n)   ( CLOCK_ID() + CLOCK_DATA(n) )
1073 
1074 #define	CLOCK_RID_ID()    (128*( 12+(3+1)+4+2 ))
1075 #define	CLOCK_RID_DATA(n) (128*( 22 + 12+(3+1)+(128<<(n))+2+gap3_tbl[(n)&7] ))
1076 
1077 #define	CLOCK_RDT_ID()    (128*( 12+(3+1)+4+2+22 + 12+(3+1) ))
1078 #define	CLOCK_RDT_DATA(n) (128*( (128<<(n))+2+gap3_tbl[(n)&7] ))
1079 
1080 #define	CLOCK_GAP3(n)     (128*( gap3_tbl[(n)&7] ))
1081 #define	CLOCK_GAP4(n)     (128*( gap4_tbl[(n)&7] ))
1082 #define	CLOCK_TRACK()     (128*( 6250 ))
1083 
1084 /* 1�Х��Ȥ�ž������ 32us */
1085 #define	CLOCK_BYTE()      (128)
1086 #define	CLOCK_2MS()       (8000)
1087 
1088 #else	/* �Ȥꤢ�������������٤Ǥ����� */
1089 
1090 #define	CLOCK_GAP0()      (0)
1091 #define	CLOCK_ID()        (0)
1092 #define	CLOCK_DATA(n)     (0)
1093 #define	CLOCK_SECTOR(n)   ( CLOCK_ID() + CLOCK_DATA(n) )
1094 #define	CLOCK_RID_ID()    (0)
1095 #define	CLOCK_RID_DATA(n) (0)
1096 #define	CLOCK_RDT_ID()    (128*( 12+(3+1)+4+2+22 + 12+(3+1) ))
1097 #define	CLOCK_RDT_DATA(n) (0)
1098 #define	CLOCK_GAP3(n)     (0)
1099 #define	CLOCK_GAP4(n)     (0)
1100 #define	CLOCK_TRACK()     (128*( 6250 ))
1101 #define	CLOCK_BYTE()      (128)
1102 #define	CLOCK_2MS()       (8000)
1103 #endif
1104 
1105 
1106 /* �إåɥ��ɡ��������Υ������Ȥ��¬���뤫�ɤ��� */
1107 #define WAIT_FOR_HEADLOAD
1108 #define WAIT_FOR_SEEK
1109 
1110 
1111 
1112 
1113 /*===========================================================================
1114  * READ/WRITE�ϥ��ޥ�ɤǡ�ID�������˥�˥åȤʤɤΥ����å���Ԥ�
1115  *	����ͤ� 0 �ξ�硢�ǥ��������ʤ��Τǡ��ǥ��������åȤ�̵�¤��Ԥ�
1116  *	����ͤ� 1 �ξ�硢��̤� ST0��ST2 �˥��åȤ����
1117  *			   (�����Υ��顼�Ϥ����Ǥϥ��åȤ��ʤ�)
1118  *===========================================================================*/
fdc_check_unit(void)1119 static	int	fdc_check_unit( void )
1120 {
1121   int	drv = (fdc.us);
1122 
1123 	/* ̤��³�ɥ饤�֤䡢��������ɥ饤�֤���ʤ顢�۾ェλ */
1124 
1125   if( fdc.us >= NR_DRIVE || fdc.status & (0x0f) ){
1126     fdc.st0 = ST0_IC_AT | ST0_NR | (fdc.hd<<2) | fdc.us;
1127     fdc.st1 = 0;
1128     fdc.st2 = 0;
1129     if( fdc.command == READ_ID ){ fdc.c = fdc.h = fdc.r = fdc.n = 0xff; }
1130     fdc.carry = 0;
1131     return 1;
1132   }
1133 
1134 	/* �ǥ�������̵�����ϡ����ĤޤǤ��äƤ⽪��ʤ� */
1135 
1136   if( disk_not_exist( drv ) ){
1137     fdc.wait  = CLOCK_2MS();			   /* 2ms��ˤ��ʤ���	*/
1138     fdc.carry = 0;
1139     return 0;
1140   }
1141 
1142 	/* �饤�ȷϥ��ޥ�ɤǡ��饤�ȥץ�ƥ��Ȼ��ϡ��۾ェλ */
1143 
1144   if( fdc.command == WRITE_ID   ||
1145       fdc.command == WRITE_DATA ||
1146       fdc.command == WRITE_DELETED_DATA ){
1147     if( drive[ drv ].protect == DISK_PROTECT_TRUE ){
1148       fdc.st0 = ST0_IC_AT | (fdc.hd<<2) | fdc.us;
1149       fdc.st1 = ST1_NW;
1150       fdc.st2 = 0;
1151       fdc.carry = 0;
1152       status_message( 1, STATUS_WARN_TIME, "Disk Write Protected" );
1153       return 1;
1154     }
1155   }
1156 
1157 	/* �إåɤ�������ɻ��ϡ��إåɥ��ɻ��֤�û� */
1158 
1159 #ifdef	WAIT_FOR_HEADLOAD
1160   if( fdc.hl_stat[drv] == FALSE ){
1161     /* ���ɲ� ? */
1162     if ((cpu_timing > 0) && (fdc_wait)) {
1163       /*logfdc("### Head Down ###\n");*/
1164       xmame_dev_sample_headdown();
1165     }
1166     fdc.hl_stat[drv] = TRUE;
1167     fdc.wait += fdc.hlt_clk;
1168   }
1169   fdc.hl_wait[drv] = 0;
1170 #endif
1171 
1172 
1173 	/* �����IDR �����ߤΥȥ�å����֤Ȱ㤦���ϡ��ȥ�å��ѹ� */
1174 
1175   if( fdc.command == READ_DIAGNOSTIC ||	    /* READ DIAGNOSTIC �ޤ���        */
1176       fdc.command == WRITE_ID        ){	    /* WRITE ID        �ξ��        */
1177 					    /*    �ȥ�å���Ƭ������������ */
1178 					    /*    ɬ���ȥ�å��ѹ� (Ƭ�Ф�)  */
1179     if( ! disk_unformat(drv)   &&
1180 	( drive[drv].track & 1 ) == fdc.hd ){
1181       fdc.wait += CLOCK_TRACK()
1182 		    * (drive[drv].sec_nr - drive[drv].sec) / drive[drv].sec_nr;
1183     }
1184     disk_now_track( drv, ((drive[drv].track & ~1)|fdc.hd) );
1185     fdc.carry = 0;
1186 
1187   }else{				    /* ����ʳ��ξ��                */
1188 					    /*    ���ߥ��������֤����ɤ�     */
1189 
1190     if( sec_buf.drv != drv ){			/* �ɥ饤�־���ο����㤤����*/
1191 
1192       disk_now_track( drv, ((drive[drv].track & ~1)|fdc.hd) );
1193       fdc.carry = 0;
1194       logfdc("\n<< sector reload >>\t\t\t");
1195       if( verbose_fdc )
1196 	printf("FDC log : sec_buf reload $$$$\n" );
1197 
1198     }else
1199 
1200     if( ( drive[drv].track & 1 ) != fdc.hd ){	/* �إåɰ��֤��ۤʤ���Τ�  */
1201       int i, s = drive[drv].sec;		/* �ȥ�å��ѹ�����          */
1202 
1203       disk_now_track( drv, ((drive[drv].track & ~1)|fdc.hd) );
1204       fdc.carry = 0;
1205 
1206       if( fdc_wait ){
1207 	if( ! disk_unformat(drv) ){
1208 	  for( i=0; i<s; i++ ){				/* ���������֤��ư  */
1209 	    if( drive[drv].sec >= s ) break;		/* �إåɰ�ư����    */
1210 	    disk_next_sec( drv );			/* ��������Ʊ������  */
1211 	  }						/* �˰�ư�����褦    */
1212 	}
1213       }
1214     }
1215   }
1216 
1217 	/* ����ե����ޥåȤλ��ϡ�ľ���˰۾ェλ (WRITE_ID ����) */
1218 
1219   if( fdc.command != WRITE_ID ){
1220     if( disk_unformat( drv ) || disk_unformatable( drv ) ){
1221       fdc.st0 = ST0_IC_AT | (fdc.hd<<2) | fdc.us;
1222       fdc.st1 = ST1_MA;
1223       fdc.st2 = 0;
1224       if( fdc.command == READ_ID ){ fdc.c = fdc.h = fdc.r = fdc.n = 0xff; }
1225       fdc.wait += CLOCK_TRACK() * 2;
1226       fdc.carry = CLOCK_GAP0();
1227       return 1;
1228     }
1229   }
1230 
1231 	/* ����ۤ�ʬ�Υ������Ȥ�������ϡ��û� */
1232 
1233   if( fdc.carry > 0 ){
1234     fdc.wait += fdc.carry;
1235   }
1236   fdc.carry = 0;
1237 
1238 
1239 	/* ��ö��λ��ST0 �� NT(Normal Terminate:���ェλ) ���å� */
1240 
1241   fdc.st0 = ST0_IC_NT | (fdc.hd<<2) | fdc.us;
1242   fdc.st1 = 0;
1243   fdc.st2 = 0;
1244 
1245   return 1;
1246 }
1247 
1248 
1249 
1250 /*===========================================================================
1251  * READ/WRITE�ϥ��ޥ�ɤǡ�ID��õ��
1252  *	����ͤ� 0 �ξ�硢�ǥ��������ʤ��Τǡ��ǥ��������åȤ�̵�¤��Ԥ�
1253  *	����ͤ� 1 �ξ�硢��̤� ST0��ST2 �˥��åȤ����
1254  *			   (�����Υ��顼�Ϥ����Ǥϥ��åȤ��ʤ�)
1255  *===========================================================================*/
fdc_search_id(void)1256 static	int	fdc_search_id( void )
1257 {
1258   int	drv = (fdc.us);
1259   int	index_cnt = 0;			/* ����ǥå����ۡ��븡�в�� */
1260   int	exist_iam = FALSE;		/* IAM��1�٤Ǥ⸫�Ĥ��ä��鿿 */
1261   int	n;
1262 
1263 	/* �ǽ�ˡ���˥åȤʤɤΥ����å���Ԥ� */
1264 
1265   if( fdc_check_unit() == 0 ){		/* �ǥ�������̵���Ȥ������ */
1266     return 0;
1267   }else{
1268     if( fdc.st0 & ST0_IC ){		/* �ʤˤ��۾郎��������   */
1269       return 1;				/* (Busy,Protect,Un-format) */
1270     }
1271   }
1272 
1273 	/* ���������� (�����������Ĥ��뤫����ǥå����ۡ���2���Фǽ�λ) */
1274 
1275   if     ( sec_buf.sec_nr > 19 ) n = 0;		/* �ȥ�å��ե����ޥåȻ��� */
1276   else if( sec_buf.sec_nr > 10 ) n = 1;		/* N ��Ŭ���˿�¬����       */
1277   else if( sec_buf.sec_nr >  5 ) n = 2;		/* (GAP3��GAP4Ĺ�λ�����)   */
1278   else if( sec_buf.sec_nr >  2 ) n = 3;
1279   else if( sec_buf.sec_nr >  1 ) n = 4;
1280   else                           n = 5;
1281 
1282   while( 1 ){
1283 
1284     if( sector_density_mismatch()   ||	/* ���Υ������ˤ� IAM ���ʤ�         */
1285         sec_buf.status == STATUS_MA ){
1286       ;							/* ���Υ�������̵��  */
1287 
1288     }else{				/* ���Υ������ˤ� IAM ������         */
1289       exist_iam = TRUE;
1290 
1291       if( fdc.command == READ_DIAGNOSTIC ){	/* READ DIAG �ξ��          */
1292 	if( sec_buf.status == STATUS_MA_MD ){		/* DATA mark �ʤ�    */
1293 	  return 0;					/*	�ϥ����롩 */
1294 	}else{						/* DATA mark ����    */
1295 	  break;					/*	������������ */
1296 	}
1297 
1298       }else if( fdc.command == READ_ID ){	/* READ ID�ξ��             */
1299 	if( sec_buf.status == STATUS_DE ){		/* ID CRC �۾��     */
1300 	  ;						/*	������������ */
1301 	}else{						/* ID CRC �����     */
1302 	  break;					/*	������������ */
1303 	}
1304 
1305       }else{					/* READ / WRITE �ξ��       */
1306 	if( idr_match() ){				/* IDR ���׻�        */
1307 	  if( sec_buf.status == STATUS_DE ){		    /* ID CRC �۾�   */
1308 	    fdc.st0 = ST0_IC_AT | (fdc.hd<<2) | fdc.us;
1309 	    fdc.st1 = ST1_DE;
1310 	    fdc.st2 = 0;
1311 
1312 	    fdc.wait += CLOCK_RID_ID();
1313 	    fdc.carry = CLOCK_RID_DATA( n );
1314 	    disk_next_sec( drv );
1315 	    if( drive[drv].sec==0 ) fdc.carry += CLOCK_GAP4(n) + CLOCK_GAP0();
1316 	    return 1;
1317 	  }
1318 	  else
1319 	  if( sec_buf.status == STATUS_MA_MD     &&	    /* (D)DAM �ʤ�   */
1320 	      (fdc.command == READ_DATA ||		    /*   (READ���Τ�)*/
1321 	       fdc.command == READ_DELETED_DATA) ){
1322 
1323 	    fdc.st0 = ST0_IC_AT | (fdc.hd<<2) | fdc.us;
1324 	    fdc.st1 = ST1_MA;
1325 	    fdc.st2 = ST2_MD;
1326 
1327 	    fdc.wait += CLOCK_RID_ID() + CLOCK_2MS();
1328 	    disk_next_sec( drv );
1329 	    if( drive[drv].sec==0 ) fdc.carry += CLOCK_GAP4(n) + CLOCK_GAP0();
1330 	    return 1;
1331 	  }
1332 	  else{
1333 	    break;					    /* ������������  */
1334 	  }
1335 	}else{						/*  IDR ���פ��ʤ��� */
1336 	  ;						    /* ������������  */
1337 	}
1338       }
1339     }
1340 
1341 					/* ���פ��ʤ��ä��ΤǼ����������� */
1342     fdc.wait += CLOCK_SECTOR( n );
1343     disk_next_sec( drv );
1344 
1345     if( drive[drv].sec == 0 ){		/* ����ǥå����ۡ������         */
1346       index_cnt ++;
1347       fdc.wait += CLOCK_GAP4( n );
1348 
1349       if( index_cnt >= 2 ){			/* ��פǡ�2���Ф���      */
1350 
1351 	fdc.st0 = ST0_IC_AT | (fdc.hd<<2) | fdc.us;
1352 	fdc.st1 = (exist_iam) ? ST1_ND   : ST1_MA;	    /* IAM��1�٤Ǥ� */
1353 	fdc.st2 = (exist_iam) ? 0 /*��*/ : 0;		    /* ���Ĥ��ä��� */
1354 	if( exist_iam ){				    /* ���ơ������� */
1355 	  if( fdc.c != fdc.pcn[drv] ){ fdc.st2 |= ST2_NC;   /* �㴳�ۤʤ�   */
1356 	  if( fdc.c == 0xff )          fdc.st2 |= ST2_BC; }
1357 	}
1358 	if( fdc.command == READ_ID ){ fdc.c = fdc.h = fdc.r = fdc.n = 0xff; }
1359 	fdc.carry = CLOCK_GAP0();
1360 	return 1;
1361       }
1362 
1363       fdc.wait += CLOCK_GAP0();
1364     }
1365 
1366   }
1367 
1368 
1369 	/* ID̵���ߤĤ��ä��Τǡ� ST0 �� NT ���åȤ������ */
1370 
1371   fdc.st0 = ST0_IC_NT | (fdc.hd<<2) | fdc.us;
1372   fdc.st1 = 0;
1373   fdc.st2 = 0;
1374 
1375   if( fdc.command == READ_ID ){		/* READ ID �ξ�� */
1376 
1377     fdc.c = sec_buf.c;				/* ���Ĥ�����������CHRN������*/
1378     fdc.h = sec_buf.h;
1379     fdc.r = sec_buf.r;
1380     fdc.n = sec_buf.n;
1381 
1382     fdc.wait += CLOCK_RID_ID();
1383     fdc.carry = CLOCK_RID_DATA( n );
1384 
1385     disk_next_sec( drv );
1386     if( drive[drv].sec==0 ) fdc.carry += CLOCK_GAP4(n) + CLOCK_GAP0();
1387 
1388   }else{				/* ����ʳ� �ξ�� */
1389 
1390     fdc.wait += CLOCK_RDT_ID();
1391     fdc.gap3  = CLOCK_GAP3( n );
1392 
1393     if( fdc.command == READ_DATA ||
1394 	fdc.command == READ_DELETED_DATA ){
1395       if( sec_buf.deleted == DISK_DELETED_TRUE ) fdc.st2 |= ST2_CM;
1396     }
1397   }
1398 
1399   return 1;
1400 }
1401 
1402 
1403 
1404 /*===========================================================================
1405  * READ�ϥ��ޥ�ɤǡ�DATA��Хåե����ɤ߹���
1406  *	��̤� ST0��ST2 �ȥХåե����åȤ����
1407  *	(READ ID �ξ�硢���δؿ��ϸƤФʤ�����)
1408  *===========================================================================*/
fdc_read_data(void)1409 static	int	fdc_read_data( void )
1410 {
1411   int	drv = (fdc.us);
1412   int	read_size, size, ptr, error;
1413 
1414 
1415   print_fdc_status(( (fdc.command==READ_DIAGNOSTIC) ? BP_DIAG : BP_READ ),
1416 		   drv, drive[drv].track, drive[drv].sec);
1417 
1418 	/* STATUS ������� (READ(DELETED)DATA�ξ��� DATA CRC���顼�Τ�) */
1419 
1420   if( sec_buf.status == STATUS_DE ){		/* ID CRC err */
1421     fdc.st0 = ST0_IC_AT | (fdc.hd<<2) | fdc.us;
1422     fdc.st1 = ST1_DE;
1423     fdc.st2 = ( (sec_buf.deleted==DISK_DELETED_TRUE)? ST2_CM: 0 );
1424   }
1425   else
1426   if( sec_buf.status == STATUS_DE_DD ){		/* DATA CRC err */
1427     fdc.st0 = ST0_IC_AT | (fdc.hd<<2) | fdc.us;
1428     fdc.st1 = ST1_DE;
1429     fdc.st2 = ST2_DD | ( (sec_buf.deleted==DISK_DELETED_TRUE)? ST2_CM: 0 );
1430   }
1431   else{						/* CRC OK */
1432     fdc.st0 = ST0_IC_NT | (fdc.hd<<2) | fdc.us;
1433     fdc.st1 = 0;
1434     fdc.st2 = ( (sec_buf.deleted==DISK_DELETED_TRUE)? ST2_CM: 0 );
1435   }
1436   if( ! idr_match() ){				/* IDR�԰��� */
1437     fdc.st0 |= ST0_IC_AT;
1438     fdc.st1 |= ST1_ND;
1439   }
1440 
1441 
1442 	/* DATA ��ʬ���ɤ� */
1443 
1444   read_size = 128 << (fdc.n & 7);		/* �ɤ߹��ߥ�����       */
1445   ptr       = 0;				/* �����߰���		*/
1446 
1447   if( fdc.command == READ_DIAGNOSTIC ){
1448     if((sec_buf.size==0x80 && read_size!=0x80) ||	/* �������� N��      */
1449        (sec_buf.size & 0xff00) != read_size    ){	/* IDR�� N���㤦���� */
1450       fdc.st0 |= ST0_IC_AT;				/* DATA CRC err      */
1451       fdc.st1 |= ST1_DE;
1452       fdc.st2 |= ST2_DD;
1453     }
1454   }
1455 
1456   while( read_size > 0 ){	/* -------------------���ꥵ����ʬ�ɤ�³���� */
1457 
1458     size = MIN( read_size, sec_buf.size );
1459     if( osd_fseek( drive[ drv ].fp,
1460 		   drive[ drv ].sec_pos + SZ_DISK_ID,  SEEK_SET )==0 ){
1461       if( osd_fread( &data_buf[ptr], sizeof(Uchar),
1462 		     size, drive[ drv ].fp )==(size_t)size ){
1463 	error = 0;
1464       }
1465       else error = 1;
1466     } else error = 2;
1467     if( error ){			/* OS��٥�Υ��顼ȯ�� */
1468       printf_system_error( error );		/* DATA CRC err �ˤ���*/
1469       status_message( 1, STATUS_WARN_TIME, "DiskI/O Read Error" );
1470       fdc.st0 |= ST0_IC_AT;
1471       fdc.st1 |= ST1_DE;
1472       fdc.st2 |= ST2_DD;
1473       break;
1474     }
1475 
1476     ptr       += size;
1477     read_size -= size;
1478     if( read_size <= 0 ) break;
1479 
1480 
1481     fdc.st0 |= ST0_IC_AT;		/* ���Υ������˸٤ä� */
1482     fdc.st1 |= ST1_DE;				/* DATA CRC err �ˤ��� */
1483     fdc.st2 |= ST2_DD;
1484 
1485 
1486 	/* �������֤����� (DATA-CRC,GAP3,ID-SYNC,IAM,ID,ID-CRC,GAP2�ʤ�) */
1487 
1488 #if 0		/* �������֤Υǡ��������ʤ� */
1489 		    /* CRC  GAP3  SYNC   AM    ID  CRC GAP2 */
1490     if( fdc.mf ) size = 2 + 0x36 + 12 + (3+1) + 4 + 2 + 22;
1491     else         size = 2 + 0x2a +  6 + (1+1) + 4 + 2 + 11;
1492 
1493     ptr       += size;
1494     read_size -= size;
1495 
1496     disk_next_sec( drv );
1497 
1498 #else		/* peach���ꡢ�������֥ǡ�������������������ޤ��� */
1499 
1500     size = fill_sector_gap(ptr, drv, fdc.mf);
1501     if (size < -1) goto FDC_READ_DATA_RETURN;
1502 
1503     ptr       += size;
1504     read_size -= size;
1505 #endif
1506   }				/* ----------------------------------------- */
1507 
1508 		/* �ɤ߹��߽���ä��顢���������ؿʤ�Ƥ��� */
1509 
1510   disk_next_sec( drv );
1511 
1512 
1513  FDC_READ_DATA_RETURN:
1514 
1515 	/* READ DIAGNOSTIC �ξ�硢CRC err �� IDR�԰��פ�����Ȥ��Ƥߤ�	*/
1516 	/* (ST1, ST2�ΥӥåȤϡ����Τޤ޻Ĥ�)				*/
1517 
1518   if( fdc.command == READ_DIAGNOSTIC ){
1519     fdc.st0 &= ~ST0_IC;		/* == ST0_IC_NT     */
1520   }
1521 
1522   return 1;
1523 }
1524 
1525 
1526 
1527 /*===========================================================================
1528  * WRITE�ϥ��ޥ�ɤǡ��Хåե���DATA��ե�����˽��Ф�
1529  *	��̤� ST0��ST2 �ȥХåե����åȤ����
1530  *
1531  *	�ʲ��Τ褦�ʥ��᡼�������ä���硢���Υ������˥ǡ�����饤�Ȥ�����
1532  *	        +----------+----------------+----------+----------------+
1533  *	        |C       00|                |C       00|                |
1534  *	        |H       00|                |H       00|                |
1535  *	        |R       01|    �ǡ�����    |R       01|    �ǡ�����    |
1536  *	        |N       02|    256�Х���   |N       01|    256�Х���   |
1537  *	        |��������16|                |��������16|                |
1538  *	        |������ 256|                |������ 256|                |
1539  *	        +----------+----------------+----------+----------------+
1540  *	N=2 �ʤΤǡ��饤�Ȥ���� 512 �Х��ȡ��Ĥޤ���Υ��������˲����롣
1541  *	        +----------+---------------------------------+----------+
1542  *	        |C       00|                                 |������    |
1543  *	        |H       00|                                 |��̣��̵��|
1544  *	        |R       01|            �ǡ�����             |���ߥǡ���|
1545  *	        |N       02|            512�Х���            |�Ȥʤ�    |
1546  *	        |��������16|                                 |          |
1547  *	        |������ 528|                                 | 16�Х��� |
1548  *	        +----------+---------------------------------+----------+
1549  *	�������ϡָ�Υ������Υ�����+16�Х��ȡ����䤹 (�����������Ѥ��ʤ�)��
1550  *===========================================================================*/
fdc_write_data(void)1551 static	int	fdc_write_data( void )
1552 {
1553   long	id_pos, write_pos;
1554   int	write_size, total_size, size, ptr, error=0, sys_err=0;
1555   int	drv = fdc.us;
1556   unsigned char	c[2];
1557   int	gap4_size  = sec_buf.size;
1558   int	gap4_wrote = FALSE;
1559 
1560   print_fdc_status(BP_WRITE, drv, drive[drv].track, drive[drv].sec);
1561 
1562 
1563 	/* �����κ���˥ǥ������������줿�ꤷ�����ϡ����������۾ェλ */
1564 
1565   if( disk_not_exist( drv ) ||				/* �ǥ�����̵�� */
1566       drive[ drv ].read_only ||				/* �����߶ػ� */
1567       drive[ drv ].protect == DISK_PROTECT_TRUE ||	/* �饤�ȥץ�ƥ��� */
1568       disk_unformat(drv) || disk_unformatable(drv) ){	/* ����ե����ޥå� */
1569 
1570     int write_protected = FALSE;	/* ����ԲĤ������ξ�硢�� */
1571     if( ! disk_not_exist( drv ) &&
1572 	( drive[ drv ].read_only ||
1573 	  drive[ drv ].protect == DISK_PROTECT_TRUE ) ){
1574       write_protected = TRUE;
1575     }
1576 
1577     fdc.st0 = ST0_IC_AT | (fdc.hd<<2) | fdc.us;
1578     fdc.st1 = 0;
1579     fdc.st2 = 0;
1580     if( write_protected ) fdc.st1 |= ST1_NW;
1581     else                  fdc.st0 |= ST0_NR;
1582 
1583 
1584     if( fdc_ignore_readonly &&		/* ReadOnly ��̵�뤹��������ェλ */
1585 	write_protected     &&
1586 	drive[ drv ].protect != DISK_PROTECT_TRUE ){
1587 
1588       fdc.st0 = ST0_IC_NT | (fdc.hd<<2) | fdc.us;
1589       fdc.st1 = 0;
1590       fdc.st2 = ( (fdc.command==WRITE_DELETED_DATA)? ST2_CM: 0 );
1591 
1592       if( verbose_fdc ){
1593 	printf("FDC %s : Drive %d Write Skipped (write protected)\n",
1594 	       cmd_name[fdc.command],drv+1);
1595       }
1596       status_message( 1, STATUS_WARN_TIME, "Disk Write Skipped" );
1597 
1598     }else{
1599 
1600       if( verbose_fdc ){
1601 	if( write_protected )
1602 	  printf("FDC %s : Drive %d Write Failed (write protected)\n",
1603 		 cmd_name[fdc.command],drv+1);
1604 	else
1605 	  printf("FDC %s : Drive %d Write Failed (file changed ?)\n",
1606 		 cmd_name[fdc.command],drv+1);
1607       }
1608       status_message( 1, STATUS_WARN_TIME, "Disk Write Failed" );
1609     }
1610     return 1;
1611   }
1612 
1613 
1614 	/* DATA ��ʬ��� */
1615 
1616   id_pos     = drive[ drv ].sec_pos;		/* ID�������Υե�������� */
1617 
1618   write_size = 128 << (fdc.n & 7);		/* �����ߥ�����         */
1619   ptr        = 0;				/* �ǡ����Υݥ���       */
1620   write_pos  = drive[drv].sec_pos + SZ_DISK_ID;	/* �����ߤΥե�������� */
1621   total_size = sec_buf.size;			/* �������Υǡ����������� */
1622 
1623   while( write_size > 0 ){	/* -------------------���ꥵ����ʬ��³���� */
1624 
1625     size = MIN( write_size, sec_buf.size );
1626     if( write_pos + size <= drive[drv].disk_end ){
1627     if( osd_fseek( drive[ drv ].fp,
1628 		   write_pos,  SEEK_SET )==0 ){
1629       if( osd_fwrite( &data_buf[ptr], sizeof(Uchar),
1630 		      size, drive[ drv ].fp )==(size_t)size ){
1631 	error = 0;
1632       }
1633       else error = 1;
1634     } else error = 2;
1635     } else error = 3;
1636     if( error ){
1637       printf_system_error( error );
1638       break;
1639     }
1640 
1641     ptr        += size;
1642     write_pos  += size;
1643     write_size -= size;
1644 
1645     if( write_size<=0 ) break;			/* ���̤ϡ�������ȴ����     */
1646 
1647     if( gap4_wrote == FALSE ){
1648       disk_next_sec( drv );			/* ���Υ������˸٤ä����   */
1649     }
1650 
1651     if( drive[drv].sec != 0 ){			/* ��³���륻����������С� */
1652 						/*	���Υ������˾��  */
1653       total_size += (sec_buf.size + SZ_DISK_ID);/*	(����ʬ����������)  */
1654 
1655     }else{ /* drive[drv].sec == 0 */		/* ̵��(��Ƭ����ä�)�ʤ�� */
1656       gap4_wrote = TRUE;			/*	GAP4 �˾��Ȥߤʤ� */
1657       total_size += (gap4_size + SZ_DISK_ID);	/*	(Ŭ���ˡ���������)  */
1658       /* ���Υȥ�å��Υǡ������˲����뤪���줢�ꡣ������*/
1659     }
1660 
1661     if( verbose_fdc ){
1662       if( gap4_wrote == FALSE )
1663 	printf("FDC %s : Sector Overlap in track %d (DRIVE %d:)\n",
1664 	       cmd_name[fdc.command], drive[drv].track, drv+1);
1665       else
1666 	printf("FDC %s : GAP4 Overlap in track %d (DRIVE %d:)\n",
1667 	       cmd_name[fdc.command], drive[drv].track, drv+1);
1668     }
1669 
1670   }				/* ----------------------------------------- */
1671 
1672 
1673 	/* ID ���������롣*/
1674 
1675   if( fdc.mf && fdc.n==0 ){
1676     c[0] = DISK_DELETED_FALSE;
1677     c[1] = STATUS_MA_MD;
1678   }else{
1679     if( fdc.command==WRITE_DATA ){
1680       c[0] = DISK_DELETED_FALSE;
1681       c[1] = (error) ? STATUS_DE_DD : STATUS_NORMAL;
1682     }else{
1683       c[0] = DISK_DELETED_TRUE;
1684       c[1] = (error) ? STATUS_DE_DD : STATUS_CM;
1685     }
1686   }
1687   if( error > 0 ) sys_err = 1;
1688   if( osd_fseek( drive[ drv ].fp,		/* ID �Ρ�DAM/DDAM���� */
1689 		 id_pos + DISK_DELETED,  SEEK_SET )==0 ){
1690     if( osd_fwrite( &c[0], sizeof(Uchar), 2, drive[ drv ].fp )==2 ){
1691       error = 0;
1692     }
1693     else error = 1;
1694   } else error = 2;
1695   if( error ){
1696     printf_system_error( error );
1697     sys_err = 1;
1698   }
1699 
1700 
1701   c[0] = ( total_size >>  0  ) & 0xff;
1702   c[1] = ( total_size >>  8  ) & 0xff;
1703   if( osd_fseek( drive[ drv ].fp,		/* ID �Ρ����������������� */
1704 		 id_pos + DISK_SEC_SZ,  SEEK_SET )==0 ){
1705     if( osd_fwrite( &c[0], sizeof(Uchar), 2, drive[ drv ].fp )==2 ){
1706       error = 0;
1707     }
1708     else error = 1;
1709   } else error = 2;
1710   if( error ){
1711     printf_system_error( error );
1712     sys_err = 1;
1713   }
1714 
1715 
1716   osd_fflush( drive[ drv ].fp );
1717 
1718 
1719 	/* ���桢�����ƥ�Υ��顼�������ä���۾ェλ���� */
1720 
1721   if( sys_err ){
1722     fdc.st0 = ST0_IC_AT | (fdc.hd<<2) | fdc.us | ST0_NR;
1723     fdc.st1 = 0;
1724     fdc.st2 = 0;
1725     status_message( 1, STATUS_WARN_TIME, "DiskI/O Write Error" );
1726   }else{
1727     fdc.st0 = ST0_IC_NT | (fdc.hd<<2) | fdc.us;
1728     fdc.st1 = 0;
1729     fdc.st2 = ( (fdc.command==WRITE_DELETED_DATA)? ST2_CM: 0 );
1730   }
1731 
1732   if( gap4_wrote == FALSE ){
1733     disk_next_sec( drv );
1734   }
1735   return 1;
1736 }
1737 
1738 
1739 
1740 /*===========================================================================
1741  * WRITE ID ���ޥ�ɤǡ��Хåե� �� IDR �˴�Ť��ե�����˽��Ф�
1742  *	��̤� ST0��ST2
1743  *===========================================================================*/
fdc_write_id(void)1744 static	int	fdc_write_id( void )
1745 {
1746   int	size, error, i, j, id_ptr;
1747   long	format_pos;
1748   char	id[SZ_DISK_ID],	data[128];
1749   int	drv = fdc.us;
1750 
1751 
1752 	/* �����κ���˥ǥ������������줿�ꤷ�����ϡ����������۾ェλ */
1753 
1754   if( disk_not_exist( drv ) ||				/* �ǥ�����̵�� */
1755       drive[ drv ].read_only ||				/* �����߶ػ� */
1756       drive[ drv ].protect == DISK_PROTECT_TRUE ||	/* �饤�ȥץ�ƥ��� */
1757       disk_unformatable(drv) ){				/* �ե����ޥå���ǽ */
1758 
1759     int write_protected = FALSE;	/* ����ԲĤ������ξ�硢�� */
1760     if( ! disk_not_exist( drv ) &&
1761 	( drive[ drv ].read_only ||
1762 	  drive[ drv ].protect == DISK_PROTECT_TRUE ) ){
1763       write_protected = TRUE;
1764     }
1765 
1766     fdc.st0 = ST0_IC_AT | (fdc.hd<<2) | fdc.us;
1767     fdc.st1 = 0;
1768     fdc.st2 = 0;
1769     if( write_protected ) fdc.st1 |= ST1_NW;
1770     else                  fdc.st0 |= ST0_NR;
1771 
1772 
1773     if( fdc_ignore_readonly &&		/* ReadOnly ��̵�뤹��������ェλ */
1774 	write_protected     &&
1775 	drive[ drv ].protect != DISK_PROTECT_TRUE ){
1776 
1777       fdc.st0 = ST0_IC_NT | (fdc.hd<<2) | fdc.us;
1778       fdc.st1 = 0;
1779       fdc.st2 = 0;
1780 
1781       if( verbose_fdc ){
1782 	printf("FDC %s : Drive %d Write Skipped (write protected)\n",
1783 	       cmd_name[fdc.command],drv+1);
1784       }
1785       status_message( 1, STATUS_WARN_TIME, "Disk Write Skipped" );
1786 
1787     }else{
1788 
1789       if( verbose_fdc ){
1790 	if( write_protected )
1791 	  printf("FDC %s : Drive %d Format Failed (write protected)\n",
1792 		 cmd_name[fdc.command],drv+1);
1793 	else if( ! disk_not_exist( drv ) && disk_unformatable(drv) )
1794 	  printf("FDC %s : Drive %d Format Failed (no file space)\n",
1795 		 cmd_name[fdc.command],drv+1);
1796 	else
1797 	  printf("FDC %s : Drive %d Format Failed (file changed ?)\n",
1798 		 cmd_name[fdc.command],drv+1);
1799       }
1800       status_message( 1, STATUS_WARN_TIME, "Disk Write Failed" );
1801     }
1802     return 1;
1803   }
1804 
1805 
1806 	/* �ե����ޥåȥǡ����ν��� */
1807 
1808   for( size=0; size<128; size++ ) data[size] = fdc.d;
1809 
1810 
1811 	/*        �ե����ޥåȥѥ�᡼���β���       */
1812 	/* �ȥ�å�1����ۤ��ʤ���Ƚ�ꡣ�ۤ������ϡ� */
1813 	/* �Ǹ��1���˼��ޤ�ʬ�Τߤ� WRITE ID ���롣 */
1814 
1815   id_ptr = 0;
1816   {
1817     int	SZ_BYTE = (drive[ drv ].type==DISK_TYPE_2HD) ? 10400 : 6250;
1818     int	SZ_GAP0 = (fdc.mf) ? (80+12+3+1    +50) : (40+6+1+1+    50);
1819     int	SZ_AM   = (fdc.mf) ? (   12+3+1+4+2+22) : (   6+1+1+4+2+11);
1820     int	SZ_DAM  = (fdc.mf) ? (   12+3+1+0+2+ 0) : (   6+1+1+0+2+ 0);
1821     int	max_sec;
1822     SZ_GAP0 = 0; /* �Ȥꤢ������GAP0 ��ʬ�ϱۤ��Ƥ�پ�ʥ� */
1823     max_sec = (SZ_BYTE-SZ_GAP0)/( SZ_AM+SZ_DAM + 128*(1<<(fdc.n&7))+ fdc.gpl );
1824     if( fdc.sc > max_sec ){
1825 
1826       if( verbose_fdc )
1827         printf("FDC %s : Over Sector %d -> fixed %d (DRIVE %d:)\n",
1828 	       cmd_name[fdc.command],fdc.sc,max_sec,drv+1);
1829 
1830       id_ptr = (fdc.sc - max_sec) * 4;
1831       fdc.sc = max_sec;
1832 
1833     }
1834   }
1835 
1836 
1837 
1838 	/* ID / DATA ��ե�����˽����� */
1839 
1840   format_pos = drive[ drv ].track_top;
1841   error = 0;
1842 
1843   if( fdc.sc==0 ){				/* ����ե����ޥåȤ���� */
1844 
1845     for( i=0; i<SZ_DISK_ID; i++ ) id[ i ] = 0;
1846 
1847     if( format_pos + 16 <= drive[drv].disk_end ){
1848     if( osd_fseek( drive[ drv ].fp,  format_pos,  SEEK_SET )==0 ){
1849       if( osd_fwrite( id, sizeof(Uchar), 16, drive[ drv ].fp )==16 ){
1850 	error = 0;
1851       }
1852       else error = 1;
1853     } else error = 2;
1854     } else error = 3;
1855 
1856   }else for( i=0; i<fdc.sc; i++ ){		/* �ե����ޥåȤ���� */
1857 
1858     id[ DISK_C ] = data_buf[ id_ptr++ ];
1859     id[ DISK_H ] = data_buf[ id_ptr++ ];
1860     id[ DISK_R ] = data_buf[ id_ptr++ ];
1861     id[ DISK_N ] = data_buf[ id_ptr++ ];
1862     id[ DISK_SEC_NR   ] = (fdc.sc    ) & 0xff;
1863     id[ DISK_SEC_NR+1 ] = (fdc.sc>>8 ) & 0xff;
1864     id[ DISK_DENSITY ] = (fdc.mf) ? DISK_DENSITY_DOUBLE : DISK_DENSITY_SINGLE;
1865     id[ DISK_DELETED ] = DISK_DELETED_FALSE;
1866     id[ DISK_STATUS ] = STATUS_NORMAL;
1867     id[ DISK_RESERVED+0 ] = 0;
1868     id[ DISK_RESERVED+1 ] = 0;
1869     id[ DISK_RESERVED+2 ] = 0;
1870     id[ DISK_RESERVED+3 ] = 0;
1871     id[ DISK_RESERVED+4 ] = 0;
1872     id[ DISK_SEC_SZ   ] = ( 128*(1<<(fdc.n&7))      ) & 0xff;
1873     id[ DISK_SEC_SZ+1 ] = ( 128*(1<<(fdc.n&7)) >> 8 ) & 0xff;
1874 
1875     if( verbose_fdc )
1876       if( id[ DISK_N ] != fdc.n )
1877         printf("FDC %s : Mix Sector in track %d (DRIVE %d:)\n",
1878 	       cmd_name[fdc.command],drive[drv].track,drv+1);
1879 
1880     if( format_pos + 16 <= drive[drv].disk_end ){
1881     if( osd_fseek( drive[ drv ].fp,  format_pos,  SEEK_SET )==0 ){
1882       if( osd_fwrite( id, sizeof(Uchar), 16, drive[ drv ].fp )==16 ){
1883 	format_pos += 16;
1884 
1885 	for( j=0; j<(1<<(fdc.n&7)); j++ ){
1886 
1887 	  if( format_pos + 128 <= drive[drv].disk_end ){
1888 	  if( osd_fseek( drive[ drv ].fp,  format_pos,  SEEK_SET )==0 ){
1889 	    if( osd_fwrite( data, sizeof(Uchar), 128, drive[ drv ].fp )==128 ){
1890 	      format_pos += 128;
1891 	    }
1892 	    else{ error = 1; break; }
1893 	  } else{ error = 2; break; }
1894 	  } else{ error = 3; break; }
1895 
1896 	}
1897 
1898       }
1899       else error = 1;
1900     } else error = 2;
1901     } else error = 3;
1902 
1903   }
1904 
1905   if( error ){					/* SEEK / READ Error */
1906     printf_system_error( error );
1907   }
1908 
1909   osd_fflush( drive[ drv ].fp );
1910 
1911 
1912 	/* ���桢�����ƥ�Υ��顼�������ä���۾ェλ���� */
1913 
1914   if( error ){
1915     fdc.st0 = ST0_IC_AT | (fdc.hd<<2) | fdc.us | ST0_NR;
1916     fdc.st1 = 0;
1917     fdc.st2 = 0;
1918     status_message( 1, STATUS_WARN_TIME, "DiskI/O Write Error" );
1919   }else{
1920     fdc.st0 = ST0_IC_NT | (fdc.hd<<2) | fdc.us;
1921     fdc.st1 = 0;
1922     fdc.st2 = 0;
1923   }
1924 
1925   disk_now_track( drv,   drive[drv].track );
1926   return 1;
1927 }
1928 
1929 
1930 
1931 /*===========================================================================
1932  * E-PHASE ���ェλ���ˡ����� CHRN ��ؤ�
1933  *	with_TC ���� (TC�ˤ�����ェλ) �ξ�硢�ǽ��������ʤ� �� CHRN ��ؤ�
1934  *	with_TC ����                    �ξ�硢�ǽ��������Ǥ� �� CHRN �Τޤ�
1935  *	�ʤ����ǽ���������ã�����鿿���֤�
1936  *
1937  *	2DD/2HD �Ǥ�Ʊ�������Ǥ����������������(�������ʤ� ;_;)
1938  *===========================================================================*/
fdc_next_chrn(int with_TC)1939 static	int	fdc_next_chrn( int with_TC )
1940 {
1941   if( fdc.mt==0 ){		/* �ޥ���ȥ�å��������ʤ��� */
1942 
1943     if( fdc.r == fdc.eot ){		/* �ǽ��������ʤ顢	*/
1944       if( with_TC ){
1945 	fdc.c ++;			/* C+=1, R=1 �ˤ��롣	*/
1946 	fdc.r = 1;			/* 			*/
1947       }
1948       return 1;				/* �֤��ͤ� �� (�ǽ�)	*/
1949     }else{
1950       fdc.r ++;				/* �ǽ��Ǥʤ���С�R+=1	*/
1951       return 0;				/* �֤��ͤ� �� (��³)	*/
1952     }
1953 
1954   }else{			/* �ޥ���ȥ�å������λ� */
1955 
1956     if( fdc.hd==0 ){		/*   ɽ�̽����� */
1957 
1958       if( fdc.r == fdc.eot ){		/* �ǽ��������ʤ顢	*/
1959 	fdc.hd = 1;			/* ΢�̤����ؤ��ơ�	*/
1960 	fdc.h ^= 1;			/* H ȿž��R = 1	*/
1961 	fdc.r  = 1;			/* �֤��ͤ� �� (��³)	*/
1962 	return 0;
1963       }else{
1964 	fdc.r ++;			/* �ǽ��Ǥʤ���С�R+=1	*/
1965 	return 0;			/* �֤��ͤ� �� (��³)	*/
1966       }
1967 
1968     }else{			/*   ΢�̽����� */
1969 
1970       if( fdc.r == fdc.eot ){		/* �ǽ��������ʤ顢	*/
1971 	if( with_TC ){
1972 	  fdc.h ^= 1;			/* H ȿž��		*/
1973 	  fdc.c ++;			/* C+=1, R=1 �ˤ��롣	*/
1974 	  fdc.r = 1;			/* 			*/
1975 	}
1976 	return 1;			/* �֤��ͤ� �� (�ǽ�)	*/
1977       }else{
1978 	fdc.r ++;			/* �ǽ��Ǥʤ���С�R+=1	*/
1979 	return 0;			/* �֤��ͤ� �� (��³)	*/
1980       }
1981     }
1982   }
1983 }
1984 
1985 
1986 
1987 /*===========================================================================
1988  * ���ޥ�ɥե���������
1989  *	�ۥ���(����CPU)�ȤΥǡ����Τ����� 4clock ����˽�����
1990  *	��������� (�Ĥޤꡢ�ǡ����Τ����˥������Ȥ�̵��)
1991  *===========================================================================*/
c_phase(void)1992 static	void	c_phase( void )
1993 {
1994   int cmd, nd, i;
1995   unsigned char * const table[][10] =
1996   {
1997 /*WAIT */{ 0 },
1998 /*R_DAT*/{ &fdc.c0,&fdc.c1, &fdc.c,&fdc.h,&fdc.r,&fdc.n, &fdc.eot,&fdc.gpl,&fdc.dtl,0},
1999 /*R_DEL*/{ &fdc.c0,&fdc.c1, &fdc.c,&fdc.h,&fdc.r,&fdc.n, &fdc.eot,&fdc.gpl,&fdc.dtl,0},
2000 /*R_DIA*/{ &fdc.c0,&fdc.c1, &fdc.c,&fdc.h,&fdc.r,&fdc.n, &fdc.eot,&fdc.gpl,&fdc.dtl,0},
2001 /*R_ID */{ &fdc.c0,&fdc.c1, 0 },
2002 /*W_DAT*/{ &fdc.c0,&fdc.c1, &fdc.c,&fdc.h,&fdc.r,&fdc.n, &fdc.eot,&fdc.gpl,&fdc.dtl,0},
2003 /*W_DEL*/{ &fdc.c0,&fdc.c1, &fdc.c,&fdc.h,&fdc.r,&fdc.n, &fdc.eot,&fdc.gpl,&fdc.dtl,0},
2004 /*W_ID */{ &fdc.c0,&fdc.c1, &fdc.n, &fdc.sc, &fdc.gpl, &fdc.d, 0 },
2005 /*S_EQU*/{ &fdc.c0,&fdc.c1, &fdc.c,&fdc.h,&fdc.r,&fdc.n, &fdc.eot,&fdc.gpl,&fdc.stp,0},
2006 /*S_LOW*/{ &fdc.c0,&fdc.c1, &fdc.c,&fdc.h,&fdc.r,&fdc.n, &fdc.eot,&fdc.gpl,&fdc.stp,0},
2007 /*S_HIG*/{ &fdc.c0,&fdc.c1, &fdc.c,&fdc.h,&fdc.r,&fdc.n, &fdc.eot,&fdc.gpl,&fdc.stp,0},
2008 /*SEEK */{ &fdc.c0,&fdc.c1, &fdc.cn, 0 },
2009 /*RECAL*/{ &fdc.c0,&fdc.c1, 0 },
2010 /*SNS_I*/{ &fdc.c0,         0 },
2011 /*SNS_D*/{ &fdc.c0,&fdc.c1, 0 },
2012 /*SPECI*/{ &fdc.c0,         &fdc.s0, &fdc.s1, 0 },
2013 /*INVAL*/{ &fdc.c0,         0 },
2014   };
2015 
2016   /* �֥ۥ��Ȥ��ǡ��������FDC��������ΡפΥ������Ȥ�ɬ�פʤ顢 */
2017   /* �����ǻ��ַв���Ԥġ�(�ԤäƤ���֤Ͻ��������˴ؿ�������)  */
2018   ;
2019 
2020 
2021   if( fdc.status & REQ_MASTER ){	/* �ۥ��Ȥ���Υǡ���̵�� */
2022 
2023     ICOUNT( -1 );
2024 
2025   }else{				/* �ۥ��Ȥ���ǡ������褿 */
2026 
2027     *table[ fdc.command ][ fdc.step ] = fdc.write;		/*�ǡ�������*/
2028     fdc.step ++;
2029 
2030     if( table[ fdc.command ][ fdc.step ] ){	/* �ޤ��ǡ�����ɬ�פʻ� */
2031 
2032       fdc.status = (fdc.status&0x0f) | FDC_BUSY | REQ_MASTER;
2033       ICOUNT( -1 );
2034 
2035     }else{					/* ���ǡ���������괰λ */
2036 
2037       if( FDC_flag ){					/* ���ȯ����ʤ��  */
2038 	for( i=0; i<MAX_DRIVE; i++ ){			/* ��������λ����    */
2039 	  if( fdc.seek_stat[i]==SEEK_STAT_INTR ){	/* �ɥ饤�� (�����  */
2040 	    fdc.seek_stat[i] = SEEK_STAT_STOP;		/* ȯ����) ����    */
2041 	    fdc.status &= ~(1<<i);
2042 	    break;
2043 	  }
2044 	}
2045 	fdc.intr_unit = i;				/* ���Υɥ饤�֤�    */
2046 	fdc_cancel_interrupt();				/* SENSE INT ������  */
2047 
2048 	if( verbose_fdc )
2049 	  if( fdc.command != SENSE_INT_STATUS )
2050 	    printf("FDC log : Missing SENSE INT STATUS $$$$\n" );
2051       }
2052 
2053 
2054       cmd     = (fdc.c0 & 0x1f);
2055       fdc.sk  = (fdc.c0 & 0x20) >> 5;
2056       fdc.mf  = (fdc.c0 & 0x40) >> 6;
2057       fdc.mt  = (fdc.c0 & 0x80) >> 7;
2058 
2059       fdc.us  = (fdc.c1 & 0x03);			/* SENSE INT��INVALID*/
2060       fdc.hd  = (fdc.c1 & 0x04) >> 2;			/* �Ǥ����פʤ������*/
2061 
2062 
2063       switch( fdc.command ){				/* ���ޥ���̤ν���  */
2064 
2065       case READ_DIAGNOSTIC:					/* READ�� */
2066 	if( verbose_fdc ){
2067 	  printf("FDC %s : Drive %d Track %d\n",
2068 		 cmd_name[fdc.command],fdc.us+1,fdc.ncn[fdc.us]*2+fdc.hd);
2069 	}
2070 	fdc.sk = 0;
2071 	fdc.mt = 0;	/* FALLTHROUGH */
2072       case READ_DATA:
2073       case READ_DELETED_DATA:
2074       case READ_ID:
2075 	fdc.status = (fdc.status&0x0f) | FDC_BUSY | DATA_IO;
2076 	fdc.phase  = E_PHASE;
2077 
2078 	if( fdc.command==READ_ID ){
2079 	  if( verbose_fdc ){
2080 	    printf("FDC %s : Drive %d Track %d\n",
2081 		   cmd_name[fdc.command],fdc.us+1,fdc.ncn[fdc.us]*2+fdc.hd);
2082 	  }
2083 	  logfdc("%s mf%d us%d hd%d\n",
2084 		 cmd_name[fdc.command],
2085 		 fdc.mf,fdc.us,fdc.hd);
2086 	}else{
2087 	  logfdc("%s sk%d mf%d mt%d us%d hd%d eot=%d gpl=%d dtl=%d\n",
2088 		 cmd_name[fdc.command],
2089 		 fdc.sk,fdc.mf,fdc.mt,fdc.us,fdc.hd,fdc.eot,fdc.gpl,fdc.dtl);
2090 	}
2091 	break;
2092 
2093       case WRITE_DATA:						/* WRITE�� */
2094       case WRITE_DELETED_DATA:
2095 	fdc.sk = 0;	/* FALLTHROUGH */
2096       case WRITE_ID:
2097 	fdc.status = (fdc.status&0x0f) | FDC_BUSY;
2098 	fdc.phase  = E_PHASE;
2099 
2100 	if( fdc.command==WRITE_ID ){
2101 	  logfdc("%s mf%d us%d hd%d n%d sc%d gpl%d d%02x\n",
2102 		 cmd_name[fdc.command],
2103 		 fdc.mf,fdc.us,fdc.hd,fdc.n,fdc.sc,fdc.gpl,fdc.d);
2104 	}else{
2105 	  logfdc("%s sk%d mf%d mt%d us%d hd%d eot=%d gpl=%d dtl=%d\n",
2106 		 cmd_name[fdc.command],
2107 		 fdc.sk,fdc.mf,fdc.mt,fdc.us,fdc.hd,fdc.eot,fdc.gpl,fdc.dtl);
2108 	}
2109 	break;
2110 
2111       case SEEK:						/* SEEK�� */
2112       case RECALIBRATE:
2113 	fdc.ncn[ fdc.us ] = (fdc.command==SEEK) ? fdc.cn : 0 ;
2114 	fdc.status = (fdc.status&0x0f) | FDC_BUSY;
2115 	fdc.phase  = E_PHASE;
2116 
2117 	logfdc("%s us%d %02x (Tr.%02d,%02d=>%02d,%02d)\n",
2118 	       cmd_name[fdc.command],
2119 	       fdc.us,fdc.ncn[fdc.us],fdc.pcn[fdc.us]*2,fdc.pcn[fdc.us]*2+1,
2120 				      fdc.ncn[fdc.us]*2,fdc.ncn[fdc.us]*2+1);
2121 	break;
2122 
2123       case SENSE_INT_STATUS:					/* SENSE�� */
2124       case SENSE_DEVICE_STATUS:
2125       case INVALID:
2126 	fdc.status  = (fdc.status&0x0f) | FDC_BUSY | DATA_IO;
2127 	fdc.phase   = R_PHASE;
2128 
2129 	if( fdc.command==SENSE_DEVICE_STATUS ){
2130 	  logfdc("%s us%d hd%d\n",   cmd_name[fdc.command], fdc.us, fdc.hd );
2131 	}else{
2132 	  logfdc("%s \n",            cmd_name[fdc.command] );
2133 	}
2134 	break;
2135 
2136       case SPECIFY:						/* SPECIFY�� */
2137 	fdc.srt_clk = (16-((fdc.s0>>4)&0x0f)) *  (2*4000);  /* (16-srt)x 2ms */
2138 	fdc.hut_clk =      (fdc.s0    &0x0f)  * (32*4000);  /*     hut x32ms */
2139 	fdc.hlt_clk =     ((fdc.s1>>1)&0x7f)  *  (4*4000);  /*     hlt x 4ms */
2140 	nd          =       fdc.s1    &   1;
2141 	if( fdc.hut_clk==0 ) fdc.hut_clk = 16 * (32*4000);		/* ? */
2142 
2143 	logfdc("%s srt%dms hut%dms hlt%dms (%02X %02X)\n",
2144 	       cmd_name[fdc.command],
2145 	     fdc.srt_clk/4000,fdc.hut_clk/4000,fdc.hlt_clk/4000,fdc.s0,fdc.s1);
2146 
2147 	fdc.status  = (fdc.status&0x0f) | REQ_MASTER;
2148 	fdc.command = WAIT;
2149 	break;
2150 
2151       default:							/* ¾��NG */
2152 	fprintf( stderr, "FDC unsupported %02x(%s)\n",
2153 		 cmd, cmd_name[ fdc.command ] );
2154 	ICOUNT( -1 );
2155 	return;
2156       }
2157 
2158       fdc.step = 0;
2159       ICOUNT( 0 );
2160       REPEAT();
2161     }
2162   }
2163 }
2164 
2165 
2166 
2167 /*===========================================================================
2168  * �ꥶ��ȥե���������
2169  *	�ۥ���(����CPU)�ȤΥǡ����Τ����� 4clock ����˽�����
2170  *	��������� (�Ĥޤꡢ�ǡ����Τ����˥������Ȥ�̵��)
2171  *===========================================================================*/
r_phase(void)2172 static	void	r_phase( void )
2173 {
2174   int i;
2175   unsigned char * const table[][8] =
2176   {
2177 /*WAIT */{ 0 },
2178 /*R_DAT*/{ &fdc.st0, &fdc.st1, &fdc.st2, &fdc.c, &fdc.h, &fdc.r, &fdc.n, 0 },
2179 /*R_DEL*/{ &fdc.st0, &fdc.st1, &fdc.st2, &fdc.c, &fdc.h, &fdc.r, &fdc.n, 0 },
2180 /*R_DIA*/{ &fdc.st0, &fdc.st1, &fdc.st2, &fdc.c, &fdc.h, &fdc.r, &fdc.n, 0 },
2181 /*R_ID */{ &fdc.st0, &fdc.st1, &fdc.st2, &fdc.c, &fdc.h, &fdc.r, &fdc.n, 0 },
2182 /*W_DAT*/{ &fdc.st0, &fdc.st1, &fdc.st2, &fdc.c, &fdc.h, &fdc.r, &fdc.n, 0 },
2183 /*W_DEL*/{ &fdc.st0, &fdc.st1, &fdc.st2, &fdc.c, &fdc.h, &fdc.r, &fdc.n, 0 },
2184 /*W_ID */{ &fdc.st0, &fdc.st1, &fdc.st2, &fdc.c, &fdc.h, &fdc.r, &fdc.n, 0 },
2185 /*S_EQU*/{ &fdc.st0, &fdc.st1, &fdc.st2, &fdc.c, &fdc.h, &fdc.r, &fdc.n, 0 },
2186 /*S_LOW*/{ &fdc.st0, &fdc.st1, &fdc.st2, &fdc.c, &fdc.h, &fdc.r, &fdc.n, 0 },
2187 /*S_HIG*/{ &fdc.st0, &fdc.st1, &fdc.st2, &fdc.c, &fdc.h, &fdc.r, &fdc.n, 0 },
2188 /*SEEK */{ 0 },
2189 /*RECAL*/{ 0 },
2190 /*SNS_I*/{ &fdc.r0, &fdc.r1, 0 },
2191 /*SNS_D*/{ &fdc.st3, 0 },
2192 /*SPECI*/{ 0 },
2193 /*INVAL*/{ &fdc.r0, 0 },
2194   };
2195 
2196 	/* R-PHASE �ΰ��ֺǽ�ˡ����Τ���ǡ����ΰ������������� */
2197 
2198   if( fdc.step == 0 ){
2199 
2200     fdc.status &= ~REQ_MASTER;		/* ������ */
2201 /*  ICOUNT( 0 );*/
2202 
2203     switch( fdc.command ){		/* ���ޥ���̤ν���  */
2204 
2205     case SENSE_INT_STATUS:			/* SENSE INT STATUS          */
2206       i = fdc.intr_unit;				/* ��������(���ȯ��)*/
2207       fdc.intr_unit = 4;
2208       if( i < MAX_DRIVE ){				/* �Υɥ饤�֤���    */
2209 	if( i<NR_DRIVE ) fdc.r0 = ST0_IC_NT | ST0_SE | i;
2210 	else             fdc.r0 = ST0_IC_AT | ST0_SE | ST0_NR | i;
2211 	fdc.r1 = fdc.pcn[ i ];
2212 	logfdc("\t\t\t\t\t\t<st0:%02x pcn:%02x>\n",
2213 	       fdc.r0,fdc.r1);
2214       }else{						/* ���Ĥ���ʤ�����  */
2215 	fdc.command = INVALID;				/* INVALID�����Ȥ��� */
2216 	fdc.r0 = ST0_IC_IC;
2217 	logfdc("\t\t\t\t\t\tinvalid\n");
2218       }
2219       break;
2220 
2221     case SENSE_DEVICE_STATUS:			/* SENSE DEVICE STATUS    */
2222       if( fdc.us >= NR_DRIVE ){			/* ST3 ����������         */
2223 	fdc.st3 = ST3_FT | ((fdc.hd<<2) & ST3_HD) | ( fdc.us & ST3_US );
2224       }else{
2225 	if( disk_not_exist( fdc.us ) ||
2226 	    (disk_ex_drv & (1 << fdc.us)) ){ /* �ǥ����������ؤ������å� */
2227 							    /* thanks peach! */
2228 	  disk_ex_drv ^= (1 << fdc.us); /* �ɥ饤���ֹ�Υӥå�ȿž */
2229 	  fdc.st3 =((fdc.status & (1<<fdc.us)) ? 0 : ST3_RY ) |
2230 			((fdc.pcn[fdc.us]==0) ? ST3_T0 : 0 ) |
2231 			((fdc.hd<<2) & ST3_HD) | ( fdc.us & ST3_US );
2232 	}else{
2233 	  fdc.st3 =((fdc.status & (1<<fdc.us)) ? 0 : ST3_RY ) |
2234 	      		((drive[fdc.us].protect==DISK_PROTECT_TRUE)?ST3_WP:0) |
2235 			((fdc.pcn[fdc.us]==0) ? ST3_T0 : 0 ) | ST3_TS |
2236 			((fdc.hd<<2) & ST3_HD) | ( fdc.us & ST3_US );
2237 	}
2238       }
2239       logfdc("\t\t\t\t\t\t<st3:%02x>\n",
2240 	     fdc.st3);
2241       break;
2242 
2243     case INVALID:				/* INVALID                */
2244       fdc.r0 = ST0_IC_IC;			/* ST0 ����������         */
2245       logfdc("\t\t\t\t\t\t<st0:%02x>\n",
2246 	     fdc.r0);
2247       break;
2248 
2249     default:					/* ����ʳ���             */
2250       fdc_occur_interrupt();			/* ������ȯ��������     */
2251       logfdc("\t\t\t\t\t\t<ST:%02x %02x %02x  CHRN:%02x %02x %02x %02x>\n",
2252 	     fdc.st0,fdc.st1,fdc.st2,fdc.c,fdc.h,fdc.r,fdc.n);
2253       break;
2254     }
2255   }
2256 
2257 
2258 
2259   if( fdc.status & REQ_MASTER ){	/* �ۥ��Ȥޤ��ǡ����ɤޤ� */
2260 
2261     /* �������ˤ�ꡢ fdc.step == 0 �λ��Ϥ����ˤϤ��ʤ� */
2262     ICOUNT( -1 );
2263 
2264   }else{				/* �ۥ��Ȥ��ǡ������ɤ�� */
2265 
2266     /* �֥ۥ��Ȥ��ǡ����ɹ���FDC��������ΡפΥ������Ȥ�ɬ�פʤ顢 */
2267     /* �����ǻ��ַв���Ԥġ�(�ԤäƤ���֤Ͻ��������˴ؿ�������)  */
2268     ;
2269 
2270     if( table[ fdc.command ][ fdc.step ] ){		/* �ޤ��ǡ������� */
2271 
2272       if( fdc.step != 0 ) fdc_cancel_interrupt();
2273 
2274       fdc.status = (fdc.status&0x0f) | FDC_BUSY | DATA_IO | REQ_MASTER;
2275       fdc.read   = *table[ fdc.command ][ fdc.step ];
2276       fdc.step ++;
2277       ICOUNT( -1 );
2278 
2279     }else{						/* �⤦�ǡ����ʤ� */
2280 
2281       fdc.read = 0xff;
2282       fdc.status = (fdc.status&0x0f) | REQ_MASTER;
2283       fdc.command = WAIT;
2284       fdc.step = 0;
2285       ICOUNT( -1 );
2286     }
2287   }
2288 }
2289 
2290 
2291 
2292 /*===========================================================================
2293  * ���������塼�����ե���������
2294  *===========================================================================*/
2295 
2296 /*---------------------------------------------------------------------------
2297  *	SEEK��
2298  *---------------------------------------------------------------------------*/
e_phase_seek(void)2299 static	void	e_phase_seek( void )
2300 {
2301 
2302   fdc.status = (fdc.status&0x0f) | REQ_MASTER | (1<<fdc.us);
2303 
2304   if( fdc.us >= NR_DRIVE ||				/* ̤��³�ɥ饤�� or */
2305       fdc.pcn[ fdc.us ] == fdc.ncn[ fdc.us ] ){		/* ���������פξ��  */
2306 
2307     if( sec_buf.drv != fdc.us ) sec_buf.drv = -1;
2308 
2309     fdc.seek_stat[ fdc.us ] = SEEK_STAT_END;
2310     fdc.seek_wait[ fdc.us ] = 0;
2311     ICOUNT( 0 );
2312     REPEAT();
2313 
2314   }else{		/* ư����Υɥ饤�֤���٥�����������ɤ����褦 ? */
2315 
2316     sec_buf.drv = -1;
2317 
2318 #ifdef	WAIT_FOR_SEEK
2319     if( fdc_wait == FALSE ){
2320 #endif
2321       fdc.pcn[ fdc.us ] = fdc.ncn[ fdc.us ];
2322       fdc.seek_stat[ fdc.us ] = SEEK_STAT_END;
2323       fdc.seek_wait[ fdc.us ] = 0;
2324       ICOUNT( 0 );
2325       REPEAT();
2326 
2327 #ifdef	WAIT_FOR_SEEK
2328     }else{
2329       /* �������� ? */
2330       if ((cpu_timing > 0) && (fdc_wait)) {
2331 	fdc_sound_counter = 0;
2332 	/*logfdc("### Seek ###\n");*/
2333 	xmame_dev_sample_seek();
2334       }
2335       fdc.seek_stat[ fdc.us ] = SEEK_STAT_MOVE;
2336       if( fdc.pcn[ fdc.us ] < fdc.ncn[ fdc.us ] ) fdc.pcn[ fdc.us ] ++;
2337       else                                        fdc.pcn[ fdc.us ] --;
2338       fdc.seek_wait[ fdc.us ] = fdc.srt_clk;
2339       ICOUNT( -1 );
2340       REPEAT();
2341     }
2342 #endif
2343   }
2344 
2345   fdc.command = WAIT;
2346   fdc.step = 0;
2347 }
2348 
2349 
2350 
2351 /*---------------------------------------------------------------------------
2352  *	READ��
2353  *---------------------------------------------------------------------------*/
2354 
2355 /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2356  * ����ID���������ߤĤ��ä���Хåե����ɤ߹���
2357  * ����� -1:��λ(E-PHASE��)  0:���Τޤ�  1:����
2358  *- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -	*/
e_phase_read_search(void)2359 static	int	e_phase_read_search( void )
2360 {
2361   int search, ret, skip_this;
2362 
2363   if( fdc.command != READ_ID ){
2364     logfdc("\t\t\tC:%02X H:%02X R:%02X N:%02X  ",fdc.c,fdc.h,fdc.r,fdc.n);
2365   }
2366 
2367 
2368   fdc.ddam_not_skipped = 0;
2369 
2370 
2371   search = fdc_search_id();		/* ID��������			*/
2372 /*printf("<%d><%d>",fdc.wait,fdc.carry);*/
2373   if( search == FALSE ){		/* ������ǽ (�ǥ�����̤����)	*/
2374 
2375     ret = 0;						/* ���٤���ʤ���  */
2376 
2377   }else{				/* ������ǽ (�ǥ���������)	*/
2378 
2379     if( fdc.command == READ_ID ){	    /* READ ID �ξ��		     */
2380 
2381       ret = -1;
2382 
2383     }else if( fdc.st0 & ST0_IC ){	    /* ������������ ID�����Ĥ���ʤ� */
2384 
2385       logfdc("-Miss\n");
2386       ret = -1;
2387 
2388     }else{				    /* ���������� ID�����Ĥ��ä�     */
2389 
2390       if( ( fdc.command==READ_DATA &&		/* (D)DAM ���פ��ʤ��ʤ�    */
2391 	    ( fdc.st2 & ST2_CM )   )          ||
2392 	  ( fdc.command==READ_DELETED_DATA &&
2393 	    !( fdc.st2 & ST2_CM )          )  ){
2394 							/* �����åץ����å� */
2395 	if( fdc.sk ){ skip_this = TRUE;  }
2396 	else        { skip_this = FALSE; fdc.ddam_not_skipped = TRUE; }
2397 
2398       }else{					/* (D)DAM �����פ����ʤ�    */
2399 						/* (READ DIAGNOSTIC �λ���) */
2400 	skip_this = FALSE;				/* �����åפϤ��ʤ� */
2401       }
2402 
2403       if( skip_this ){				/* �����������åפ����� */
2404 	if( fdc_next_chrn(FALSE)==0 ){			/* ���������˿ʤ�   */
2405 	  logfdc("Skip\n");
2406 	  ret = 0;
2407 	}else{						/* ���� EOT ���ä�  */
2408 	  fdc.st0 |= ST0_IC_AT;
2409 	  fdc.st1 |= ST1_EN;
2410 	  logfdc("Skip-EOT\n");
2411 	  ret = -1;
2412 	}
2413       }else{					/* �����åפ������ɤ���    */
2414 	fdc_read_data();
2415 	fdc.data_ptr = 0;
2416 	if( fdc.n==0 ) fdc.counter = (128>fdc.dtl) ? 128 : fdc.dtl;
2417 	else           fdc.counter = 128 << (fdc.n & 7);
2418 	ret = 1;
2419       }
2420     }
2421     REPEAT();
2422   }
2423   return ret;
2424 }
2425 
2426 
2427 
2428 /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2429  * �Хåե�����1�Х��ȤȤ�������ۥ��Ȥ�ž�� (������ȯ��)
2430  * ����� -1:��λ(��������λ������)  1:����
2431  *- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -	*/
e_phase_read_send(void)2432 static	int	e_phase_read_send( void )
2433 {
2434   int ret;
2435 
2436   if( fdc.TC && fdc.data_ptr ){		/* TC���椢�� (1��ʾ塢���ȯ����) */
2437 
2438     fdc.limit = 0;
2439     ICOUNT( (fdc.counter + 2) * CLOCK_BYTE() );
2440     REPEAT();
2441     ret = -1;
2442 
2443   }else{				/* TC����̵���ʤ顢���ȯ�� */
2444     fdc_occur_interrupt();
2445     fdc.status = (fdc.status&0x0f) | FDC_BUSY | NON_DMA | DATA_IO | REQ_MASTER;
2446     fdc.read   = data_buf[ fdc.data_ptr ++ ];
2447     fdc.limit  = CLOCK_BYTE();
2448     ICOUNT( -1 );
2449     ret = 1;
2450   }
2451 
2452   return ret;
2453 }
2454 
2455 
2456 
2457 /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2458  * �ۥ��Ȥΰ�������ǧ (�����ߥ��ꥢ)
2459  * ����� -1:��λ(��������λ������) 0:���Τޤ�  1:����(ž��or��������λ����)
2460  *- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -	*/
e_phase_read_recv(int interval)2461 static	int	e_phase_read_recv( int interval )
2462 {
2463   int ret;
2464 
2465   fdc.limit -= interval;
2466   if( fdc.limit < 0 ){			/* ������ַв�ǥ����С���� */
2467     /* fdc.st1 |= ST1_OR; */
2468     fdc.limit = 0;
2469     if( verbose_fdc )
2470       if( fdc_wait ) printf("FDC %s : Over Run\n", cmd_name[fdc.command] );
2471   }
2472 
2473   if( fdc.TC ){				/* TC���椢��ξ�� */
2474 
2475     fdc_cancel_interrupt();
2476     fdc.limit = 0;
2477     ICOUNT( (fdc.counter + 2) * CLOCK_BYTE() );
2478     REPEAT();
2479     ret = -1;
2480 
2481   }else{				/* �ǡ������ɤߤ����줿��� */
2482 
2483     if( !( fdc.status & REQ_MASTER ) ){
2484       fdc_cancel_interrupt();
2485       -- fdc.counter;
2486       ICOUNT( fdc.limit );
2487       REPEAT();
2488       if( fdc.counter==0 ){ fdc.limit = 2 * CLOCK_BYTE(); }
2489       else                { fdc.limit = 0;                }
2490       ret = 1;
2491 
2492     }else{				/* �ޤ����ɤޤ�Ƥ��ʤ���� */
2493       ICOUNT( -1 );
2494       ret = 0;
2495     }
2496   }
2497   return ret;
2498 }
2499 
2500 
2501 
2502 /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2503  * 1�������ν�λ(��ž����λ�ʤ���TC����)��CRC���顼��TC���ǧ����
2504  * ����� -1:��λ(E-PHASE��) 0:���Τޤ�  1:����(�ޥ��������)
2505  *- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -	*/
e_phase_read_end(int interval)2506 static	int	e_phase_read_end( int interval )
2507 {
2508   int ret;
2509 
2510   fdc.limit -= interval;
2511   if( fdc.limit < 0 ){
2512     fdc.limit = 0;
2513   }
2514 
2515   if( fdc.command != READ_DIAGNOSTIC &&
2516       fdc.st0 & ST0_IC ){		/* ID/DATA CRC���顼����ξ��	*/
2517 
2518     logfdc("-CRC\n");
2519     ICOUNT( fdc.limit );
2520     REPEAT();
2521     fdc.limit = 0;
2522     ret = -1;							/* E-PHASE�� */
2523 
2524   }else{				/* CRC��������ä����	*/
2525 
2526     if( fdc.TC ){			    /* TC���椬���ä���� */
2527 
2528       if( fdc.ddam_not_skipped ){		/* (D)DAM�԰��פʤΤ˥����å�*/
2529 	logfdc("TC(Noskip)\n");			/* �����ʤ顢���Υ������Τޤ�*/
2530 
2531       }else{					/* ����ʳ� (��READ DIAG)�ʤ�*/
2532 	fdc_next_chrn(TRUE);			/* ����������ؤ�            */
2533 	logfdc("TC\n");
2534       }
2535       ICOUNT( fdc.limit );
2536       REPEAT();
2537       fdc.limit = 0;
2538       ret = -1;							/* E-PHASE�� */
2539 
2540     }else{				    /* TC���椬�ʤ���� */
2541 
2542       if( fdc.limit <= 0 ){		    /* 2�Х��ȥ�����в� */
2543 
2544 	if( fdc.ddam_not_skipped ){		/* (D)DAM�԰��פʤΤ˥����å�*/
2545 	  fdc.st0 |= ST0_IC_AT;			/* �����ʤ顢�۾ェλ        */
2546 	  fdc.st1 |= ST1_EN;
2547 	  logfdc("MT-Noskip\n");
2548 	  ret = -1;						/* E-PHASE�� */
2549 
2550 	}else{					/* ����ʳ� (��READ DIAG)�ʤ�*/
2551 
2552 	  if( fdc_next_chrn(FALSE)==0 ){		/* ���������˿ʤ�   */
2553 	    logfdc("MT\n");
2554 	    ret = 1;
2555 	  }else{					/* ���� EOT ���ä�  */
2556 	    fdc.st0 |= ST0_IC_AT;
2557 	    fdc.st1 |= ST1_EN;
2558 	    logfdc("MT-EOT\n");
2559 	    ret = -1;
2560 	  }
2561 	}
2562 	ICOUNT( 0 );
2563 	REPEAT();
2564 
2565       }else{				    /* 2�Х��ȥ�����в���Ԥ� */
2566 	ICOUNT( 10 );					/* Ŭ���ʾ����ʻ��� */
2567 	ret = 0;
2568       }
2569     }
2570   }
2571 
2572   if( ret != 0 ){
2573     fdc.carry = fdc.gap3;
2574 /*  printf("<%d><%d>",fdc.wait,fdc.carry);*/
2575   }
2576   return ret;
2577 }
2578 
2579 
2580 /*---------------------------------------------------------------------------
2581  *	READ/WRITE����
2582  *---------------------------------------------------------------------------*/
2583 
e_phase_finish(void)2584 static	void	e_phase_finish( void )
2585 {
2586   fdc.TC = FALSE;
2587   fdc.status = (fdc.status&0x0f) | FDC_BUSY | DATA_IO;
2588   fdc.phase  = R_PHASE;
2589   fdc.step   = 0;
2590   ICOUNT( 0 );
2591   REPEAT();
2592 }
2593 
2594 
2595 /*---------------------------------------------------------------------------
2596  *	WRITE��
2597  *---------------------------------------------------------------------------*/
2598 
2599 /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2600  * �����߲�ǽ�������å�
2601  * ����� -1:��λ(E-PHASE��)  0:���Τޤ�  1:����
2602  *- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -	*/
e_phase_writeid_search(void)2603 static	int	e_phase_writeid_search( void )
2604 {
2605   int search, ret;
2606 
2607   search = fdc_check_unit();		/* ���Ƚ�ꤹ��			*/
2608 
2609   if( search == FALSE ){		/* Ƚ����ǽ (�ǥ�����̤����)	*/
2610 
2611     ret = 0;						/* ���٤���ʤ���  */
2612 
2613   }else{				/* Ƚ����			*/
2614 
2615     if( fdc.st0 & ST0_IC ){		    /* ��������ǽ */
2616 
2617       logfdc("-WrPro\n");
2618       ret = -1;
2619 
2620     }else{				    /* �����߲�ǽ */
2621       fdc.data_ptr = 0;
2622       if( fdc.sc==0 ){
2623 	fdc.counter = 256 * 4;
2624 	if( verbose_fdc )
2625 	  printf("FDC %s : no sector\n",cmd_name[fdc.command]);
2626       }else{
2627 	fdc.counter = fdc.sc * 4;
2628       }
2629       ret = 1;
2630     }
2631     REPEAT();
2632   }
2633   return ret;
2634 }
2635 
2636 
2637 
2638 /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2639  * ������ID��������
2640  * ����� -1:��λ(E-PHASE��)  0:���Τޤ�  1:����
2641  *- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -	*/
e_phase_write_search(void)2642 static	int	e_phase_write_search( void )
2643 {
2644   int search, ret;
2645 
2646   logfdc("\t\t\tC:%02X H:%02X R:%02X N:%02X  ",fdc.c,fdc.h,fdc.r,fdc.n);
2647 
2648 
2649   search = fdc_search_id();		/* ID��������			*/
2650 
2651   if( search == FALSE ){		/* ������ǽ (�ǥ�����̤����)	*/
2652 
2653     ret = 0;						/* ���٤���ʤ���  */
2654 
2655   }else{				/* ������ǽ (�ǥ���������)	*/
2656 
2657     if( fdc.st0 & ST0_IC ){	    	    /* ������������ �۾�ȯ��         */
2658 
2659       if( fdc.st1 & ST1_NW ){			/* ��������ǽ     */
2660 	logfdc("-WrPro\n");
2661       }else{					/* ID�����Ĥ���ʤ� */
2662 	logfdc("-Miss\n");
2663       }
2664       ret = -1;
2665 
2666     }else{				    /* �������ơ�̵��ID���Ĥ���    */
2667       fdc.data_ptr = 0;
2668       if( fdc.n==0 ) fdc.counter = (128>fdc.dtl) ? 128 : fdc.dtl;
2669       else           fdc.counter = 128 << (fdc.n & 7);
2670       ret = 1;
2671     }
2672     REPEAT();
2673   }
2674   return ret;
2675 }
2676 
2677 
2678 
2679 /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2680  * �ۥ��Ȥ�ž�����׵� (������ȯ��)
2681  * ����� -1:��λ(��������λ������)  1:����
2682  *- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -	*/
e_phase_write_request(void)2683 static	int	e_phase_write_request( void )
2684 {
2685   int ret;
2686 
2687   if( fdc.TC && fdc.data_ptr ){		/* TC���椢�� (1��ʾ塢���ȯ����) */
2688 
2689     fdc.limit = 0;
2690     if( fdc.command == WRITE_ID ) ICOUNT( 0 ); /* �׻������ݤʤΤ� 0 */
2691     else                          ICOUNT( (fdc.counter + 2) * CLOCK_BYTE() );
2692     REPEAT();
2693     ret = -1;
2694 
2695   }else{				/* TC����̵���ʤ顢���ȯ�� */
2696     fdc_occur_interrupt();
2697     fdc.status = (fdc.status&0x0f) | FDC_BUSY | NON_DMA | REQ_MASTER;
2698     fdc.limit  = CLOCK_BYTE();
2699     ICOUNT( -1 );
2700     ret = 1;
2701   }
2702   return ret;
2703 }
2704 
2705 
2706 
2707 /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2708  * �ۥ��Ȥ���1�Х��Ȱ�����ꡢ�Хåե�������� (�����ߥ��ꥢ)
2709  * ����� -1:��λ(��������λ������) 0:���Τޤ�  1:����(ž��or��������λ����)
2710  *- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -	*/
e_phase_write_respond(int interval)2711 static	int	e_phase_write_respond( int interval )
2712 {
2713   int ret;
2714 
2715   fdc.limit -= interval;
2716 
2717   if( fdc.limit<0 ){			/* ������ַв�ǥ����С���� */
2718     /* fdc.st1 |= ST1_OR; */
2719     fdc.limit = 0;
2720     if( verbose_fdc )
2721       if( fdc_wait ) printf("FDC %s : Over Run\n", cmd_name[fdc.command] );
2722   }
2723 
2724   if( fdc.TC ){				/* TC���椢��ξ�� */
2725 
2726     fdc_cancel_interrupt();
2727     fdc.limit = 0;
2728     if( fdc.command == WRITE_ID ) ICOUNT( 0 ); /* �׻������ݤʤΤ� 0 */
2729     else                          ICOUNT( (fdc.counter + 2) * CLOCK_BYTE() );
2730     REPEAT();
2731     ret = -1;
2732 
2733   }else{				/* �ǡ����������ޤ줿��� */
2734 
2735     if( !( fdc.status & REQ_MASTER ) ){
2736       fdc_cancel_interrupt();
2737       data_buf[ fdc.data_ptr ++ ] = fdc.write;
2738       -- fdc.counter;
2739 
2740       if( fdc.command == WRITE_ID ){
2741 	logfdc("%02X %s",fdc.write,((fdc.counter%4)==0)?"\n":"");
2742 
2743 	ICOUNT( fdc.limit + ( ((fdc.counter%4)==0)? CLOCK_SECTOR(fdc.n) :0 ) );
2744 	REPEAT();
2745 	if( fdc.counter==0 ){ fdc.limit = CLOCK_GAP4(fdc.n); }
2746 	else                { fdc.limit = 0; }
2747       }else{
2748 	ICOUNT( fdc.limit );
2749 	REPEAT();
2750 	if( fdc.counter==0 ){ fdc.limit = 2 * CLOCK_BYTE(); }
2751 	else                { fdc.limit = 0;                }
2752       }
2753       ret = 1;
2754 
2755     }else{				/* �ޤ�������Ƥ��ʤ���� */
2756       ICOUNT( -1 );
2757       ret = 0;
2758     }
2759   }
2760   return ret;
2761 }
2762 
2763 
2764 
2765 /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2766  * 1�ȥ�å�ʬ�����᡼���ե�����˽��Ф�
2767  * ����� 1:��λ(��������λ������)
2768  *- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -	*/
e_phase_writeid_track(void)2769 static	int	e_phase_writeid_track( void )
2770 {
2771   int ret;
2772 
2773   fdc.TC = FALSE;			/* TC���椬����оä� */
2774   if( fdc.counter!=0 ){
2775     if( verbose_fdc ) printf("FDC %s : CHRN missing\n",cmd_name[fdc.command]);
2776 
2777     while( (fdc.counter%4)!=0 ){		/* 4�Х��Ȥ������ʤ� */
2778       data_buf[ fdc.data_ptr ++ ] = 0x00;	/* ��ʬ��00H������ */
2779       -- fdc.counter;
2780     }
2781     fdc.sc = (4*fdc.sc - fdc.counter) /4;	/* ���θ� SC ���� */
2782   }
2783 
2784   fdc_write_id();			/* �饤�Ȥ���			*/
2785   {
2786     ICOUNT( fdc.limit );
2787     REPEAT();
2788     fdc.limit = 0;
2789     fdc.carry = 0;
2790     ret = 1;
2791   }
2792   return ret;
2793 }
2794 
2795 
2796 
2797 /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2798  * 1������ʬ�����᡼���ե�����˽��Ф�
2799  * ����� 1:��λ(��������λ������)
2800  *- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -	*/
e_phase_write_sector(void)2801 static	int	e_phase_write_sector( void )
2802 {
2803   int i, ret;
2804 
2805   while( fdc.counter ){			/* �������������������ʤ����	*/
2806     data_buf[ fdc.data_ptr ++ ] = 0x00;	/*	00H������		*/
2807     -- fdc.counter;
2808   }
2809   if( fdc.n==0 && fdc.dtl<128 ){
2810     for( i=0; i<128-fdc.dtl; i++ ){
2811       data_buf[ fdc.data_ptr ++ ] = 0x00;
2812     }
2813   }
2814 
2815   fdc_write_data();			/* �饤�Ȥ���			*/
2816   {
2817     ICOUNT( 0 );
2818     REPEAT();
2819     ret = 1;
2820   }
2821   return ret;
2822 }
2823 
2824 
2825 
2826 /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2827  * 1�������ν�λ(�����ߺ�)��TC���ǧ���� (���顼�Ϥ��ꤨ�ʤ�)
2828  * ����� -1:��λ(E-PHASE��) 0:���Τޤ�  1:����(�ޥ��������)
2829  *- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -	*/
e_phase_write_end(int interval)2830 static	int	e_phase_write_end( int interval )
2831 {
2832   int ret;
2833 
2834   fdc.limit -= interval;
2835   if( fdc.limit < 0 ){
2836     fdc.limit = 0;
2837   }
2838 
2839   if( fdc.TC ){				    /* TC���椬���ä����       */
2840 
2841     fdc_next_chrn(TRUE);			    /* ����������ؤ�   */
2842     logfdc("TC\n");
2843     ICOUNT( fdc.limit + CLOCK_BYTE() );
2844     REPEAT();
2845     fdc.limit = 0;
2846     ret = -1;							/* E-PHASE�� */
2847 
2848   }else{				    /* TC���椬�ʤ����         */
2849 
2850     if( fdc.limit <= 0 ){			/* 2�Х��ȥ�����в�    */
2851 
2852       if( fdc_next_chrn(FALSE)==0 ){		    /* ���������˿ʤ�   */
2853 	logfdc("MT\n");
2854 	ret = 1;
2855       }else{					    /* ���� EOT ���ä�  */
2856 	fdc.st0 |= ST0_IC_AT;
2857 	fdc.st1 |= ST1_EN;
2858 	logfdc("MT-EOT\n");
2859 	ret = -1;
2860       }
2861       ICOUNT( 0 );
2862       REPEAT();
2863 
2864     }else{					/* 2�Х��ȥ�����в��Ԥ�*/
2865       ICOUNT( 10 );				    /* Ŭ���ʾ����ʻ��� */
2866       ret = 0;
2867     }
2868   }
2869 
2870   if( ret != 0 ){
2871     fdc.carry = fdc.gap3;
2872   }
2873   return ret;
2874 }
2875 
2876 
2877 
2878 
2879 
2880 
2881 
2882 /************************************************************************/
2883 /* FDC �� �����ᥤ��							*/
2884 /*	������ ����ˤ��δؿ���Ƥ��������ηв����( 4MHz���ơ��Ȥ� )	*/
2885 /************************************************************************/
2886 
fdc_ctrl(int interval)2887 int	fdc_ctrl( int interval )
2888 {
2889   int	i, w, rest;
2890 
2891 
2892   if( fdc.wait < 0 ){			/* ̵���Ԥ����ä���� */
2893     rest = 0;
2894     fdc.wait = 0;
2895     fdc.carry -= interval;
2896     if( fdc.carry < 0 ) fdc.carry = 0;
2897   }else{				/* ͭ���Ԥ����ä���� */
2898     if( fdc.wait >= interval ){			/* �������ȸ��� */
2899       rest = 0;
2900       fdc.wait -= interval;
2901     }else{
2902       rest = interval - fdc.wait;		/* ���ޤ�ʬ�� rest �˥��å� */
2903       fdc.wait = 0;
2904     }
2905   }
2906 
2907   /********************************** ������ư�� *****************************/
2908 
2909   for( i=0; i<NR_DRIVE; i++ ){				/* �ɥ饤�� 0��1�Τ� */
2910     if( fdc.seek_stat[i] == SEEK_STAT_MOVE ){		/*  ��������ʤ���� */
2911       fdc.seek_wait[i] -= interval;
2912       if( fdc.seek_wait[i] <= 0 ){
2913 	if( fdc.ncn[i] == fdc.pcn[i] ){				/* �������� */
2914 	  fdc.seek_stat[i] = SEEK_STAT_END;
2915 	  fdc.seek_wait[i] = 0;
2916 	}else{							/* �ޤ��ޤ� */
2917 	  /* �������� ? */
2918 	  if ((cpu_timing > 0) && (fdc_wait)) {
2919 	    fdc_sound_counter ++;
2920 	    if (fdc_sound_counter >= fdc_sound_skipper) {
2921 	      fdc_sound_counter = 0;
2922 	      /*logfdc("### Seek ###\n");*/
2923 	      xmame_dev_sample_seek();
2924 	    }
2925 	  }
2926 	  if( fdc.pcn[i] < fdc.ncn[i] ) fdc.pcn[i] ++;
2927 	  else                          fdc.pcn[i] --;
2928 	  fdc.seek_wait[i] = fdc.srt_clk;
2929 	}
2930       }
2931     }
2932   }
2933 
2934   /*************************** �إåɥ������ư�� **************************/
2935 #ifdef	WAIT_FOR_HEADLOAD
2936   if( fdc.command == WAIT ||			/* �꡼��/�饤�Ȱʳ�         */
2937       fdc.command >= SEEK ){
2938     for( i=0; i<MAX_DRIVE; i++ ){
2939       if( fdc.hl_stat[i] ){				/* �إåɥ�����ʤ�*/
2940 	fdc.hl_wait[i] += interval;				/* ���֤�û�*/
2941 	if( fdc.hl_wait[i] >= fdc.hut_clk ){
2942 	  fdc.hl_stat[i] = FALSE;
2943 	  /* ������ɲ� ? */
2944 	  if ((cpu_timing > 0) && (fdc_wait)) {
2945 	    /*logfdc("### Head Up ###\n");*/
2946 	    xmame_dev_sample_headup();
2947 	  }
2948 	}
2949       }
2950     }
2951   }
2952 #endif
2953 
2954   /******* FDC �������������Ȥʤ��ʤ�(���˼����)������̵�¤˷����֤� ******/
2955 
2956   do {
2957 
2958     if( fdc.command == WAIT ){	/*========================== ���ޥ���Ԥ� ===*/
2959 
2960       if( ( fdc.status & REQ_MASTER )==0 ){	/* ���ޥ�ɼ����������	*/
2961 	switch( fdc.write & 0x1f ){
2962 	case 0x06:	fdc.command = READ_DATA;		break;
2963 	case 0x0c:	fdc.command = READ_DELETED_DATA;	break;
2964 	case 0x0a:	fdc.command = READ_ID;			break;
2965 	case 0x0d:	fdc.command = WRITE_ID;			break;
2966 	case 0x05:	fdc.command = WRITE_DATA;		break;
2967 	case 0x09:	fdc.command = WRITE_DELETED_DATA;	break;
2968 	case 0x02:	fdc.command = READ_DIAGNOSTIC;		break;
2969 	case 0x11:	fdc.command = SCAN_EQUAL;		break;
2970 	case 0x19:	fdc.command = SCAN_LOW_OR_EQUAL;	break;
2971 	case 0x1d:	fdc.command = SCAN_HIGH_OR_EQUAL;	break;
2972 	case 0x0f:	fdc.command = SEEK;			break;
2973 	case 0x07:	fdc.command = RECALIBRATE;		break;
2974 	case 0x08:	fdc.command = SENSE_INT_STATUS;		break;
2975 	case 0x04:	fdc.command = SENSE_DEVICE_STATUS;	break;
2976 	case 0x03:	fdc.command = SPECIFY;			break;
2977 	default:	fdc.command = INVALID;			break;
2978 	}
2979 	fdc.phase = C_PHASE;
2980 	fdc.step  = 0;
2981 	fdc.TC    = FALSE;
2982 	ICOUNT( 0 );					/* ���������֤� */
2983 
2984       }else {					/* ���ޥ�ɤʤ����	*/
2985 
2986 	for( i=0; i<MAX_DRIVE; i++ ){			/* ��������λȽ�� */
2987 	  if( fdc.seek_stat[i] == SEEK_STAT_END ){
2988 	    fdc_occur_interrupt();
2989 	    fdc.seek_stat[i] = SEEK_STAT_INTR;
2990 	    fdc.seek_wait[i] = 0;
2991 	    if( i<NR_DRIVE && disk_not_exist(i)==FALSE &&
2992 		sec_buf.drv == -1 ){
2993 	      disk_now_track( i, fdc.ncn[ i ]*2 + fdc.hd );
2994 	      fdc.carry = 0;
2995 	    }
2996 	    break;
2997 	  }
2998 	}
2999 	ICOUNT( -1 );
3000       }
3001       break;
3002 
3003     }else{			/*========================== ���ޥ�ɽ��� ===*/
3004 
3005       if( fdc.wait ) break;
3006 
3007       switch( fdc.phase ){
3008       case C_PHASE:		    /* = = = = = = = C-PHASE = = = = = = = = */
3009 	c_phase();
3010 	break;
3011 
3012       case E_PHASE:		    /* = = = = = = = E-PHASE = = = = = = = = */
3013 	switch( fdc.command ){
3014 
3015 	case READ_DATA:			/* ---------------------- READ DATA -*/
3016 	case READ_DELETED_DATA:		/* -------------- READ DELETED DATA -*/
3017 	case READ_DIAGNOSTIC:		/* ---------------- READ DIAGNOSTIC -*/
3018 	case READ_ID:			/* ------------------------ READ ID -*/
3019 	  switch( fdc.step ){
3020 	  case 0:				/* ID���������᡼���꡼�� - -*/
3021 	    switch( e_phase_read_search() ){
3022 	    case -1:	fdc.step = 4;	break;		/* ���顼ȯ��   */
3023 	    case  1:	fdc.step = 1;	break;		/* �꡼�ɽ����� */
3024 	    default:			break;		/* �Ԥ�         */
3025 	    }	/* READ ID �� case 1: �Ϥ��ꤨ�ʤ� */
3026 	    break;
3027 
3028 	  case 1:				/* 1�Х�������  - - - - - - -*/
3029 	    switch( e_phase_read_send() ){
3030 	    case -1:	fdc.step = 3;	break;		/* TC ����    */
3031 	    case  1:	fdc.step = 2;	break;		/* ž�������� */
3032 	    default:			break;		/* �Ԥ�       */
3033 	    }
3034 	    break;
3035 
3036 	  case 2:				/* �ۥ��Ȱ�����Ԥ� - - - - -*/
3037 	    switch( e_phase_read_recv( interval ) ){
3038 	    case -1:	fdc.step = 3;	break;		/* TC ����    */
3039 	    case  1:
3040 	      if( fdc.counter==0 ) fdc.step = 3;	/* TC �Ԥ���  */
3041 	      else                 fdc.step = 1;	/* ����ž���� */
3042 	      break;
3043 	    default:			break;		/* �Ԥ�       */
3044 	    }
3045 	    break;
3046 
3047 	  case 3:				/* 1��������λ  - - - - - - -*/
3048 	    switch( e_phase_read_end( interval ) ){
3049 	    case -1:	fdc.step = 4;	break;		/* ��λ       */
3050 	    case  1:	fdc.step = 0;	break;		/* ���������� */
3051 	    default:			break;		/* �Ԥ�       */
3052 	    }
3053 	    break;
3054 
3055 	  case 4:				/* E-PHASE��λ  - - - - - - -*/
3056 	    e_phase_finish();
3057 	    break;
3058 	  }
3059 	  break;
3060 
3061 
3062 	case WRITE_ID:			/* ----------------------- WRITE ID -*/
3063 	  switch( fdc.step ){
3064 	  case 0:				/* �����ǧ - - - - - - - - -*/
3065 	    switch( e_phase_writeid_search() ){
3066 	    case -1:	fdc.step = 4;	break;		/* ���顼ȯ��   */
3067 	    case  1:	fdc.step = 1;	break;		/* �饤�Ƚ����� */
3068 	    default:			break;		/* �Ԥ�         */
3069 	    }
3070 	    break;
3071 
3072 	  case 1:				/* �ۥ��Ȥ��׵� - - - - - - -*/
3073 	    switch( e_phase_write_request() ){
3074 	    case -1:	fdc.step = 3;	break;		/* TC ����    */
3075 	    case  1:	fdc.step = 2;	break;		/* ž�������� */
3076 	    default:			break;		/* �Ԥ�       */
3077 	    }
3078 	    break;
3079 
3080 	  case 2:				/* 1�Х��ȼ���  - - - - - - -*/
3081 	    switch( e_phase_write_respond( interval ) ){
3082 	    case -1:	fdc.step = 3;	break;		/* TC ����    */
3083 	    case  1:
3084 	      if( fdc.counter==0 ) fdc.step = 3;	/* �����ߤ� */
3085 	      else                 fdc.step = 1;	/* ����ž���� */
3086 	      break;
3087 	    default:			break;		/* �Ԥ�       */
3088 	    }
3089 	    break;
3090 
3091 	  case 3:				/* ���᡼�������� - - - - -*/
3092 	    e_phase_writeid_track();
3093 	    fdc.step = 4;	/* FALLTHROUGH */
3094 	  case 4:				/* E-PHASE��λ  - - - - - - -*/
3095 	    e_phase_finish();
3096 	    break;
3097 	  }
3098 	  break;
3099 
3100 
3101 	case WRITE_DATA:		/* --------------------- WRITE DATA -*/
3102 	case WRITE_DELETED_DATA:	/* ------------- WRITE DELETED DATA -*/
3103 	  switch( fdc.step ){
3104 	  case 0:				/* ID���� - - - - - - - - - -*/
3105 	    switch( e_phase_write_search() ){
3106 	    case -1:	fdc.step = 5;	break;		/* ���顼ȯ��   */
3107 	    case  1:	fdc.step = 1;	break;		/* �饤�Ƚ����� */
3108 	    default:			break;		/* �Ԥ�         */
3109 	    }
3110 	    break;
3111 
3112 	  case 1:				/* �ۥ��Ȥ��׵� - - - - - - -*/
3113 	    switch( e_phase_write_request() ){
3114 	    case -1:	fdc.step = 3;	break;		/* TC ����    */
3115 	    case  1:	fdc.step = 2;	break;		/* ž�������� */
3116 	    default:			break;		/* �Ԥ�       */
3117 	    }
3118 	    break;
3119 
3120 	  case 2:				/* 1�Х��ȼ���  - - - - - - -*/
3121 	    switch( e_phase_write_respond( interval ) ){
3122 	    case -1:	fdc.step = 3;	break;		/* TC ����    */
3123 	    case  1:
3124 	      if( fdc.counter==0 ) fdc.step = 3;	/* TC �Ԥ���  */
3125 	      else                 fdc.step = 1;	/* ����ž���� */
3126 	      break;
3127 	    default:			break;		/* �Ԥ�       */
3128 	    }
3129 	    break;
3130 
3131 	  case 3:				/* ���᡼�������� - - - - -*/
3132 	    e_phase_write_sector();
3133 	    fdc.step = 4;	/* FALLTHROUGH */
3134 	  case 4:				/* 1��������λ  - - - - - - -*/
3135 	    switch( e_phase_write_end( interval ) ){
3136 	    case -1:	fdc.step = 5;	break;		/* ��λ       */
3137 	    case  1:	fdc.step = 0;	break;		/* ���������� */
3138 	    default:			break;		/* �Ԥ�       */
3139 	    }
3140 	    break;
3141 
3142 	  case 5:				/* E-PHASE��λ  - - - - - - -*/
3143 	    e_phase_finish();
3144 	    break;
3145 	  }
3146 	  break;
3147 
3148 
3149 	case SEEK:			/* --------------------------- SEEK -*/
3150 	case RECALIBRATE:		/* -------------------- RECALIBRATE -*/
3151 	  e_phase_seek();
3152 	  break;
3153 
3154 
3155 	case SENSE_INT_STATUS:		/* --------------- SENSE_INT_STATUS -*/
3156 	case SENSE_DEVICE_STATUS:	/* ------------ SENSE_DEVICE_STATUS -*/
3157 	case SPECIFY:			/* ------------------------ SPECIFY -*/
3158 	case INVALID:			/* ------------------------ Invalid -*/
3159 	  /* E-PHASE��̵�� */
3160 	  break;
3161 
3162 
3163 	default:			/* ----------------------------------*/
3164 	  /* ̤�б����ޥ�ɡġġ� */
3165 	  break;
3166 	}
3167 	break;
3168 
3169 
3170       case R_PHASE:		    /* = = = = = = = R-PHASE = = = = = = = = */
3171 	r_phase();
3172 	break;
3173       }
3174     }
3175 
3176 
3177     if( rest > 0 ){			/* �������ȸ����κݤΤ��ޤ�ʬ����� */
3178       if( fdc.wait < 0 ){
3179 	fdc.carry -= rest;
3180 	if( fdc.carry < 0 ) fdc.carry = 0;
3181       }else{
3182 	fdc.wait -= rest;
3183 	if( fdc.wait < 0 ) fdc.wait = 0;
3184       }
3185       rest   = 0;
3186     }
3187     interval = 0;
3188 
3189   } while( fdc.wait==0 );
3190 
3191 
3192   /************ ���� FDC�����ޤǤ��Ԥ����֤��� (-1��̵�¤��Ԥ�) ************/
3193   w = -1;
3194 
3195   if( fdc.command == WAIT ){		/* �Ե���Τߡ���������λ���֤��ǧ */
3196     for( i=0; i<MAX_DRIVE; i++ ){
3197       if( fdc.seek_stat[i] == SEEK_STAT_MOVE &&
3198 	  fdc.seek_wait[i] >  0 ){
3199 	if( w == -1 ) w = fdc.seek_wait[i];
3200 	else if( w > fdc.seek_wait[i] ) w = fdc.seek_wait[i];
3201       }
3202     }
3203   }
3204   /* w �ϥ�������λ�ޤǤκ�û����å��� �ޤ��� -1 �����åȤ���Ƥ��� */
3205 
3206   if( fdc_wait == FALSE ||		/* �������Ȥʤ� �ޤ���          */
3207       fdc.wait < 0 ){			/* �������Ȥ����̵���Ԥ��ξ�� */
3208 
3209     ;/* w (��������λ�ʤ���̵��) �ޤ��Ԥ� */
3210 
3211   }else{				/* �Ԥ����֤�����Ѥߤξ��     */
3212     if( w < 0 ) w = fdc.wait;
3213     else        w = MIN( w, fdc.wait );
3214   }
3215 
3216   return w;
3217 }
3218 
3219 
3220 
3221 /************************************************************************/
3222 /* �ɥ饤�֤ξ��֤��֤��ؿ�						*/
3223 /************************************************************************/
get_drive_ready(int drv)3224 int	get_drive_ready( int drv )
3225 {
3226   if( fdc.command==WAIT ) return 1;
3227   else{
3228     if( fdc.us==drv ) return 0;
3229     else              return 1;
3230   }
3231 }
3232 
3233 
3234 
3235 /************************************************************************/
3236 /* �������֤�����                                                     */
3237 /************************************************************************/
3238 /*
3239  * READ DIAG �Υ������֤Υǡ�������������ϡ�peach��ˤ��������ޤ�����
3240  */
3241 #define IF_WITHIN_DATA_BUF_SIZE(s)	\
3242 if (s >= DATA_BUF_SIZE) {		\
3243     printf("FDC : Buffer over flow\n");	\
3244     fflush(stdout);			\
3245     return(-1);				\
3246 } else
3247 
3248 #define RET_GAP_ERR(cond) if (cond != TRUE) return(-1);
3249 
3250 /*
3251  * GAP3 �η׻�
3252  */
3253 INLINE
calc_gap3_size(int n,Uchar fdc_mf)3254 int calc_gap3_size(int n, Uchar fdc_mf)
3255 {
3256     int gap3_size;
3257 
3258     /* GAP3 �Υ������Ϸ�ޤäƤ���櫓�ǤϤʤ��ΤǤ����ޤ�ɸ��Ū���� */
3259     switch (n) {
3260     case 1:	gap3_size = 27;	break;
3261     case 2:	gap3_size = 42;	break;
3262     case 3:	gap3_size = 58;	break;
3263     default:	gap3_size = 58; /* ����¾��ʬ����� */
3264     }
3265     if (fdc_mf) gap3_size *= 2;	/* ��̩�� */
3266     return(gap3_size);
3267 }
3268 
3269 INLINE
input_safely_data(int ptr,int * ad,int data,int size)3270 int input_safely_data(int ptr, int *ad, int data, int size)
3271 {
3272     if (size == 0) return(TRUE);
3273 
3274     if (ptr + *ad + size < DATA_BUF_SIZE) {
3275 	memset(&data_buf[ptr + *ad], data, size);
3276 	*ad += size;
3277 	return(TRUE);
3278     } else {
3279 	printf("FDC : Buffer overflow\n");
3280 	fflush(stdout);
3281 	return(FALSE);
3282     }
3283 }
3284 
fill_sector_gap(int ptr,int drv,Uchar fdc_mf)3285 static int fill_sector_gap(int ptr, int drv, Uchar fdc_mf)
3286 {
3287     int   sync_size, am_size;
3288     int   gap0_size, gap1_size, gap2_size, gap3_size, gap4_size;
3289     int   track_size;
3290     Uchar gap;
3291     Uchar undel;
3292     int   size;
3293     int   tmp_size;
3294 
3295     if (fdc_mf) {
3296 	/* ��̩�� */
3297 	track_size = 6250;
3298 	gap0_size = 80;
3299 	sync_size = 12;
3300 	am_size   = 3 + 1;
3301 	gap1_size = 50;
3302 	gap2_size = 22;
3303 	gap = 0x4e;
3304 	/*if      (sec_buf.sec_nr <= 8)  gap4_size = 654;
3305 	  else if (sec_buf.sec_nr <= 15) gap4_size = 400;
3306 	  else                           gap4_size = 598;*/
3307     } else {
3308 	/* ñ̩�� */
3309 	track_size = 3100;
3310 	gap0_size = 40;
3311 	sync_size = 6;
3312 	am_size = 1;
3313 	gap1_size = 26;
3314 	gap2_size = 11;
3315 	gap = 0xff;
3316 	/*if      (sec_buf.sec_nr <= 8)  gap4_size = 311;
3317 	  else if (sec_buf.sec_nr <= 15) gap4_size = 170;
3318 	  else                           gap4_size = 247;*/
3319     }
3320     gap3_size = calc_gap3_size(sec_buf.n, fdc_mf);
3321 
3322     size = 0;
3323     /* DATA �ե�����ɤκǸ��� */
3324     size += 2;			/* DATA CRC */
3325 
3326     /* GAP3 */
3327     RET_GAP_ERR(input_safely_data(ptr, &size, gap, gap3_size));
3328 
3329     /* �ǽ��������ʤ�ץꥢ��֥� + �ݥ��ȥ���֥� */
3330     if (drive[drv].sec + 1 >= drive[drv].sec_nr) {
3331 	/* �ݥ��ȥ���֥� (GAP4) �Υ�������Ĵ�٤� */
3332 	tmp_size = gap0_size + sync_size + am_size + gap1_size;
3333 	/* ���ƤΥ������� GAP ������� */
3334 	do {
3335 	    disk_next_sec(drv);
3336 	    tmp_size += sync_size + am_size + 4 + 2; /* ID �ե������ */
3337 	    tmp_size += gap2_size;
3338 	    tmp_size += sync_size + am_size + sec_buf.size + 2;
3339 	    tmp_size += calc_gap3_size(sec_buf.n, fdc_mf);
3340 	} while (drive[drv].sec + 1 < drive[drv].sec_nr);
3341 	gap4_size = track_size - tmp_size;
3342 	if (gap4_size < 0) {
3343 	    printf("Abnormal sector\n");
3344 	    return(-1);
3345 	}
3346 
3347 
3348 	RET_GAP_ERR(input_safely_data(ptr, &size, gap, gap4_size));
3349 	RET_GAP_ERR(input_safely_data(ptr, &size, 0, sync_size));
3350 	RET_GAP_ERR(input_safely_data(ptr, &size, 0xc2, am_size - 1));
3351 	RET_GAP_ERR(input_safely_data(ptr, &size, 0xfc, 1));
3352 	RET_GAP_ERR(input_safely_data(ptr, &size, gap, gap1_size));
3353     }
3354 
3355     /* ���Υ����� */
3356     disk_next_sec(drv);
3357 
3358     /* ID �ե������ */
3359     RET_GAP_ERR(input_safely_data(ptr, &size, 0, sync_size));
3360     RET_GAP_ERR(input_safely_data(ptr, &size, 0xa1, am_size - 1));
3361     RET_GAP_ERR(input_safely_data(ptr, &size, 0xfe, 1));
3362 
3363     RET_GAP_ERR(input_safely_data(ptr, &size, sec_buf.c, 1));
3364     RET_GAP_ERR(input_safely_data(ptr, &size, sec_buf.h, 1));
3365     RET_GAP_ERR(input_safely_data(ptr, &size, sec_buf.r, 1));
3366     RET_GAP_ERR(input_safely_data(ptr, &size, sec_buf.n, 1));
3367     size += 2;			/* ID CRC */
3368 
3369     /* GAP2 */
3370     RET_GAP_ERR(input_safely_data(ptr, &size, gap, gap2_size));
3371 
3372     /* DATA �ե������ */
3373     RET_GAP_ERR(input_safely_data(ptr, &size, 0, sync_size));
3374     RET_GAP_ERR(input_safely_data(ptr, &size, 0xa1, am_size - 1));
3375 
3376     if (sec_buf.deleted == DISK_DELETED_TRUE) undel = 0xf8;
3377     else undel = 0xfb;
3378     RET_GAP_ERR(input_safely_data(ptr, &size, undel, 1));
3379 
3380     return(size);
3381 }
3382 
3383 
3384 
3385 /***********************************************************************
3386  * ���ơ��ȥ��ɡ����ơ��ȥ�����
3387  ************************************************************************/
3388 
3389 #define	SID		"FDC "
3390 #define	SID_DATA	"FDC0"
3391 #define	SID2		"FDC2"
3392 
3393 static	T_SUSPEND_W	suspend_fdc_work[]=
3394 {
3395   { TYPE_STR,	&file_disk[0][0],	},
3396   { TYPE_STR,	&file_disk[1][0],	},
3397   { TYPE_INT,	&image_disk[0],		},
3398   { TYPE_INT,	&image_disk[1],		},
3399   { TYPE_INT,	&readonly_disk[0],	},
3400   { TYPE_INT,	&readonly_disk[1],	},
3401 
3402   { TYPE_INT,	&disk_exchange,		},
3403   { TYPE_INT,	&disk_ex_drv,		},
3404 
3405   { TYPE_INT,	&FDC_flag,		},
3406   { TYPE_INT,	&fdc_wait,		},
3407 
3408   { TYPE_INT,	&fdc.command,		},
3409   { TYPE_INT,	&fdc.phase,		},
3410   { TYPE_INT,	&fdc.step,		},
3411   { TYPE_INT,	&fdc.counter,		},
3412   { TYPE_INT,	&fdc.data_ptr,		},
3413 
3414   { TYPE_INT,	&fdc.limit,		},
3415   { TYPE_INT,	&fdc.wait,		},
3416   { TYPE_INT,	&fdc.carry,		},
3417   { TYPE_INT,	&fdc.gap3,		},
3418 
3419   { TYPE_INT,	&fdc.seek_stat[0],	},
3420   { TYPE_INT,	&fdc.seek_stat[1],	},
3421   { TYPE_INT,	&fdc.seek_stat[2],	},
3422   { TYPE_INT,	&fdc.seek_stat[3],	},
3423   { TYPE_INT,	&fdc.seek_wait[0],	},
3424   { TYPE_INT,	&fdc.seek_wait[1],	},
3425   { TYPE_INT,	&fdc.seek_wait[2],	},
3426   { TYPE_INT,	&fdc.seek_wait[3],	},
3427 
3428   { TYPE_INT,	&fdc.srt_clk,		},
3429   { TYPE_INT,	&fdc.hut_clk,		},
3430   { TYPE_INT,	&fdc.hlt_clk,		},
3431   { TYPE_INT,	&fdc.hl_stat[0],	},
3432   { TYPE_INT,	&fdc.hl_stat[1],	},
3433   { TYPE_INT,	&fdc.hl_stat[2],	},
3434   { TYPE_INT,	&fdc.hl_stat[3],	},
3435   { TYPE_INT,	&fdc.hl_wait[0],	},
3436   { TYPE_INT,	&fdc.hl_wait[1],	},
3437   { TYPE_INT,	&fdc.hl_wait[2],	},
3438   { TYPE_INT,	&fdc.hl_wait[3],	},
3439 
3440   { TYPE_INT,	&fdc.ddam_not_skipped,	},
3441 
3442   { TYPE_BYTE,	&fdc.status,		},
3443   { TYPE_BYTE,	&fdc.read,		},
3444   { TYPE_BYTE,	&fdc.write,		},
3445   { TYPE_BYTE,	&fdc.TC,		},
3446 
3447   { TYPE_CHAR,	&fdc.sk,		},
3448   { TYPE_CHAR,	&fdc.mf,		},
3449   { TYPE_CHAR,	&fdc.mt,		},
3450   { TYPE_CHAR,	&fdc.us,		},
3451   { TYPE_CHAR,	&fdc.hd,		},
3452   { TYPE_CHAR,	&fdc.c,			},
3453   { TYPE_CHAR,	&fdc.h,			},
3454   { TYPE_CHAR,	&fdc.r,			},
3455   { TYPE_CHAR,	&fdc.n,			},
3456   { TYPE_CHAR,	&fdc.eot,		},
3457   { TYPE_CHAR,	&fdc.gpl,		},
3458   { TYPE_CHAR,	&fdc.dtl,		},
3459   { TYPE_CHAR,	&fdc.d,			},
3460   { TYPE_CHAR,	&fdc.sc,		},
3461   { TYPE_CHAR,	&fdc.stp,		},
3462   { TYPE_CHAR,	&fdc.ncn[0],		},
3463   { TYPE_CHAR,	&fdc.ncn[1],		},
3464   { TYPE_CHAR,	&fdc.ncn[2],		},
3465   { TYPE_CHAR,	&fdc.ncn[3],		},
3466   { TYPE_CHAR,	&fdc.pcn[0],		},
3467   { TYPE_CHAR,	&fdc.pcn[1],		},
3468   { TYPE_CHAR,	&fdc.pcn[2],		},
3469   { TYPE_CHAR,	&fdc.pcn[3],		},
3470   { TYPE_CHAR,	&fdc.st0,		},
3471   { TYPE_CHAR,	&fdc.st1,		},
3472   { TYPE_CHAR,	&fdc.st2,		},
3473   { TYPE_CHAR,	&fdc.st3,		},
3474 
3475   { TYPE_END,	0			},
3476 };
3477 
3478 static	T_SUSPEND_W	suspend_fdc_work2[]=
3479 {
3480   { TYPE_CHAR,	&fdc.c0			},
3481   { TYPE_CHAR,	&fdc.c1			},
3482   { TYPE_CHAR,	&fdc.cn			},
3483   { TYPE_CHAR,	&fdc.s0			},
3484   { TYPE_CHAR,	&fdc.s1			},
3485   { TYPE_CHAR,	&fdc.r0			},
3486   { TYPE_CHAR,	&fdc.r1			},
3487   { TYPE_CHAR,	&fdc.intr_unit		},
3488 
3489   { TYPE_END,	0			},
3490 };
3491 
3492 
statesave_fdc(void)3493 int	statesave_fdc( void )
3494 {
3495   image_disk[0] = drive[0].selected_image;
3496   image_disk[1] = drive[1].selected_image;
3497 
3498   if( statesave_table( SID, suspend_fdc_work ) != STATE_OK ) return FALSE;
3499 
3500   /* �ǡ����Хåե� */
3501   if( statesave_block( SID_DATA, data_buf, DATA_BUF_SIZE ) != STATE_OK )
3502 								return FALSE;
3503 
3504   if( statesave_table( SID2, suspend_fdc_work2 ) != STATE_OK ) return FALSE;
3505 
3506   return TRUE;
3507 }
3508 
stateload_fdc(void)3509 int	stateload_fdc( void )
3510 {
3511   if( stateload_table( SID, suspend_fdc_work ) != STATE_OK ) return FALSE;
3512 
3513   /* �ǡ����Хåե� */
3514   if( stateload_block( SID_DATA, data_buf, DATA_BUF_SIZE ) != STATE_OK )
3515 								return FALSE;
3516 
3517   if( stateload_table( SID2, suspend_fdc_work2 ) != STATE_OK ){
3518 
3519     /* ��С������ʤ顢�ߤΤ��� */
3520 
3521     printf( "stateload : Statefile is old. (ver 0.6.0 or 1?)\n" );
3522 
3523     /* �Ȥ��������Τ����������ˤʤ�褦���֤��������Բ�ǽ�������ä� */
3524     /* �����ʤ��Τǡ�ɬ���۾ェλ�Ȥʤ�褦�ʥѥ�᡼�����֤�����   */
3525 
3526     fdc.c0 = 0xff;	/* invalid  */
3527     fdc.c1 = 0xff;	/* 3rd unit */
3528     fdc.cn = 0xff;	/* 255 Cyl. */
3529     fdc.s0 = 0xda;	/* default  */
3530     fdc.s1 = 0x19;	/* default  */
3531     fdc.r0 = ST0_IC_IC;	/* invalid  */
3532     fdc.r1 = 0xff;	/* 255 Cyl. */
3533     fdc.intr_unit = 4;	/* non exist unit */
3534 
3535     return TRUE;
3536 
3537   }
3538 
3539   return TRUE;
3540 }
3541 
3542 
3543 
3544 
3545 
3546 
3547 /* �ǥХå��Ѥδؿ� */
monitor_fdc(void)3548 void monitor_fdc(void)
3549 {
3550   printf("com = %d phs = %d  step = %d\n",fdc.command,fdc.phase,fdc.step);
3551   printf("FDC flag = %d\n",FDC_flag);
3552 #if 0
3553   printf("\n");
3554   printf("fp       = %d , %d\n", drive[0].fp,       drive[1].fp      );
3555   printf("track    = %d , %d\n", drive[0].track,    drive[1].track   );
3556   printf("sec_nr   = %d , %d\n", drive[0].sec_nr,   drive[1].sec_nr  );
3557   printf("sec      = %d , %d\n", drive[0].sec,      drive[1].sec       );
3558   printf("sec_pos  = %d , %d\n", drive[0].sec_pos,  drive[1].sec_pos   );
3559   printf("track_top= %d , %d\n", drive[0].track_top,drive[1].track_top );
3560   printf("disk_top = %d , %d\n", drive[0].disk_top, drive[1].sec     );
3561   printf("type     = %d , %d\n", drive[0].type,     drive[1].type );
3562   printf("protect  = %d , %d\n", drive[0].protect,  drive[1].protect     );
3563 
3564   printf("\n");
3565   {
3566     int	i,j,k;
3567     for(k=0;k<(128<<(fdc.n&7))/256;k++){
3568       for(i=0;i<16;i++){
3569 	for(j=0;j<16;j++){
3570 	  printf("%02X ",data_buf[k*256+i*16+j]);
3571 	}
3572 	printf("\n");
3573       }
3574     }
3575   }
3576   printf("\n");
3577 #endif
3578 }
3579