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