35 #define FDC_PRIVATE_HEAD_SIDE
36 #define FDC_PRIVATE_HEAD_TRACK
37 #define FDC_PRIVATE_STATUS_A
38 #define FDC_PRIVATE_STATUS_B
40 #ifndef FDC_PRIVATE_HEAD_TRACK
43 #ifndef FDC_PRIVATE_HEAD_SIDE
46 #ifndef FDC_PRIVATE_STATUS_A
49 #ifndef FDC_PRIVATE_STATUS_B
52 static Uint8 track, sector, side;
57 static int emulate_busy;
60 static int cache_p_cpu;
61 static int cache_p_fdc;
62 static int swap_mask = 0;
63 static int warn_disk = 1;
64 static int warn_swap_bit = 1;
68 #ifdef FDC_PRIVATE_STATUS_A
71 #ifdef FDC_PRIVATE_STATUS_B
74 #ifdef FDC_PRIVATE_HEAD_TRACK
77 #ifdef FDC_PRIVATE_HEAD_SIDE
82 #ifdef FDC_PRIVATE_STATUS_A
83 # define DRV_STATUS_A(drv_no) drives[drv_no].status_a_storage
85 # define DRV_STATUS_A(drv_no) status_a_storage
88 #ifdef FDC_PRIVATE_STATUS_B
89 # define DRV_STATUS_B(drv_no) drives[drv_no].status_b_storage
91 # define DRV_STATUS_B(drv_no) status_b_storage
94 #ifdef FDC_PRIVATE_HEAD_SIDE
95 # define DRV_HEAD_SIDE(drv_no) drives[drv_no].head_side_storage
97 # define DRV_HEAD_SIDE(drv_no) head_side_storage
100 #ifdef FDC_PRIVATE_HEAD_TRACK
101 # define DRV_HEAD_TRACK(drv_no) drives[drv_no].head_track_storage
103 # define DRV_HEAD_TRACK(drv_no) head_track_storage
107 static void execute_command (
void );
112 DEBUG(
"FDC: init F011 emulation core" NL);
125 for (
int i = 0; i < 8; i++) {
163 static unsigned int blink_counter = 0;
164 int f011_motor = control & 32;
165 int f011_led = control & 64;
166 blink_counter += blink_inc;
167 return (!f011_led && f011_motor) || (f011_led && (blink_counter & 0x100));
179 drives[which].have_disk = in_have_disk;
180 drives[which].have_write = in_have_write;
181 DEBUG(
"FDC: init: set have_disk=%d, have_write=%d on drive %d" NL, in_have_disk, in_have_write, which);
190 if (!in_have_write) {
202 static void read_sector (
void )
206 DEBUG(
"FDC: reading sector drive=%d track=%d sector=%d side=%d @ PC=$%04X" NL, drive, track, sector, side, cpu65.old_pc);
207 Uint8 read_buffer[512];
208 error =
fdc_cb_rd_sec(drive, read_buffer, side, track, sector);
210 DEBUG(
"FDC: sector read-callback returned with error!" NL);
213 DEBUG(
"FDC: sector has been read." NL);
214 for (n = 0; n < 512; n++) {
215 cache[cache_p_fdc] = read_buffer[n];
216 cache_p_fdc = (cache_p_fdc + 1) & 511;
221 DEBUG(
"FDC: no disk in drive" NL);
223 INFO_WINDOW(
"No disk image was given or can be loaded!");
240 static void write_sector (
void )
244 DEBUG(
"FDC: writing sector drive=%d track=%d sector=%d side=%d @ PC=$%04X" NL, drive, track, sector, side, cpu65.old_pc);
245 Uint8 write_buffer[512];
247 for (n = 0; n < 512; n++) {
248 write_buffer[n] = cache[cache_p_fdc];
249 cache_p_fdc = (cache_p_fdc + 1) & 511;
251 error =
fdc_cb_wr_sec(drive, write_buffer, side, track, sector);
253 DEBUG(
"FDC: sector write-callback returned with error!" NL);
255 DEBUG(
"FDC: sector has been written." NL);
258 DEBUG(
"FDC: no disk in drive or write protected" NL);
260 INFO_WINDOW(
"No disk image was given or can be loaded or write protected disk!");
280 #ifdef DEBUG_FOR_PAUL
281 printf(
"PAUL: FDC register %d will be written now, data is $%02X buffer pointer is %d now" NL,
addr,
data, cache_p_cpu);
286 if (status_a & 128) {
287 DEBUG(
"FDC: WARN: trying to write control register ($%02X) while FDC is busy." NL,
data);
296 DEBUG(
"FDC: disk change signal was cleared on drive selection (drive: %d)" NL,
drive);
303 DEBUG(
"FDC: WARN: not drive-0 is selected: %d!" NL,
drive);
305 DEBUG(
"FDC: great, drive-0 is selected" NL);
308 DEBUG(
"FDC: WARN: SWAP bit emulation is experimental!" NL);
310 DEBUGPRINT(
"FDC: warning: SWAP bit emulation is experimental! There will be no further warnings on this." NL);
319 DEBUG(
"FDC: command=$%02X (lower bits: $%X)" NL,
data & 0xF8,
data & 7);
321 DEBUG(
"FDC: WARN: trying to issue another command ($%02X) while the previous ($%02X) is running." NL,
data, cmd);
346 cache[cache_p_cpu ^ swap_mask] =
data;
347 cache_p_cpu = (cache_p_cpu + 1) & 511;
349 if (cache_p_cpu == cache_p_fdc)
366 #ifdef DEBUG_FOR_PAUL
367 printf(
"PAUL: FDC register %d has been written, data was $%02X buffer pointer is %d now" NL,
addr,
data, cache_p_cpu);
372 static void execute_command (
void )
374 #ifdef DEBUG_FOR_PAUL
375 printf(
"PAUL: issuing FDC command $%02X pointer was %d" NL, cmd, cache_p_cpu);
380 INFO_WINDOW(
"Sorry, FDC-IRQ is not supported yet, by FDC emulation!");
386 printf(
"Command: $%02X" NL, cmd);
388 switch (cmd & 0xF8) {
401 printf(
"READ: cache_p_cpu=%d / cache_p_fdc=%d drive_selected=%d" NL, cache_p_cpu, cache_p_fdc, drive);
403 DEBUG(
"FDC: READ: head_track=%d need_track=%d head_side=%d need_side=%d need_sector=%d drive_selected=%d" NL,
413 printf(
"WRITE: cache_p_cpu=%d / cache_p_fdc=%d drive_selected=%d" NL, cache_p_cpu, cache_p_fdc, drive);
415 DEBUG(
"FDC: WRITE: head_track=%d need_track=%d head_side=%d need_side=%d need_sector=%d drive_selected=%d" NL,
420 printf(
"Sorry, write protected stuff ..." NL);
449 printf(
"BEFORE pointer reset: cache_p_cpu=%d cache_p_fdc=%d" NL, cache_p_cpu, cache_p_fdc);
453 DEBUG(
"FDC: WARN: resetting cache pointers" NL);
461 DEBUG(
"FDC: WARN: unknown comand: $%02X" NL, cmd);
466 #ifdef DEBUG_FOR_PAUL
467 printf(
"PAUL: issued FDC command $%02X pointer is %d" NL, cmd, cache_p_cpu);
475 #ifdef DEBUG_FOR_PAUL
476 printf(
"PAUL: FDC register %d will be read, buffer pointer is %d now" NL,
addr, cache_p_cpu);
483 if (emulate_busy > 0)
485 if (emulate_busy <= 0) {
487 printf(
"Delayed command execution!!!" NL);
521 result = cache[cache_p_cpu ^ swap_mask];
522 cache_p_cpu = (cache_p_cpu + 1) & 511;
524 if (cache_p_cpu == cache_p_fdc)
542 DEBUG(
"FDC: reading register %d result is $%02X" NL,
addr, result);
543 #ifdef DEBUG_FOR_PAUL
544 printf(
"PAUL: FDC register %d has been read, result was $%02X buffer pointer is %d now" NL,
addr, result, cache_p_cpu);
553 #ifdef XEMU_SNAPSHOT_SUPPORT
557 #define SNAPSHOT_FDC_BLOCK_VERSION 0
560 #define SNAPSHOT_FDC_BLOCK_SIZE 0x100
562 #define CACHE_SIZE 512
563 #define SNAPSHOT_FDC_BLOCK_SIZE (0x100 + CACHE_SIZE)
566 int fdc_snapshot_load_state (
const struct xemu_snapshot_definition_st *def,
struct xemu_snapshot_block_st *
block )
568 Uint8 buffer[SNAPSHOT_FDC_BLOCK_SIZE];
570 if (
block->block_version != SNAPSHOT_FDC_BLOCK_VERSION ||
block->sub_counter ||
block->sub_size !=
sizeof buffer)
571 RETURN_XSNAPERR_USER(
"Bad FDC-F011 block syntax");
572 a = xemusnap_read_file(buffer,
sizeof buffer);
575 curcmd = P_AS_BE32(buffer + 4);
576 emulate_busy = P_AS_BE32(buffer + 8);
577 drive = P_AS_BE32(buffer + 12);
579 cache_p_cpu = P_AS_BE32(buffer + 16);
580 cache_p_fdc = P_AS_BE32(buffer + 20);
581 swap_mask = P_AS_BE32(buffer + 24);
582 drives[
drive].have_disk = P_AS_BE32(buffer + 28);
583 drives[
drive].have_write = P_AS_BE32(buffer + 32);
586 sector = buffer[130];
588 control = buffer[132];
592 dskclock = buffer[136];
595 memcpy(cache, buffer + 0x100, CACHE_SIZE);
601 int fdc_snapshot_save_state (
const struct xemu_snapshot_definition_st *def )
603 Uint8 buffer[SNAPSHOT_FDC_BLOCK_SIZE];
604 int a = xemusnap_write_block_header(def->idstr, SNAPSHOT_FDC_BLOCK_VERSION);
606 memset(buffer, 0xFF,
sizeof buffer);
609 U32_AS_BE(buffer + 4, curcmd);
610 U32_AS_BE(buffer + 8, emulate_busy);
611 U32_AS_BE(buffer + 12, drive);
612 U32_AS_BE(buffer + 16, cache_p_cpu);
613 U32_AS_BE(buffer + 20, cache_p_fdc);
614 U32_AS_BE(buffer + 24, swap_mask);
615 U32_AS_BE(buffer + 28, drives[drive].
have_disk);
616 U32_AS_BE(buffer + 32, drives[drive].
have_write);
619 buffer[130] = sector;
621 buffer[132] = control;
625 buffer[136] = dskclock;
628 memcpy(buffer + 0x100, cache, CACHE_SIZE);
630 return xemusnap_write_sub_block(buffer,
sizeof buffer);