The FDC is now a device_t, and the FDC code has been cleaned up;
Merged floppy.c and fdd.c and renamed floppy_*.c (the floppy image format handlers) to fdd_*.c; Reading the AT or PS/2 keyboard controller status no longer clears the transmit timeout bit, fixes error 8601 (mouse error) on the IBM PS/2 Model 80; MMU translate and DMA physical reads and writes now go through _mem_exec instead of directly to ram[], should fix the last remaining problems with remapped mappings; Implemented the Sound gain dialog; Added the resource for the "New floppy image" dialog and the needed functions for the functionality of exporting the currently mounted floppy image as 86F, both of which should be finished in the next commit; Applied the CD-ROM fixes from the PCem commit; Added the "Keep ratio" option for full screen stretch.
This commit is contained in:
3717
src/floppy/fdc.c
3717
src/floppy/fdc.c
File diff suppressed because it is too large
Load Diff
206
src/floppy/fdc.h
206
src/floppy/fdc.h
@@ -9,84 +9,162 @@
|
||||
* Implementation of the NEC uPD-765 and compatible floppy disk
|
||||
* controller.
|
||||
*
|
||||
* Version: @(#)fdc.h 1.0.2 2017/09/03
|
||||
* Version: @(#)fdc.h 1.0.3 2018/01/16
|
||||
*
|
||||
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
* Copyright 2008-2017 Sarah Walker.
|
||||
* Copyright 2016,2017 Miran Grca.
|
||||
* Copyright 2008-2018 Sarah Walker.
|
||||
* Copyright 2016-2018 Miran Grca.
|
||||
*/
|
||||
#ifndef EMU_FDC_H
|
||||
# define EMU_FDC_H
|
||||
|
||||
|
||||
extern void fdc_init(void);
|
||||
extern void fdc_add(void);
|
||||
extern void fdc_add_for_superio(void);
|
||||
extern void fdc_add_pcjr(void);
|
||||
extern void fdc_add_tandy(void);
|
||||
extern void fdc_remove(void);
|
||||
extern void fdc_reset(void);
|
||||
extern void fdc_poll(void);
|
||||
extern void fdc_abort(void);
|
||||
extern void fdc_floppychange_clear(int drive);
|
||||
extern void fdc_set_dskchg_activelow(void);
|
||||
extern void fdc_3f1_enable(int enable);
|
||||
extern void fdc_set_ps1(void);
|
||||
extern int fdc_get_bit_rate(void);
|
||||
extern int fdc_get_bitcell_period(void);
|
||||
#define FDC_FLAG_PCJR 0x01 /* PCjr */
|
||||
#define FDC_FLAG_DISKCHG_ACTLOW 0x02 /* Amstrad, PS/1, PS/2 ISA */
|
||||
#define FDC_FLAG_AT 0x04 /* AT+, PS/x */
|
||||
#define FDC_FLAG_PS1 0x08 /* PS/1, PS/2 ISA */
|
||||
#define FDC_FLAG_SUPERIO 0x10 /* Super I/O chips */
|
||||
#define FDC_FLAG_START_RWC_1 0x20 /* W83877F, W83977F */
|
||||
#define FDC_FLAG_MORE_TRACKS 0x40 /* W83877F, W83977F, PC87306, PC87309 */
|
||||
#define FDC_FLAG_NSC 0x80 /* PC87306, PC87309 */
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint8_t dor, stat, command, dat, st0, swap;
|
||||
uint8_t swwp, disable_write;
|
||||
uint8_t params[256], res[256];
|
||||
uint8_t specify[256], format_dat[256];
|
||||
uint8_t config, pretrk;
|
||||
uint8_t fifobuf[16];
|
||||
|
||||
uint16_t base_address;
|
||||
|
||||
int head, sector, drive, lastdrive;
|
||||
int pcn[4], eot[256];
|
||||
int rw_track, pos;
|
||||
int pnum, ptot;
|
||||
int rate, reset_stat;
|
||||
int lock, perp;
|
||||
int abort;
|
||||
int format_state, format_n;
|
||||
int tc, written;
|
||||
|
||||
int data_ready, inread;
|
||||
int bitcell_period, enh_mode;
|
||||
int rwc[4], drvrate[4];
|
||||
int boot_drive, dma;
|
||||
int densel_polarity, densel_force;
|
||||
int fifo, tfifo;
|
||||
int fifobufpos, drv2en;
|
||||
|
||||
int gap, dtl;
|
||||
int enable_3f1, format_sectors;
|
||||
int max_track, mfm;
|
||||
int deleted, wrong_am;
|
||||
int sc, satisfying_sectors;
|
||||
int fintr, rw_drive;
|
||||
|
||||
int flags, interrupt;
|
||||
|
||||
int irq; /* Should be 6 by default. */
|
||||
int dma_ch; /* Should be 2 by default. */
|
||||
|
||||
int bit_rate; /* Should be 250 at start. */
|
||||
int paramstogo;
|
||||
|
||||
sector_id_t read_track_sector;
|
||||
|
||||
int64_t time;
|
||||
int64_t watchdog_timer, watchdog_count;
|
||||
} fdc_t;
|
||||
|
||||
extern void fdc_remove(fdc_t *fdc);
|
||||
extern void fdc_poll(fdc_t *fdc);
|
||||
extern void fdc_abort(fdc_t *fdc);
|
||||
extern void fdc_set_dskchg_activelow(fdc_t *fdc);
|
||||
extern void fdc_3f1_enable(fdc_t *fdc, int enable);
|
||||
extern int fdc_get_bit_rate(fdc_t *fdc);
|
||||
extern int fdc_get_bitcell_period(fdc_t *fdc);
|
||||
|
||||
/* A few functions to communicate between Super I/O chips and the FDC. */
|
||||
extern void fdc_update_is_nsc(int is_nsc);
|
||||
extern void fdc_update_max_track(int max_track);
|
||||
extern void fdc_update_enh_mode(int enh_mode);
|
||||
extern int fdc_get_rwc(int drive);
|
||||
extern void fdc_update_rwc(int drive, int rwc);
|
||||
extern int fdc_get_boot_drive(void);
|
||||
extern void fdc_update_boot_drive(int boot_drive);
|
||||
extern void fdc_update_densel_polarity(int densel_polarity);
|
||||
extern uint8_t fdc_get_densel_polarity(void);
|
||||
extern void fdc_update_densel_force(int densel_force);
|
||||
extern void fdc_update_drvrate(int drive, int drvrate);
|
||||
extern void fdc_update_drv2en(int drv2en);
|
||||
extern void fdc_update_enh_mode(fdc_t *fdc, int enh_mode);
|
||||
extern int fdc_get_rwc(fdc_t *fdc, int drive);
|
||||
extern void fdc_update_rwc(fdc_t *fdc, int drive, int rwc);
|
||||
extern int fdc_get_boot_drive(fdc_t *fdc);
|
||||
extern void fdc_update_boot_drive(fdc_t *fdc, int boot_drive);
|
||||
extern void fdc_update_densel_polarity(fdc_t *fdc, int densel_polarity);
|
||||
extern uint8_t fdc_get_densel_polarity(fdc_t *fdc);
|
||||
extern void fdc_update_densel_force(fdc_t *fdc, int densel_force);
|
||||
extern void fdc_update_drvrate(fdc_t *fdc, int drive, int drvrate);
|
||||
extern void fdc_update_drv2en(fdc_t *fdc, int drv2en);
|
||||
|
||||
extern void fdc_noidam(void);
|
||||
extern void fdc_nosector(void);
|
||||
extern void fdc_nodataam(void);
|
||||
extern void fdc_cannotformat(void);
|
||||
extern void fdc_wrongcylinder(void);
|
||||
extern void fdc_badcylinder(void);
|
||||
extern void fdc_noidam(fdc_t *fdc);
|
||||
extern void fdc_nosector(fdc_t *fdc);
|
||||
extern void fdc_nodataam(fdc_t *fdc);
|
||||
extern void fdc_cannotformat(fdc_t *fdc);
|
||||
extern void fdc_wrongcylinder(fdc_t *fdc);
|
||||
extern void fdc_badcylinder(fdc_t *fdc);
|
||||
extern void fdc_writeprotect(fdc_t *fdc);
|
||||
extern void fdc_datacrcerror(fdc_t *fdc);
|
||||
extern void fdc_headercrcerror(fdc_t *fdc);
|
||||
extern void fdc_nosector(fdc_t *fdc);
|
||||
|
||||
extern sector_id_t fdc_get_read_track_sector(void);
|
||||
extern int fdc_get_compare_condition(void);
|
||||
extern int fdc_is_deleted(void);
|
||||
extern int fdc_is_sk(void);
|
||||
extern void fdc_set_wrong_am(void);
|
||||
extern int fdc_get_drive(void);
|
||||
extern int fdc_get_perp(void);
|
||||
extern int fdc_get_format_n(void);
|
||||
extern int fdc_is_mfm(void);
|
||||
extern double fdc_get_hut(void);
|
||||
extern double fdc_get_hlt(void);
|
||||
extern void fdc_request_next_sector_id(void);
|
||||
extern void fdc_stop_id_request(void);
|
||||
extern int fdc_get_gap(void);
|
||||
extern int fdc_get_gap2(int drive);
|
||||
extern int fdc_get_dtl(void);
|
||||
extern int fdc_get_format_sectors(void);
|
||||
extern int real_drive(fdc_t *fdc, int drive);
|
||||
|
||||
extern void fdc_finishcompare(int satisfying);
|
||||
extern void fdc_finishread(void);
|
||||
extern void fdc_sector_finishcompare(int satisfying);
|
||||
extern void fdc_sector_finishread(void);
|
||||
extern void fdc_track_finishread(int condition);
|
||||
extern int fdc_is_verify(void);
|
||||
extern sector_id_t fdc_get_read_track_sector(fdc_t *fdc);
|
||||
extern int fdc_get_compare_condition(fdc_t *fdc);
|
||||
extern int fdc_is_deleted(fdc_t *fdc);
|
||||
extern int fdc_is_sk(fdc_t *fdc);
|
||||
extern void fdc_set_wrong_am(fdc_t *fdc);
|
||||
extern int fdc_get_drive(fdc_t *fdc);
|
||||
extern int fdc_get_perp(fdc_t *fdc);
|
||||
extern int fdc_get_format_n(fdc_t *fdc);
|
||||
extern int fdc_is_mfm(fdc_t *fdc);
|
||||
extern double fdc_get_hut(fdc_t *fdc);
|
||||
extern double fdc_get_hlt(fdc_t *fdc);
|
||||
extern void fdc_request_next_sector_id(fdc_t *fdc);
|
||||
extern void fdc_stop_id_request(fdc_t *fdc);
|
||||
extern int fdc_get_gap(fdc_t *fdc);
|
||||
extern int fdc_get_gap2(fdc_t *fdc, int drive);
|
||||
extern int fdc_get_dtl(fdc_t *fdc);
|
||||
extern int fdc_get_format_sectors(fdc_t *fdc);
|
||||
extern uint8_t fdc_get_swwp(fdc_t *fdc);
|
||||
extern void fdc_set_swwp(fdc_t *fdc, uint8_t swwp);
|
||||
extern uint8_t fdc_get_diswr(fdc_t *fdc);
|
||||
extern void fdc_set_diswr(fdc_t *fdc, uint8_t diswr);
|
||||
extern uint8_t fdc_get_swap(fdc_t *fdc);
|
||||
extern void fdc_set_swap(fdc_t *fdc, uint8_t swap);
|
||||
|
||||
extern int real_drive(int drive);
|
||||
extern void fdc_overrun(void);
|
||||
extern void fdc_set_base(int base, int super_io);
|
||||
extern int fdc_ps1_525(void);
|
||||
extern void fdc_hard_reset(void);
|
||||
extern void fdc_finishcompare(fdc_t *fdc, int satisfying);
|
||||
extern void fdc_finishread(fdc_t *fdc);
|
||||
extern void fdc_sector_finishcompare(fdc_t *fdc, int satisfying);
|
||||
extern void fdc_sector_finishread(fdc_t *fdc);
|
||||
extern void fdc_track_finishread(fdc_t *fdc, int condition);
|
||||
extern int fdc_is_verify(fdc_t *fdc);
|
||||
|
||||
extern void fdc_overrun(fdc_t *fdc);
|
||||
extern void fdc_set_base(fdc_t *fdc, int base);
|
||||
extern int fdc_getdata(fdc_t *fdc, int last);
|
||||
extern int fdc_data(fdc_t *fdc, uint8_t data);
|
||||
|
||||
extern void fdc_sectorid(fdc_t *fdc, uint8_t track, uint8_t side, uint8_t sector, uint8_t size, uint8_t crc1, uint8_t crc2);
|
||||
|
||||
extern void fdc_reset(void *priv);
|
||||
|
||||
extern uint8_t fdc_ps1_525(void);
|
||||
|
||||
#ifdef EMU_DEVICE_H
|
||||
extern device_t fdc_xt_device;
|
||||
extern device_t fdc_xt_amstrad_device;
|
||||
extern device_t fdc_pcjr_device;
|
||||
extern device_t fdc_at_device;
|
||||
extern device_t fdc_at_actlow_device;
|
||||
extern device_t fdc_at_ps1_device;
|
||||
extern device_t fdc_at_smc_device;
|
||||
extern device_t fdc_at_winbond_device;
|
||||
extern device_t fdc_at_nsc_device;
|
||||
#endif
|
||||
|
||||
|
||||
#endif /*EMU_FDC_H*/
|
||||
|
||||
415
src/floppy/fdd.c
415
src/floppy/fdd.c
@@ -8,22 +8,107 @@
|
||||
*
|
||||
* Implementation of the floppy drive emulation.
|
||||
*
|
||||
* Version: @(#)fdd.c 1.0.5 2017/11/04
|
||||
* Version: @(#)fdd.c 1.0.6 2018/01/16
|
||||
*
|
||||
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
*
|
||||
* Copyright 2008-2017 Sarah Walker.
|
||||
* Copyright 2016,2017 Miran Grca.
|
||||
* Copyright 2008-2018 Sarah Walker.
|
||||
* Copyright 2016-2018 Miran Grca.
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <wchar.h>
|
||||
#include "../86box.h"
|
||||
#include "floppy.h"
|
||||
#include "fdc.h"
|
||||
#include "../machine/machine.h"
|
||||
#include "../mem.h"
|
||||
#include "../rom.h"
|
||||
#include "../config.h"
|
||||
#include "../timer.h"
|
||||
#include "../plat.h"
|
||||
#include "../ui.h"
|
||||
#include "fdd.h"
|
||||
#include "fdd_86f.h"
|
||||
#include "fdd_fdi.h"
|
||||
#include "fdd_imd.h"
|
||||
#include "fdd_img.h"
|
||||
#include "fdd_json.h"
|
||||
#include "fdd_td0.h"
|
||||
#include "fdc.h"
|
||||
|
||||
|
||||
extern int driveempty[4];
|
||||
|
||||
wchar_t floppyfns[4][512];
|
||||
|
||||
int64_t fdd_poll_time[FDD_NUM] = { 16LL, 16LL, 16LL, 16LL };
|
||||
|
||||
int fdd_cur_track[FDD_NUM];
|
||||
int writeprot[FDD_NUM], fwriteprot[FDD_NUM];
|
||||
|
||||
DRIVE drives[FDD_NUM];
|
||||
int drive_type[FDD_NUM];
|
||||
|
||||
int curdrive = 0;
|
||||
|
||||
int defaultwriteprot = 0;
|
||||
|
||||
int fdc_ready;
|
||||
|
||||
int drive_empty[FDD_NUM] = {1, 1, 1, 1};
|
||||
int fdd_changed[FDD_NUM];
|
||||
|
||||
int motorspin;
|
||||
int64_t motoron[FDD_NUM];
|
||||
|
||||
int fdc_indexcount = 52;
|
||||
|
||||
fdc_t *fdd_fdc;
|
||||
|
||||
|
||||
static struct
|
||||
{
|
||||
wchar_t *ext;
|
||||
void (*load)(int drive, wchar_t *fn);
|
||||
void (*close)(int drive);
|
||||
int size;
|
||||
} loaders[]=
|
||||
{
|
||||
{L"001", img_load, img_close, -1},
|
||||
{L"002", img_load, img_close, -1},
|
||||
{L"003", img_load, img_close, -1},
|
||||
{L"004", img_load, img_close, -1},
|
||||
{L"005", img_load, img_close, -1},
|
||||
{L"006", img_load, img_close, -1},
|
||||
{L"007", img_load, img_close, -1},
|
||||
{L"008", img_load, img_close, -1},
|
||||
{L"009", img_load, img_close, -1},
|
||||
{L"010", img_load, img_close, -1},
|
||||
{L"12", img_load, img_close, -1},
|
||||
{L"144", img_load, img_close, -1},
|
||||
{L"360", img_load, img_close, -1},
|
||||
{L"720", img_load, img_close, -1},
|
||||
{L"86F", d86f_load, d86f_close, -1},
|
||||
{L"BIN", img_load, img_close, -1},
|
||||
{L"CQ", img_load, img_close, -1},
|
||||
{L"CQM", img_load, img_close, -1},
|
||||
{L"DSK", img_load, img_close, -1},
|
||||
{L"FDI", fdi_load, fdi_close, -1},
|
||||
{L"FDF", img_load, img_close, -1},
|
||||
{L"FLP", img_load, img_close, -1},
|
||||
{L"HDM", img_load, img_close, -1},
|
||||
{L"IMA", img_load, img_close, -1},
|
||||
{L"IMD", imd_load, imd_close, -1},
|
||||
{L"IMG", img_load, img_close, -1},
|
||||
{L"JSON", json_load, json_close, -1},
|
||||
{L"TD0", td0_load, td0_close, -1},
|
||||
{L"VFD", img_load, img_close, -1},
|
||||
{L"XDF", img_load, img_close, -1},
|
||||
{0,0,0}
|
||||
};
|
||||
|
||||
static int driveloaders[4];
|
||||
|
||||
|
||||
typedef struct {
|
||||
@@ -120,8 +205,6 @@ static struct
|
||||
}
|
||||
};
|
||||
|
||||
int fdd_swap = 0;
|
||||
|
||||
char *fdd_getname(int type)
|
||||
{
|
||||
return drive_types[type].name;
|
||||
@@ -146,10 +229,15 @@ int fdd_get_from_internal_name(char *s)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* This is needed for the dump as 86F feature. */
|
||||
void fdd_do_seek(int drive, int track)
|
||||
{
|
||||
if (drives[drive].seek)
|
||||
drives[drive].seek(drive, fdd[drive].track);
|
||||
}
|
||||
|
||||
void fdd_forced_seek(int drive, int track_diff)
|
||||
{
|
||||
drive = real_drive(drive);
|
||||
|
||||
fdd[drive].track += track_diff;
|
||||
|
||||
if (fdd[drive].track < 0)
|
||||
@@ -158,19 +246,13 @@ void fdd_forced_seek(int drive, int track_diff)
|
||||
if (fdd[drive].track > drive_types[fdd[drive].type].max_track)
|
||||
fdd[drive].track = drive_types[fdd[drive].type].max_track;
|
||||
|
||||
floppy_seek(drive, fdd[drive].track);
|
||||
floppytime = 5000;
|
||||
fdd_do_seek(drive, fdd[drive].track);
|
||||
}
|
||||
|
||||
void fdd_seek(int drive, int track_diff)
|
||||
{
|
||||
drive = real_drive(drive);
|
||||
|
||||
if (!track_diff)
|
||||
{
|
||||
floppytime = 5000;
|
||||
return;
|
||||
}
|
||||
|
||||
fdd[drive].track += track_diff;
|
||||
|
||||
@@ -180,22 +262,20 @@ void fdd_seek(int drive, int track_diff)
|
||||
if (fdd[drive].track > drive_types[fdd[drive].type].max_track)
|
||||
fdd[drive].track = drive_types[fdd[drive].type].max_track;
|
||||
|
||||
fdc_floppychange_clear(drive);
|
||||
floppy_seek(drive, fdd[drive].track);
|
||||
floppytime = 5000;
|
||||
fdd_changed[drive] = 0;
|
||||
|
||||
fdd_do_seek(drive, fdd[drive].track);
|
||||
}
|
||||
|
||||
int fdd_track0(int drive)
|
||||
{
|
||||
drive = real_drive(drive);
|
||||
|
||||
/* If drive is disabled, TRK0 never gets set. */
|
||||
if (!drive_types[fdd[drive].type].max_track) return 0;
|
||||
|
||||
return !fdd[drive].track;
|
||||
}
|
||||
|
||||
int fdd_track(int drive)
|
||||
int fdd_current_track(int drive)
|
||||
{
|
||||
return fdd[drive].track;
|
||||
}
|
||||
@@ -219,12 +299,10 @@ void fdd_set_densel(int densel)
|
||||
|
||||
int fdd_getrpm(int drive)
|
||||
{
|
||||
int hole = floppy_hole(drive);
|
||||
int hole = fdd_hole(drive);
|
||||
|
||||
int densel = 0;
|
||||
|
||||
drive = real_drive(drive);
|
||||
|
||||
densel = fdd[drive].densel;
|
||||
|
||||
if (drive_types[fdd[drive].type].flags & FLAG_INVERT_DENSEL)
|
||||
@@ -241,7 +319,7 @@ int fdd_getrpm(int drive)
|
||||
}
|
||||
else
|
||||
{
|
||||
/* floppy_hole(drive) returns 0 for double density media, 1 for high density, and 2 for extended density. */
|
||||
/* fdd_hole(drive) returns 0 for double density media, 1 for high density, and 2 for extended density. */
|
||||
if (hole == 1)
|
||||
{
|
||||
return densel ? 300 : 360;
|
||||
@@ -253,16 +331,9 @@ int fdd_getrpm(int drive)
|
||||
}
|
||||
}
|
||||
|
||||
void fdd_setswap(int swap)
|
||||
{
|
||||
fdd_swap = swap ? 1 : 0;
|
||||
}
|
||||
|
||||
int fdd_can_read_medium(int drive)
|
||||
{
|
||||
int hole = floppy_hole(drive);
|
||||
|
||||
drive = real_drive(drive);
|
||||
int hole = fdd_hole(drive);
|
||||
|
||||
hole = 1 << (hole + 3);
|
||||
|
||||
@@ -316,7 +387,6 @@ int fdd_is_double_sided(int drive)
|
||||
|
||||
void fdd_set_head(int drive, int head)
|
||||
{
|
||||
drive = real_drive(drive);
|
||||
fdd[drive].head = head;
|
||||
}
|
||||
|
||||
@@ -357,6 +427,279 @@ int fdd_get_densel(int drive)
|
||||
}
|
||||
}
|
||||
|
||||
void fdd_init()
|
||||
void fdd_load(int drive, wchar_t *fn)
|
||||
{
|
||||
int c = 0, size;
|
||||
wchar_t *p;
|
||||
FILE *f;
|
||||
if (!fn) return;
|
||||
p = plat_get_extension(fn);
|
||||
if (!p) return;
|
||||
f = plat_fopen(fn, L"rb");
|
||||
if (!f) return;
|
||||
fseek(f, -1, SEEK_END);
|
||||
size = ftell(f) + 1;
|
||||
fclose(f);
|
||||
while (loaders[c].ext)
|
||||
{
|
||||
if (!wcscasecmp(p, loaders[c].ext) && (size == loaders[c].size || loaders[c].size == -1))
|
||||
{
|
||||
driveloaders[drive] = c;
|
||||
memcpy(floppyfns[drive], fn, (wcslen(fn) << 1) + 2);
|
||||
loaders[c].load(drive, floppyfns[drive]);
|
||||
drive_empty[drive] = 0;
|
||||
fdd_forced_seek(drive, 0);
|
||||
fdd_changed[drive] = 1;
|
||||
return;
|
||||
}
|
||||
c++;
|
||||
}
|
||||
pclog("Couldn't load %ls %s\n",fn,p);
|
||||
drive_empty[drive] = 1;
|
||||
fdd_set_head(drive, 0);
|
||||
memset(floppyfns[drive], 0, sizeof(floppyfns[drive]));
|
||||
ui_sb_update_icon_state(drive, 1);
|
||||
}
|
||||
|
||||
void fdd_close(int drive)
|
||||
{
|
||||
if (loaders[driveloaders[drive]].close) loaders[driveloaders[drive]].close(drive);
|
||||
drive_empty[drive] = 1;
|
||||
fdd_set_head(drive, 0);
|
||||
floppyfns[drive][0] = 0;
|
||||
drives[drive].hole = NULL;
|
||||
drives[drive].poll = NULL;
|
||||
drives[drive].seek = NULL;
|
||||
drives[drive].readsector = NULL;
|
||||
drives[drive].writesector = NULL;
|
||||
drives[drive].comparesector = NULL;
|
||||
drives[drive].readaddress = NULL;
|
||||
drives[drive].format = NULL;
|
||||
drives[drive].byteperiod = NULL;
|
||||
drives[drive].stop = NULL;
|
||||
ui_sb_update_icon_state(drive, 1);
|
||||
}
|
||||
|
||||
int fdd_notfound = 0;
|
||||
static int fdd_period = 32;
|
||||
|
||||
int fdd_hole(int drive)
|
||||
{
|
||||
if (drives[drive].hole)
|
||||
{
|
||||
return drives[drive].hole(drive);
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
double fdd_byteperiod(int drive)
|
||||
{
|
||||
if (drives[drive].byteperiod)
|
||||
{
|
||||
return drives[drive].byteperiod(drive);
|
||||
}
|
||||
else
|
||||
{
|
||||
return 32.0;
|
||||
}
|
||||
}
|
||||
|
||||
double fdd_real_period(int drive)
|
||||
{
|
||||
double ddbp;
|
||||
double dusec;
|
||||
|
||||
ddbp = fdd_byteperiod(drive);
|
||||
|
||||
dusec = (double) TIMER_USEC;
|
||||
|
||||
/* This is a giant hack but until the timings become even more correct, this is needed to make floppies work right on that BIOS. */
|
||||
if (fdd_get_turbo(drive))
|
||||
{
|
||||
return (32.0 * dusec);
|
||||
}
|
||||
|
||||
if (romset == ROM_MRTHOR)
|
||||
{
|
||||
return (ddbp * dusec) / 4.0;
|
||||
}
|
||||
else
|
||||
{
|
||||
return (ddbp * dusec);
|
||||
}
|
||||
}
|
||||
|
||||
void fdd_poll(int drive)
|
||||
{
|
||||
if (drive >= FDD_NUM)
|
||||
{
|
||||
fatal("Attempting to poll floppy drive %i that is not supposed to be there\n", drive);
|
||||
}
|
||||
|
||||
fdd_poll_time[drive] += (int64_t) fdd_real_period(drive);
|
||||
|
||||
if (drives[drive].poll)
|
||||
drives[drive].poll(drive);
|
||||
|
||||
if (fdd_notfound)
|
||||
{
|
||||
fdd_notfound--;
|
||||
if (!fdd_notfound)
|
||||
fdc_noidam(fdd_fdc);
|
||||
}
|
||||
}
|
||||
|
||||
void fdd_poll_0(void *priv)
|
||||
{
|
||||
fdd_poll(0);
|
||||
}
|
||||
|
||||
void fdd_poll_1(void *priv)
|
||||
{
|
||||
fdd_poll(1);
|
||||
}
|
||||
|
||||
void fdd_poll_2(void *priv)
|
||||
{
|
||||
fdd_poll(2);
|
||||
}
|
||||
|
||||
void fdd_poll_3(void *priv)
|
||||
{
|
||||
fdd_poll(3);
|
||||
}
|
||||
|
||||
int fdd_get_bitcell_period(int rate)
|
||||
{
|
||||
int bit_rate = 250;
|
||||
|
||||
switch (rate)
|
||||
{
|
||||
case 0: /*High density*/
|
||||
bit_rate = 500;
|
||||
break;
|
||||
case 1: /*Double density (360 rpm)*/
|
||||
bit_rate = 300;
|
||||
break;
|
||||
case 2: /*Double density*/
|
||||
bit_rate = 250;
|
||||
break;
|
||||
case 3: /*Extended density*/
|
||||
bit_rate = 1000;
|
||||
break;
|
||||
}
|
||||
|
||||
return 1000000 / bit_rate*2; /*Bitcell period in ns*/
|
||||
}
|
||||
|
||||
|
||||
void fdd_set_rate(int drive, int drvden, int rate)
|
||||
{
|
||||
switch (rate)
|
||||
{
|
||||
case 0: /*High density*/
|
||||
fdd_period = 16;
|
||||
break;
|
||||
case 1:
|
||||
switch(drvden)
|
||||
{
|
||||
case 0: /*Double density (360 rpm)*/
|
||||
fdd_period = 26;
|
||||
break;
|
||||
case 1: /*High density (360 rpm)*/
|
||||
fdd_period = 16;
|
||||
break;
|
||||
case 2:
|
||||
fdd_period = 4;
|
||||
break;
|
||||
}
|
||||
case 2: /*Double density*/
|
||||
fdd_period = 32;
|
||||
break;
|
||||
case 3: /*Extended density*/
|
||||
fdd_period = 8;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void fdd_reset()
|
||||
{
|
||||
curdrive = 0;
|
||||
fdd_period = 32;
|
||||
timer_add(fdd_poll_0, &(fdd_poll_time[0]), &(motoron[0]), NULL);
|
||||
timer_add(fdd_poll_1, &(fdd_poll_time[1]), &(motoron[1]), NULL);
|
||||
timer_add(fdd_poll_2, &(fdd_poll_time[2]), &(motoron[2]), NULL);
|
||||
timer_add(fdd_poll_3, &(fdd_poll_time[3]), &(motoron[3]), NULL);
|
||||
}
|
||||
|
||||
int oldtrack[FDD_NUM] = {0, 0, 0, 0};
|
||||
|
||||
void fdd_readsector(int drive, int sector, int track, int side, int density, int sector_size)
|
||||
{
|
||||
if (drives[drive].readsector)
|
||||
drives[drive].readsector(drive, sector, track, side, density, sector_size);
|
||||
else
|
||||
fdd_notfound = 1000;
|
||||
}
|
||||
|
||||
void fdd_writesector(int drive, int sector, int track, int side, int density, int sector_size)
|
||||
{
|
||||
if (drives[drive].writesector)
|
||||
drives[drive].writesector(drive, sector, track, side, density, sector_size);
|
||||
else
|
||||
fdd_notfound = 1000;
|
||||
}
|
||||
|
||||
void fdd_comparesector(int drive, int sector, int track, int side, int density, int sector_size)
|
||||
{
|
||||
if (drives[drive].comparesector)
|
||||
drives[drive].comparesector(drive, sector, track, side, density, sector_size);
|
||||
else
|
||||
fdd_notfound = 1000;
|
||||
}
|
||||
|
||||
void fdd_readaddress(int drive, int side, int density)
|
||||
{
|
||||
if (drives[drive].readaddress)
|
||||
drives[drive].readaddress(drive, side, density);
|
||||
}
|
||||
|
||||
void fdd_format(int drive, int side, int density, uint8_t fill)
|
||||
{
|
||||
if (drives[drive].format)
|
||||
drives[drive].format(drive, side, density, fill);
|
||||
else
|
||||
fdd_notfound = 1000;
|
||||
}
|
||||
|
||||
void fdd_stop(int drive)
|
||||
{
|
||||
if (drives[drive].stop)
|
||||
drives[drive].stop(drive);
|
||||
}
|
||||
|
||||
void fdd_set_fdc(void *fdc)
|
||||
{
|
||||
fdd_fdc = (fdc_t *) fdc;
|
||||
}
|
||||
|
||||
void fdd_init(void)
|
||||
{
|
||||
drives[0].poll = drives[1].poll = drives[2].poll = drives[3].poll = 0;
|
||||
drives[0].seek = drives[1].seek = drives[2].seek = drives[3].seek = 0;
|
||||
drives[0].readsector = drives[1].readsector = drives[2].readsector = drives[3].readsector = 0;
|
||||
fdd_reset();
|
||||
|
||||
img_init();
|
||||
d86f_init();
|
||||
td0_init();
|
||||
imd_init();
|
||||
|
||||
fdd_load(0, floppyfns[0]);
|
||||
fdd_load(1, floppyfns[1]);
|
||||
fdd_load(2, floppyfns[2]);
|
||||
fdd_load(3, floppyfns[3]);
|
||||
}
|
||||
|
||||
225
src/floppy/fdd.h
225
src/floppy/fdd.h
@@ -8,18 +8,19 @@
|
||||
*
|
||||
* Implementation of the floppy drive emulation.
|
||||
*
|
||||
* Version: @(#)fdd.h 1.0.3 2017/10/01
|
||||
* Version: @(#)fdd.h 1.0.4 2018/01/16
|
||||
*
|
||||
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
*
|
||||
* Copyright 2008-2017 Sarah Walker.
|
||||
* Copyright 2016,2017 Miran Grca.
|
||||
* Copyright 2008-2018 Sarah Walker.
|
||||
* Copyright 2016-2018 Miran Grca.
|
||||
*/
|
||||
#ifndef EMU_FDD_H
|
||||
# define EMU_FDD_H
|
||||
|
||||
|
||||
#define FDD_NUM 4
|
||||
#define SEEK_RECALIBRATE -999
|
||||
|
||||
|
||||
@@ -30,6 +31,7 @@ extern "C" {
|
||||
extern int fdd_swap;
|
||||
|
||||
|
||||
extern void fdd_do_seek(int drive, int track);
|
||||
extern void fdd_forced_seek(int drive, int track_diff);
|
||||
extern void fdd_seek(int drive, int track_diff);
|
||||
extern int fdd_track0(int drive);
|
||||
@@ -52,18 +54,225 @@ extern void fdd_set_type(int drive, int type);
|
||||
extern int fdd_get_type(int drive);
|
||||
|
||||
extern int fdd_get_flags(int drive);
|
||||
|
||||
extern void fdd_init(void);
|
||||
extern int fdd_get_densel(int drive);
|
||||
|
||||
extern void fdd_setswap(int swap);
|
||||
|
||||
extern char *fdd_getname(int type);
|
||||
|
||||
extern char *fdd_get_internal_name(int type);
|
||||
extern int fdd_get_from_internal_name(char *s);
|
||||
|
||||
extern int fdd_track(int drive);
|
||||
extern int fdd_current_track(int drive);
|
||||
|
||||
|
||||
typedef struct {
|
||||
void (*seek)(int drive, int track);
|
||||
void (*readsector)(int drive, int sector, int track, int side, int density, int sector_size);
|
||||
void (*writesector)(int drive, int sector, int track, int side, int density, int sector_size);
|
||||
void (*comparesector)(int drive, int sector, int track, int side, int density, int sector_size);
|
||||
void (*readaddress)(int drive, int side, int density);
|
||||
void (*format)(int drive, int side, int density, uint8_t fill);
|
||||
int (*hole)(int drive);
|
||||
double (*byteperiod)(int drive);
|
||||
void (*stop)(int drive);
|
||||
void (*poll)(int drive);
|
||||
} DRIVE;
|
||||
|
||||
|
||||
extern DRIVE drives[FDD_NUM];
|
||||
extern wchar_t floppyfns[FDD_NUM][512];
|
||||
extern int driveempty[FDD_NUM];
|
||||
extern int64_t fdd_poll_time[FDD_NUM];
|
||||
extern int ui_writeprot[FDD_NUM];
|
||||
|
||||
extern int curdrive;
|
||||
|
||||
extern int fdd_time;
|
||||
extern int64_t floppytime;
|
||||
|
||||
|
||||
extern void fdd_load(int drive, wchar_t *fn);
|
||||
extern void fdd_new(int drive, char *fn);
|
||||
extern void fdd_close(int drive);
|
||||
extern void fdd_init(void);
|
||||
extern void fdd_reset(void);
|
||||
extern void fdd_poll(int drive);
|
||||
extern void fdd_poll_0(void* priv);
|
||||
extern void fdd_poll_1(void* priv);
|
||||
extern void fdd_poll_2(void* priv);
|
||||
extern void fdd_poll_3(void* priv);
|
||||
extern void fdd_seek(int drive, int track);
|
||||
extern void fdd_readsector(int drive, int sector, int track,
|
||||
int side, int density, int sector_size);
|
||||
extern void fdd_writesector(int drive, int sector, int track,
|
||||
int side, int density, int sector_size);
|
||||
extern void fdd_comparesector(int drive, int sector, int track,
|
||||
int side, int density, int sector_size);
|
||||
extern void fdd_readaddress(int drive, int side, int density);
|
||||
extern void fdd_format(int drive, int side, int density, uint8_t fill);
|
||||
extern int fdd_hole(int drive);
|
||||
extern double fdd_byteperiod(int drive);
|
||||
extern void fdd_stop(int drive);
|
||||
extern int fdd_empty(int drive);
|
||||
extern void fdd_set_rate(int drive, int drvden, int rate);
|
||||
|
||||
extern int motorspin;
|
||||
extern int64_t motoron[FDD_NUM];
|
||||
|
||||
extern int swwp;
|
||||
extern int disable_write;
|
||||
|
||||
extern int defaultwriteprot;
|
||||
|
||||
extern int writeprot[FDD_NUM], fwriteprot[FDD_NUM];
|
||||
extern int fdd_cur_track[FDD_NUM];
|
||||
extern int fdd_changed[FDD_NUM];
|
||||
extern int drive_empty[FDD_NUM];
|
||||
extern int drive_type[FDD_NUM];
|
||||
|
||||
/*Used in the Read A Track command. Only valid for fdd_readsector(). */
|
||||
#define SECTOR_FIRST -2
|
||||
#define SECTOR_NEXT -1
|
||||
|
||||
#if 0
|
||||
/* Bits 0-3 define byte type, bit 5 defines whether it is a per-track (0) or per-sector (1) byte, if bit 7 is set, the byte is the index hole. */
|
||||
#define BYTE_GAP0 0x00
|
||||
#define BYTE_GAP1 0x10
|
||||
#define BYTE_GAP4 0x20
|
||||
#define BYTE_GAP2 0x40
|
||||
#define BYTE_GAP3 0x50
|
||||
#define BYTE_I_SYNC 0x01
|
||||
#define BYTE_ID_SYNC 0x41
|
||||
#define BYTE_DATA_SYNC 0x51
|
||||
#define BYTE_IAM_SYNC 0x02
|
||||
#define BYTE_IDAM_SYNC 0x42
|
||||
#define BYTE_DATAAM_SYNC 0x52
|
||||
#define BYTE_IAM 0x03
|
||||
#define BYTE_IDAM 0x43
|
||||
#define BYTE_DATAAM 0x53
|
||||
#define BYTE_ID 0x44
|
||||
#define BYTE_DATA 0x54
|
||||
#define BYTE_ID_CRC 0x45
|
||||
#define BYTE_DATA_CRC 0x55
|
||||
|
||||
#define BYTE_IS_FUZZY 0x80
|
||||
#define BYTE_INDEX_HOLE 0x80 /* 1 = index hole, 0 = regular byte */
|
||||
#define BYTE_IS_SECTOR 0x40 /* 1 = per-sector, 0 = per-track */
|
||||
#define BYTE_IS_POST_TRACK 0x20 /* 1 = after all sectors, 0 = before or during all sectors */
|
||||
#define BYTE_IS_DATA 0x10 /* 1 = data, 0 = id */
|
||||
#define BYTE_TYPE 0x0F /* 5 = crc, 4 = data, 3 = address mark, 2 = address mark sync, 1 = sync, 0 = gap */
|
||||
|
||||
#define BYTE_TYPE_GAP 0x00
|
||||
#define BYTE_TYPE_SYNC 0x01
|
||||
#define BYTE_TYPE_AM_SYNC 0x02
|
||||
#define BYTE_TYPE_AM 0x03
|
||||
#define BYTE_TYPE_DATA 0x04
|
||||
#define BYTE_TYPE_CRC 0x05
|
||||
#endif
|
||||
|
||||
typedef union {
|
||||
uint16_t word;
|
||||
uint8_t bytes[2];
|
||||
} crc_t;
|
||||
|
||||
void fdd_calccrc(uint8_t byte, crc_t *crc_var);
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint16_t (*disk_flags)(int drive);
|
||||
uint16_t (*side_flags)(int drive);
|
||||
void (*writeback)(int drive);
|
||||
void (*set_sector)(int drive, int side, uint8_t c, uint8_t h, uint8_t r, uint8_t n);
|
||||
uint8_t (*read_data)(int drive, int side, uint16_t pos);
|
||||
void (*write_data)(int drive, int side, uint16_t pos, uint8_t data);
|
||||
int (*format_conditions)(int drive);
|
||||
int32_t (*extra_bit_cells)(int drive, int side);
|
||||
uint16_t* (*encoded_data)(int drive, int side);
|
||||
void (*read_revolution)(int drive);
|
||||
uint32_t (*index_hole_pos)(int drive, int side);
|
||||
uint32_t (*get_raw_size)(int drive, int side);
|
||||
uint8_t check_crc;
|
||||
} d86f_handler_t;
|
||||
|
||||
d86f_handler_t d86f_handler[FDD_NUM];
|
||||
|
||||
void d86f_common_handlers(int drive);
|
||||
|
||||
int d86f_is_40_track(int drive);
|
||||
|
||||
void d86f_reset_index_hole_pos(int drive, int side);
|
||||
|
||||
uint16_t d86f_prepare_pretrack(int drive, int side, int iso);
|
||||
uint16_t d86f_prepare_sector(int drive, int side, int prev_pos, uint8_t *id_buf, uint8_t *data_buf, int data_len, int gap2, int gap3, int deleted, int bad_crc);
|
||||
|
||||
extern int gap3_sizes[5][8][48];
|
||||
|
||||
void null_writeback(int drive);
|
||||
void null_write_data(int drive, int side, uint16_t pos, uint8_t data);
|
||||
int null_format_conditions(int drive);
|
||||
void d86f_unregister(int drive);
|
||||
|
||||
extern uint8_t dmf_r[21];
|
||||
extern uint8_t xdf_physical_sectors[2][2];
|
||||
extern uint8_t xdf_gap3_sizes[2][2];
|
||||
extern uint16_t xdf_trackx_spos[2][8];
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint8_t h;
|
||||
uint8_t r;
|
||||
} xdf_id_t;
|
||||
|
||||
typedef union
|
||||
{
|
||||
uint16_t word;
|
||||
xdf_id_t id;
|
||||
} xdf_sector_t;
|
||||
|
||||
extern xdf_sector_t xdf_img_layout[2][2][46];
|
||||
extern xdf_sector_t xdf_disk_layout[2][2][38];
|
||||
|
||||
uint32_t td0_get_raw_tsize(int side_flags, int slower_rpm);
|
||||
|
||||
void d86f_set_track_pos(int drive, uint32_t track_pos);
|
||||
|
||||
int32_t null_extra_bit_cells(int drive, int side);
|
||||
uint16_t* common_encoded_data(int drive, int side);
|
||||
|
||||
void common_read_revolution(int drive);
|
||||
void null_set_sector(int drive, int side, uint8_t c, uint8_t h, uint8_t r, uint8_t n);
|
||||
|
||||
uint32_t null_index_hole_pos(int drive, int side);
|
||||
|
||||
uint32_t common_get_raw_size(int drive, int side);
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint8_t c;
|
||||
uint8_t h;
|
||||
uint8_t r;
|
||||
uint8_t n;
|
||||
} sector_id_fields_t;
|
||||
|
||||
typedef union
|
||||
{
|
||||
uint32_t dword;
|
||||
uint8_t byte_array[4];
|
||||
sector_id_fields_t id;
|
||||
} sector_id_t;
|
||||
|
||||
void d86f_set_version(int drive, uint16_t version);
|
||||
|
||||
void d86f_initialize_last_sector_id(int drive, int c, int h, int r, int n);
|
||||
void d86f_zero_bit_field(int drive, int side);
|
||||
|
||||
void d86f_set_fdc(void *fdc);
|
||||
void fdi_set_fdc(void *fdc);
|
||||
void fdd_set_fdc(void *fdc);
|
||||
void imd_set_fdc(void *fdc);
|
||||
void img_set_fdc(void *fdc);
|
||||
|
||||
extern void d86f_set_cur_track(int drive, int track);
|
||||
extern void d86f_zero_track(int drive);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
@@ -10,10 +10,10 @@
|
||||
* data in the form of FM/MFM-encoded transitions) which also
|
||||
* forms the core of the emulator's floppy disk emulation.
|
||||
*
|
||||
* Version: @(#)floppy_86f.c 1.0.12 2017/11/24
|
||||
* Version: @(#)fdd_86f.c 1.0.13 2018/01/16
|
||||
*
|
||||
* Author: Miran Grca, <mgrca8@gmail.com>
|
||||
* Copyright 2016,2017 Miran Grca.
|
||||
* Copyright 2016-2018 Miran Grca.
|
||||
*/
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
@@ -30,10 +30,9 @@
|
||||
#include "../random.h"
|
||||
#include "../plat.h"
|
||||
#include "../ui.h"
|
||||
#include "floppy.h"
|
||||
#include "fdc.h"
|
||||
#include "fdd.h"
|
||||
#include "floppy_86f.h"
|
||||
#include "fdc.h"
|
||||
#include "fdd_86f.h"
|
||||
|
||||
|
||||
#define CHUNK 16384
|
||||
@@ -191,6 +190,10 @@ typedef union {
|
||||
Bits 10, 9 Zone type (3 = Commodore 64 zoned, 2 = Apple zoned, 1 = Pre-Apple zoned #2, 0 = Pre-Apple zoned #1)
|
||||
Bit 11 Data and surface bits are stored in reverse byte endianness */
|
||||
|
||||
|
||||
static fdc_t *d86f_fdc;
|
||||
|
||||
|
||||
#pragma pack(push,1)
|
||||
struct
|
||||
{
|
||||
@@ -618,7 +621,7 @@ int d86f_valid_bit_rate(int drive)
|
||||
{
|
||||
int rate = 0;
|
||||
int hole = 0;
|
||||
rate = fdc_get_bit_rate();
|
||||
rate = fdc_get_bit_rate(d86f_fdc);
|
||||
hole = (d86f_handler[drive].disk_flags(drive) & 6) >> 1;
|
||||
switch (hole)
|
||||
{
|
||||
@@ -689,9 +692,9 @@ uint32_t d86f_get_data_len(int drive)
|
||||
}
|
||||
else
|
||||
{
|
||||
if (fdc_get_dtl() < 128)
|
||||
if (fdc_get_dtl(d86f_fdc) < 128)
|
||||
{
|
||||
return fdc_get_dtl();
|
||||
return fdc_get_dtl(d86f_fdc);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -813,8 +816,8 @@ int d86f_can_format(int drive)
|
||||
{
|
||||
int temp;
|
||||
temp = !writeprot[drive];
|
||||
temp = temp && !swwp;
|
||||
temp = temp && fdd_can_read_medium(real_drive(drive));
|
||||
temp = temp && !fdc_get_swwp(d86f_fdc);
|
||||
temp = temp && fdd_can_read_medium(real_drive(d86f_fdc, drive));
|
||||
temp = temp && d86f_handler[drive].format_conditions(drive); /* Allows proxied formats to add their own extra conditions to formatting. */
|
||||
temp = temp && !d86f_wrong_densel(drive);
|
||||
return temp;
|
||||
@@ -893,16 +896,16 @@ static int d86f_get_bitcell_period(int drive)
|
||||
if (!mfm) rate /= 2.0;
|
||||
size = (size * 250.0) / rate;
|
||||
size = (size * 300.0) / rpm;
|
||||
size = (size * fdd_getrpm(real_drive(drive))) / 300.0;
|
||||
size = (size * fdd_getrpm(real_drive(d86f_fdc, drive))) / 300.0;
|
||||
return (int) size;
|
||||
}
|
||||
|
||||
int d86f_can_read_address(int drive)
|
||||
{
|
||||
int temp = 0;
|
||||
temp = (fdc_get_bitcell_period() == d86f_get_bitcell_period(drive));
|
||||
temp = temp && fdd_can_read_medium(real_drive(drive));
|
||||
temp = temp && (fdc_is_mfm() == d86f_is_mfm(drive));
|
||||
temp = (fdc_get_bitcell_period(d86f_fdc) == d86f_get_bitcell_period(drive));
|
||||
temp = temp && fdd_can_read_medium(real_drive(d86f_fdc, drive));
|
||||
temp = temp && (fdc_is_mfm(d86f_fdc) == d86f_is_mfm(drive));
|
||||
temp = temp && (d86f_get_encoding(drive) <= 1);
|
||||
return temp;
|
||||
}
|
||||
@@ -988,6 +991,9 @@ void d86f_put_bit(int drive, int side, int bit)
|
||||
uint16_t current_bit;
|
||||
uint16_t surface_bit;
|
||||
|
||||
if (fdc_get_diswr(d86f_fdc))
|
||||
return;
|
||||
|
||||
track_word = d86f[drive].track_pos >> 4;
|
||||
/* We need to make sure we read the bits from MSB to LSB. */
|
||||
track_bit = 15 - (d86f[drive].track_pos & 15);
|
||||
@@ -1096,14 +1102,14 @@ static uint8_t decodefm(int drive, uint16_t dat)
|
||||
return temp;
|
||||
}
|
||||
|
||||
void floppy_calccrc(uint8_t byte, crc_t *crc_var)
|
||||
void fdd_calccrc(uint8_t byte, crc_t *crc_var)
|
||||
{
|
||||
crc_var->word = (crc_var->word << 8) ^ CRCTable[(crc_var->word >> 8)^byte];
|
||||
}
|
||||
|
||||
static void d86f_calccrc(int drive, uint8_t byte)
|
||||
{
|
||||
floppy_calccrc(byte, &(d86f[drive].calc_crc));
|
||||
fdd_calccrc(byte, &(d86f[drive].calc_crc));
|
||||
}
|
||||
|
||||
int d86f_word_is_aligned(int drive, int side, uint32_t base_pos)
|
||||
@@ -1139,7 +1145,7 @@ void d86f_find_address_mark_fm(int drive, int side, find_t *find, uint16_t req_a
|
||||
if (d86f[drive].last_word[side] == req_am)
|
||||
{
|
||||
d86f[drive].calc_crc.word = 0xFFFF;
|
||||
floppy_calccrc(decodefm(drive, d86f[drive].last_word[side]), &(d86f[drive].calc_crc));
|
||||
fdd_calccrc(decodefm(drive, d86f[drive].last_word[side]), &(d86f[drive].calc_crc));
|
||||
find->sync_marks = find->bits_obtained = find->bytes_obtained = 0;
|
||||
find->sync_pos = 0xFFFFFFFF;
|
||||
d86f[drive].preceding_bit[side] = d86f[drive].last_word[side] & 1;
|
||||
@@ -1150,7 +1156,7 @@ void d86f_find_address_mark_fm(int drive, int side, find_t *find, uint16_t req_a
|
||||
if ((ignore_other_am & 2) && (d86f[drive].last_word[side] == other_am))
|
||||
{
|
||||
d86f[drive].calc_crc.word = 0xFFFF;
|
||||
floppy_calccrc(decodefm(drive, d86f[drive].last_word[side]), &(d86f[drive].calc_crc));
|
||||
fdd_calccrc(decodefm(drive, d86f[drive].last_word[side]), &(d86f[drive].calc_crc));
|
||||
find->sync_marks = find->bits_obtained = find->bytes_obtained = 0;
|
||||
find->sync_pos = 0xFFFFFFFF;
|
||||
if (ignore_other_am & 1)
|
||||
@@ -1161,7 +1167,7 @@ void d86f_find_address_mark_fm(int drive, int side, find_t *find, uint16_t req_a
|
||||
else
|
||||
{
|
||||
/* Not skip mode, process the sector anyway. */
|
||||
fdc_set_wrong_am();
|
||||
fdc_set_wrong_am(d86f_fdc);
|
||||
d86f[drive].preceding_bit[side] = d86f[drive].last_word[side] & 1;
|
||||
d86f[drive].state++;
|
||||
}
|
||||
@@ -1212,7 +1218,7 @@ void d86f_find_address_mark_mfm(int drive, int side, find_t *find, uint16_t req_
|
||||
if (d86f_word_is_aligned(drive, side, find->sync_pos))
|
||||
{
|
||||
d86f[drive].calc_crc.word = 0xCDB4;
|
||||
floppy_calccrc(decodefm(drive, d86f[drive].last_word[side]), &(d86f[drive].calc_crc));
|
||||
fdd_calccrc(decodefm(drive, d86f[drive].last_word[side]), &(d86f[drive].calc_crc));
|
||||
find->sync_marks = find->bits_obtained = find->bytes_obtained = 0;
|
||||
find->sync_pos = 0xFFFFFFFF;
|
||||
d86f[drive].preceding_bit[side] = d86f[drive].last_word[side] & 1;
|
||||
@@ -1226,7 +1232,7 @@ void d86f_find_address_mark_mfm(int drive, int side, find_t *find, uint16_t req_
|
||||
if (d86f_word_is_aligned(drive, side, find->sync_pos))
|
||||
{
|
||||
d86f[drive].calc_crc.word = 0xCDB4;
|
||||
floppy_calccrc(decodefm(drive, d86f[drive].last_word[side]), &(d86f[drive].calc_crc));
|
||||
fdd_calccrc(decodefm(drive, d86f[drive].last_word[side]), &(d86f[drive].calc_crc));
|
||||
find->sync_marks = find->bits_obtained = find->bytes_obtained = 0;
|
||||
find->sync_pos = 0xFFFFFFFF;
|
||||
if (ignore_other_am & 1)
|
||||
@@ -1237,7 +1243,7 @@ void d86f_find_address_mark_mfm(int drive, int side, find_t *find, uint16_t req_
|
||||
else
|
||||
{
|
||||
/* Not skip mode, process the sector anyway. */
|
||||
fdc_set_wrong_am();
|
||||
fdc_set_wrong_am(d86f_fdc);
|
||||
d86f[drive].preceding_bit[side] = d86f[drive].last_word[side] & 1;
|
||||
d86f[drive].state++;
|
||||
}
|
||||
@@ -1296,7 +1302,7 @@ void d86f_read_sector_id(int drive, int side, int match)
|
||||
if (d86f[drive].id_find.bytes_obtained < 4)
|
||||
{
|
||||
d86f[drive].last_sector.byte_array[d86f[drive].id_find.bytes_obtained] = decodefm(drive, d86f[drive].last_word[side]);
|
||||
floppy_calccrc(d86f[drive].last_sector.byte_array[d86f[drive].id_find.bytes_obtained], &(d86f[drive].calc_crc));
|
||||
fdd_calccrc(d86f[drive].last_sector.byte_array[d86f[drive].id_find.bytes_obtained], &(d86f[drive].calc_crc));
|
||||
}
|
||||
else if ((d86f[drive].id_find.bytes_obtained >= 4) && (d86f[drive].id_find.bytes_obtained < 6))
|
||||
{
|
||||
@@ -1315,8 +1321,8 @@ void d86f_read_sector_id(int drive, int side, int match)
|
||||
{
|
||||
d86f[drive].error_condition = 0;
|
||||
d86f[drive].state = STATE_IDLE;
|
||||
fdc_finishread();
|
||||
fdc_headercrcerror();
|
||||
fdc_finishread(d86f_fdc);
|
||||
fdc_headercrcerror(d86f_fdc);
|
||||
}
|
||||
else if (d86f[drive].state == STATE_0A_READ_ID)
|
||||
{
|
||||
@@ -1332,7 +1338,7 @@ void d86f_read_sector_id(int drive, int side, int match)
|
||||
{
|
||||
/* CRC is valid and this is a read sector ID command. */
|
||||
d86f[drive].id_find.sync_marks = d86f[drive].id_find.bits_obtained = d86f[drive].id_find.bytes_obtained = d86f[drive].error_condition = 0;
|
||||
fdc_sectorid(d86f[drive].last_sector.id.c, d86f[drive].last_sector.id.h, d86f[drive].last_sector.id.r, d86f[drive].last_sector.id.n, 0, 0);
|
||||
fdc_sectorid(d86f_fdc, d86f[drive].last_sector.id.c, d86f[drive].last_sector.id.h, d86f[drive].last_sector.id.r, d86f[drive].last_sector.id.n, 0, 0);
|
||||
d86f[drive].state = STATE_IDLE;
|
||||
}
|
||||
else
|
||||
@@ -1347,11 +1353,11 @@ void d86f_read_sector_id(int drive, int side, int match)
|
||||
{
|
||||
/* READ TRACK command, we need some special handling here. */
|
||||
/* Code corrected: Only the C, H, and N portions of the sector ID are compared, the R portion (the sector number) is ignored. */
|
||||
if ((d86f[drive].last_sector.id.c != fdc_get_read_track_sector().id.c) || (d86f[drive].last_sector.id.h != fdc_get_read_track_sector().id.h) || (d86f[drive].last_sector.id.n != fdc_get_read_track_sector().id.n))
|
||||
if ((d86f[drive].last_sector.id.c != fdc_get_read_track_sector(d86f_fdc).id.c) || (d86f[drive].last_sector.id.h != fdc_get_read_track_sector(d86f_fdc).id.h) || (d86f[drive].last_sector.id.n != fdc_get_read_track_sector(d86f_fdc).id.n))
|
||||
{
|
||||
d86f[drive].error_condition |= 4; /* Mark that the sector ID is not the one expected by the FDC. */
|
||||
/* Make sure we use the sector size from the FDC. */
|
||||
d86f[drive].last_sector.id.n = fdc_get_read_track_sector().id.n;
|
||||
d86f[drive].last_sector.id.n = fdc_get_read_track_sector(d86f_fdc).id.n;
|
||||
}
|
||||
/* If the two ID's are identical, then we do not need to do anything regarding the sector size. */
|
||||
}
|
||||
@@ -1389,7 +1395,7 @@ uint8_t d86f_get_data(int drive, int base)
|
||||
|
||||
if (d86f[drive].data_find.bytes_obtained < (d86f_get_data_len(drive) + base))
|
||||
{
|
||||
data = fdc_getdata(d86f[drive].data_find.bytes_obtained == (d86f_get_data_len(drive) + base - 1));
|
||||
data = fdc_getdata(d86f_fdc, d86f[drive].data_find.bytes_obtained == (d86f_get_data_len(drive) + base - 1));
|
||||
if ((data & DMA_OVER) || (data == -1))
|
||||
{
|
||||
d86f[drive].dma_over++;
|
||||
@@ -1413,7 +1419,7 @@ uint8_t d86f_get_data(int drive, int base)
|
||||
|
||||
void d86f_compare_byte(int drive, uint8_t received_byte, uint8_t disk_byte)
|
||||
{
|
||||
switch(fdc_get_compare_condition())
|
||||
switch(fdc_get_compare_condition(d86f_fdc))
|
||||
{
|
||||
case 0: /* SCAN EQUAL */
|
||||
if ((received_byte == disk_byte) || (received_byte == 0xFF))
|
||||
@@ -1467,7 +1473,7 @@ void d86f_read_sector_data(int drive, int side)
|
||||
{
|
||||
if (d86f[drive].state != STATE_16_VERIFY_DATA)
|
||||
{
|
||||
read_status = fdc_data(data);
|
||||
read_status = fdc_data(d86f_fdc, data);
|
||||
if (read_status == -1)
|
||||
{
|
||||
d86f[drive].dma_over++;
|
||||
@@ -1475,7 +1481,7 @@ void d86f_read_sector_data(int drive, int side)
|
||||
}
|
||||
}
|
||||
}
|
||||
floppy_calccrc(data, &(d86f[drive].calc_crc));
|
||||
fdd_calccrc(data, &(d86f[drive].calc_crc));
|
||||
}
|
||||
else if (d86f[drive].data_find.bytes_obtained < crc_pos)
|
||||
{
|
||||
@@ -1483,7 +1489,7 @@ void d86f_read_sector_data(int drive, int side)
|
||||
}
|
||||
d86f[drive].data_find.bytes_obtained++;
|
||||
|
||||
if (d86f[drive].data_find.bytes_obtained == (crc_pos + fdc_get_gap()))
|
||||
if (d86f[drive].data_find.bytes_obtained == (crc_pos + fdc_get_gap(d86f_fdc)))
|
||||
{
|
||||
/* We've got the data. */
|
||||
if (d86f[drive].dma_over > 1)
|
||||
@@ -1491,8 +1497,8 @@ void d86f_read_sector_data(int drive, int side)
|
||||
d86f[drive].data_find.sync_marks = d86f[drive].data_find.bits_obtained = d86f[drive].data_find.bytes_obtained = 0;
|
||||
d86f[drive].error_condition = 0;
|
||||
d86f[drive].state = STATE_IDLE;
|
||||
fdc_finishread();
|
||||
fdc_overrun();
|
||||
fdc_finishread(d86f_fdc);
|
||||
fdc_overrun(d86f_fdc);
|
||||
|
||||
d86f_get_bit(drive, side);
|
||||
|
||||
@@ -1506,15 +1512,15 @@ void d86f_read_sector_data(int drive, int side)
|
||||
d86f[drive].data_find.sync_marks = d86f[drive].data_find.bits_obtained = d86f[drive].data_find.bytes_obtained = 0;
|
||||
d86f[drive].error_condition = 0;
|
||||
d86f[drive].state = STATE_IDLE;
|
||||
fdc_finishread();
|
||||
fdc_datacrcerror();
|
||||
fdc_finishread(d86f_fdc);
|
||||
fdc_datacrcerror(d86f_fdc);
|
||||
}
|
||||
else if ((d86f[drive].calc_crc.word != d86f[drive].track_crc.word) && (d86f[drive].state == STATE_02_READ_DATA))
|
||||
{
|
||||
d86f[drive].data_find.sync_marks = d86f[drive].data_find.bits_obtained = d86f[drive].data_find.bytes_obtained = 0;
|
||||
d86f[drive].error_condition |= 2; /* Mark that there was a data error. */
|
||||
d86f[drive].state = STATE_IDLE;
|
||||
fdc_track_finishread(d86f[drive].error_condition);
|
||||
fdc_track_finishread(d86f_fdc, d86f[drive].error_condition);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1524,12 +1530,12 @@ void d86f_read_sector_data(int drive, int side)
|
||||
if (d86f[drive].state == STATE_11_SCAN_DATA)
|
||||
{
|
||||
d86f[drive].state = STATE_IDLE;
|
||||
fdc_sector_finishcompare((d86f[drive].satisfying_bytes == ((128 << ((uint32_t) d86f[drive].last_sector.id.n)) - 1)) ? 1 : 0);
|
||||
fdc_sector_finishcompare(d86f_fdc, (d86f[drive].satisfying_bytes == ((128 << ((uint32_t) d86f[drive].last_sector.id.n)) - 1)) ? 1 : 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
d86f[drive].state = STATE_IDLE;
|
||||
fdc_sector_finishread();
|
||||
fdc_sector_finishread(d86f_fdc);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1563,7 +1569,8 @@ void d86f_write_sector_data(int drive, int side, int mfm, uint16_t am)
|
||||
{
|
||||
/* We're in the data field of the sector, read byte from FDC and request new byte. */
|
||||
d86f[drive].current_byte[side] = d86f_get_data(drive, 1);
|
||||
d86f_handler[drive].write_data(drive, side, d86f[drive].data_find.bytes_obtained - 1, d86f[drive].current_byte[side]);
|
||||
if (!fdc_get_diswr(d86f_fdc))
|
||||
d86f_handler[drive].write_data(drive, side, d86f[drive].data_find.bytes_obtained - 1, d86f[drive].current_byte[side]);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1596,11 +1603,11 @@ void d86f_write_sector_data(int drive, int side, int mfm, uint16_t am)
|
||||
/* This is a data byte, so CRC it. */
|
||||
if (!d86f[drive].data_find.bytes_obtained)
|
||||
{
|
||||
floppy_calccrc(decodefm(drive, am), &(d86f[drive].calc_crc));
|
||||
fdd_calccrc(decodefm(drive, am), &(d86f[drive].calc_crc));
|
||||
}
|
||||
else
|
||||
{
|
||||
floppy_calccrc(d86f[drive].current_byte[side], &(d86f[drive].calc_crc));
|
||||
fdd_calccrc(d86f[drive].current_byte[side], &(d86f[drive].calc_crc));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1648,15 +1655,15 @@ void d86f_write_sector_data(int drive, int side, int mfm, uint16_t am)
|
||||
{
|
||||
d86f[drive].data_find.bytes_obtained++;
|
||||
|
||||
if (d86f[drive].data_find.bytes_obtained == (crc_pos + fdc_get_gap()))
|
||||
if (d86f[drive].data_find.bytes_obtained == (crc_pos + fdc_get_gap(d86f_fdc)))
|
||||
{
|
||||
if (d86f[drive].dma_over > 1)
|
||||
{
|
||||
d86f[drive].data_find.sync_marks = d86f[drive].data_find.bits_obtained = d86f[drive].data_find.bytes_obtained = 0;
|
||||
d86f[drive].error_condition = 0;
|
||||
d86f[drive].state = STATE_IDLE;
|
||||
fdc_finishread();
|
||||
fdc_overrun();
|
||||
fdc_finishread(d86f_fdc);
|
||||
fdc_overrun(d86f_fdc);
|
||||
|
||||
d86f[drive].data_find.bits_obtained++;
|
||||
return;
|
||||
@@ -1667,7 +1674,7 @@ void d86f_write_sector_data(int drive, int side, int mfm, uint16_t am)
|
||||
d86f[drive].error_condition = 0;
|
||||
d86f[drive].state = STATE_IDLE;
|
||||
d86f_handler[drive].writeback(drive);
|
||||
fdc_sector_finishread();
|
||||
fdc_sector_finishread(d86f_fdc);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -1726,6 +1733,9 @@ void d86f_write_direct_common(int drive, int side, uint16_t byte, uint8_t type,
|
||||
uint16_t encoded_byte = 0, mask_data, mask_surface, mask_hole, mask_fuzzy;
|
||||
decoded_t dbyte, dpbyte;
|
||||
|
||||
if (fdc_get_diswr(d86f_fdc))
|
||||
return;
|
||||
|
||||
dbyte.byte = byte;
|
||||
dpbyte.byte = d86f[drive].preceding_bit[side];
|
||||
|
||||
@@ -1805,7 +1815,7 @@ void d86f_format_finish(int drive, int side, int mfm, uint16_t sc, uint16_t gap_
|
||||
|
||||
d86f[drive].error_condition = 0;
|
||||
d86f[drive].datac = 0;
|
||||
fdc_sector_finishread();
|
||||
fdc_sector_finishread(d86f_fdc);
|
||||
}
|
||||
|
||||
void d86f_format_turbo_finish(int drive, int side, int do_write)
|
||||
@@ -1819,7 +1829,7 @@ void d86f_format_turbo_finish(int drive, int side, int do_write)
|
||||
|
||||
d86f[drive].error_condition = 0;
|
||||
d86f[drive].datac = 0;
|
||||
fdc_sector_finishread();
|
||||
fdc_sector_finishread(d86f_fdc);
|
||||
}
|
||||
|
||||
void d86f_format_track(int drive, int side, int do_write)
|
||||
@@ -1845,11 +1855,11 @@ void d86f_format_track(int drive, int side, int do_write)
|
||||
am_len = mfm ? 4 : 1;
|
||||
gap_sizes[0] = mfm ? 80 : 40;
|
||||
gap_sizes[1] = mfm ? 50 : 26;
|
||||
gap_sizes[2] = fdc_get_gap2(real_drive(drive));
|
||||
gap_sizes[3] = fdc_get_gap();
|
||||
gap_sizes[2] = fdc_get_gap2(d86f_fdc, real_drive(d86f_fdc, drive));
|
||||
gap_sizes[3] = fdc_get_gap(d86f_fdc);
|
||||
sync_len = mfm ? 12 : 6;
|
||||
sc = fdc_get_format_sectors();
|
||||
dtl = 128 << fdc_get_format_n();
|
||||
sc = fdc_get_format_sectors(d86f_fdc);
|
||||
dtl = 128 << fdc_get_format_n(d86f_fdc);
|
||||
gap_fill = mfm ? 0x4E : 0xFF;
|
||||
|
||||
switch(d86f[drive].format_state)
|
||||
@@ -1866,7 +1876,7 @@ void d86f_format_track(int drive, int side, int do_write)
|
||||
max_len = sync_len;
|
||||
if (d86f[drive].datac <= 3)
|
||||
{
|
||||
data = fdc_getdata(0);
|
||||
data = fdc_getdata(d86f_fdc, 0);
|
||||
if (data != -1)
|
||||
{
|
||||
data &= 0xff;
|
||||
@@ -1878,7 +1888,7 @@ void d86f_format_track(int drive, int side, int do_write)
|
||||
d86f[drive].format_sector_id.byte_array[d86f[drive].datac] = data & 0xff;
|
||||
if (d86f[drive].datac == 3)
|
||||
{
|
||||
fdc_stop_id_request();
|
||||
fdc_stop_id_request(d86f_fdc);
|
||||
}
|
||||
}
|
||||
case FMT_PRETRK_SYNC:
|
||||
@@ -1990,7 +2000,7 @@ void d86f_format_track(int drive, int side, int do_write)
|
||||
switch (d86f[drive].format_state)
|
||||
{
|
||||
case FMT_SECTOR_ID_SYNC:
|
||||
fdc_request_next_sector_id();
|
||||
fdc_request_next_sector_id(d86f_fdc);
|
||||
break;
|
||||
case FMT_SECTOR_IDAM:
|
||||
case FMT_SECTOR_DATAAM:
|
||||
@@ -2007,7 +2017,7 @@ void d86f_format_track(int drive, int side, int do_write)
|
||||
{
|
||||
/* Sector within allotted amount, change state to SECTOR_ID_SYNC. */
|
||||
d86f[drive].format_state = FMT_SECTOR_ID_SYNC;
|
||||
fdc_request_next_sector_id();
|
||||
fdc_request_next_sector_id(d86f_fdc);
|
||||
break;
|
||||
}
|
||||
else
|
||||
@@ -2060,7 +2070,7 @@ void d86f_turbo_read(int drive, int side)
|
||||
{
|
||||
if (d86f[drive].state != STATE_16_VERIFY_DATA)
|
||||
{
|
||||
read_status = fdc_data(dat);
|
||||
read_status = fdc_data(d86f_fdc, dat);
|
||||
if (read_status == -1)
|
||||
{
|
||||
d86f[drive].dma_over++;
|
||||
@@ -2074,8 +2084,8 @@ void d86f_turbo_read(int drive, int side)
|
||||
d86f[drive].data_find.sync_marks = d86f[drive].data_find.bits_obtained = d86f[drive].data_find.bytes_obtained = 0;
|
||||
d86f[drive].error_condition = 0;
|
||||
d86f[drive].state = STATE_IDLE;
|
||||
fdc_finishread();
|
||||
fdc_overrun();
|
||||
fdc_finishread(d86f_fdc);
|
||||
fdc_overrun(d86f_fdc);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -2087,12 +2097,12 @@ void d86f_turbo_read(int drive, int side)
|
||||
if (d86f[drive].state == STATE_11_SCAN_DATA)
|
||||
{
|
||||
d86f[drive].state = STATE_IDLE;
|
||||
fdc_sector_finishcompare((d86f[drive].satisfying_bytes == ((128 << ((uint32_t) d86f[drive].last_sector.id.n)) - 1)) ? 1 : 0);
|
||||
fdc_sector_finishcompare(d86f_fdc, (d86f[drive].satisfying_bytes == ((128 << ((uint32_t) d86f[drive].last_sector.id.n)) - 1)) ? 1 : 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
d86f[drive].state = STATE_IDLE;
|
||||
fdc_sector_finishread();
|
||||
fdc_sector_finishread(d86f_fdc);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2113,7 +2123,7 @@ void d86f_turbo_write(int drive, int side)
|
||||
d86f[drive].error_condition = 0;
|
||||
d86f[drive].state = STATE_IDLE;
|
||||
d86f_handler[drive].writeback(drive);
|
||||
fdc_sector_finishread();
|
||||
fdc_sector_finishread(d86f_fdc);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -2126,12 +2136,12 @@ void d86f_turbo_format(int drive, int side, int nop)
|
||||
uint16_t sc = 0;
|
||||
uint16_t dtl = 0;
|
||||
|
||||
sc = fdc_get_format_sectors();
|
||||
dtl = 128 << fdc_get_format_n();
|
||||
sc = fdc_get_format_sectors(d86f_fdc);
|
||||
dtl = 128 << fdc_get_format_n(d86f_fdc);
|
||||
|
||||
if (d86f[drive].datac <= 3)
|
||||
{
|
||||
dat = fdc_getdata(0);
|
||||
dat = fdc_getdata(d86f_fdc, 0);
|
||||
if (dat != -1)
|
||||
{
|
||||
dat &= 0xff;
|
||||
@@ -2143,7 +2153,7 @@ void d86f_turbo_format(int drive, int side, int nop)
|
||||
d86f[drive].format_sector_id.byte_array[d86f[drive].datac] = dat & 0xff;
|
||||
if (d86f[drive].datac == 3)
|
||||
{
|
||||
fdc_stop_id_request();
|
||||
fdc_stop_id_request(d86f_fdc);
|
||||
d86f_handler[drive].set_sector(drive, side, d86f[drive].format_sector_id.id.c, d86f[drive].format_sector_id.id.h, d86f[drive].format_sector_id.id.r, d86f[drive].format_sector_id.id.n);
|
||||
}
|
||||
}
|
||||
@@ -2169,7 +2179,7 @@ void d86f_turbo_format(int drive, int side, int nop)
|
||||
if (d86f[drive].sector_count < sc)
|
||||
{
|
||||
/* Sector within allotted amount. */
|
||||
fdc_request_next_sector_id();
|
||||
fdc_request_next_sector_id(d86f_fdc);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -2185,13 +2195,8 @@ void d86f_turbo_poll(int drive, int side)
|
||||
{
|
||||
if (!d86f_can_read_address(drive))
|
||||
{
|
||||
/* if (fdc_get_bitcell_period() != d86f_get_bitcell_period(drive)) d86f_log("[%i, %i] Bitcell period mismatch (%i != %i)\n", drive, side, fdc_get_bitcell_period(), d86f_get_bitcell_period(drive));
|
||||
if (!fdd_can_read_medium(real_drive(drive))) d86f_log("[%i, %i] Drive can not read medium (hole = %01X)\n", drive, side, d86f_hole(drive));
|
||||
if (fdc_is_mfm() != d86f_is_mfm(drive)) d86f_log("[%i, %i] Encoding mismatch\n", drive, side);
|
||||
if (d86f_get_encoding(drive) > 1) d86f_log("[%i, %i] Image encoding (%s) not FM or MFM\n", drive, side, (d86f_get_encoding(drive) == 2) ? "M2FM" : "GCR"); */
|
||||
|
||||
d86f[drive].id_find.sync_marks = d86f[drive].id_find.bits_obtained = d86f[drive].id_find.bytes_obtained = d86f[drive].error_condition = 0;
|
||||
fdc_noidam();
|
||||
fdc_noidam(d86f_fdc);
|
||||
d86f[drive].state = STATE_IDLE;
|
||||
return;
|
||||
}
|
||||
@@ -2207,17 +2212,17 @@ void d86f_turbo_poll(int drive, int side)
|
||||
d86f[drive].state++;
|
||||
return;
|
||||
case STATE_02_FIND_ID:
|
||||
if (!(d86f[drive].sector_id_bit_field[side][fdc_get_read_track_sector().id.c][fdc_get_read_track_sector().id.h][fdc_get_read_track_sector().id.r] & (1 << fdc_get_read_track_sector().id.n)))
|
||||
if (!(d86f[drive].sector_id_bit_field[side][fdc_get_read_track_sector(d86f_fdc).id.c][fdc_get_read_track_sector(d86f_fdc).id.h][fdc_get_read_track_sector(d86f_fdc).id.r] & (1 << fdc_get_read_track_sector(d86f_fdc).id.n)))
|
||||
{
|
||||
d86f[drive].id_find.sync_marks = d86f[drive].id_find.bits_obtained = d86f[drive].id_find.bytes_obtained = d86f[drive].error_condition = 0;
|
||||
fdc_nosector();
|
||||
fdc_nosector(d86f_fdc);
|
||||
d86f[drive].state = STATE_IDLE;
|
||||
return;
|
||||
}
|
||||
d86f[drive].last_sector.id.c = fdc_get_read_track_sector().id.c;
|
||||
d86f[drive].last_sector.id.h = fdc_get_read_track_sector().id.h;
|
||||
d86f[drive].last_sector.id.r = fdc_get_read_track_sector().id.r;
|
||||
d86f[drive].last_sector.id.n = fdc_get_read_track_sector().id.n;
|
||||
d86f[drive].last_sector.id.c = fdc_get_read_track_sector(d86f_fdc).id.c;
|
||||
d86f[drive].last_sector.id.h = fdc_get_read_track_sector(d86f_fdc).id.h;
|
||||
d86f[drive].last_sector.id.r = fdc_get_read_track_sector(d86f_fdc).id.r;
|
||||
d86f[drive].last_sector.id.n = fdc_get_read_track_sector(d86f_fdc).id.n;
|
||||
d86f_handler[drive].set_sector(drive, side, d86f[drive].last_sector.id.c, d86f[drive].last_sector.id.h, d86f[drive].last_sector.id.r, d86f[drive].last_sector.id.n);
|
||||
d86f[drive].turbo_pos = 0;
|
||||
d86f[drive].state++;
|
||||
@@ -2231,7 +2236,7 @@ void d86f_turbo_poll(int drive, int side)
|
||||
if (!(d86f[drive].sector_id_bit_field[side][d86f[drive].req_sector.id.c][d86f[drive].req_sector.id.h][d86f[drive].req_sector.id.r] & (1 << d86f[drive].req_sector.id.n)))
|
||||
{
|
||||
d86f[drive].id_find.sync_marks = d86f[drive].id_find.bits_obtained = d86f[drive].id_find.bytes_obtained = d86f[drive].error_condition = 0;
|
||||
fdc_nosector();
|
||||
fdc_nosector(d86f_fdc);
|
||||
d86f[drive].state = STATE_IDLE;
|
||||
return;
|
||||
}
|
||||
@@ -2246,7 +2251,7 @@ void d86f_turbo_poll(int drive, int side)
|
||||
return;
|
||||
case STATE_0A_READ_ID:
|
||||
d86f[drive].id_find.sync_marks = d86f[drive].id_find.bits_obtained = d86f[drive].id_find.bytes_obtained = d86f[drive].error_condition = 0;
|
||||
fdc_sectorid(d86f[drive].last_sector.id.c, d86f[drive].last_sector.id.h, d86f[drive].last_sector.id.r, d86f[drive].last_sector.id.n, 0, 0);
|
||||
fdc_sectorid(d86f_fdc, d86f[drive].last_sector.id.c, d86f[drive].last_sector.id.h, d86f[drive].last_sector.id.r, d86f[drive].last_sector.id.n, 0, 0);
|
||||
d86f[drive].state = STATE_IDLE;
|
||||
break;
|
||||
case STATE_02_READ_ID:
|
||||
@@ -2302,7 +2307,7 @@ void d86f_poll(int drive)
|
||||
side = 0;
|
||||
}
|
||||
|
||||
mfm = fdc_is_mfm();
|
||||
mfm = fdc_is_mfm(d86f_fdc);
|
||||
|
||||
if ((d86f[drive].state & 0xF8) == 0xE8)
|
||||
{
|
||||
@@ -2322,10 +2327,6 @@ void d86f_poll(int drive)
|
||||
{
|
||||
if (!d86f_can_read_address(drive))
|
||||
{
|
||||
/* if (fdc_get_bitcell_period() != d86f_get_bitcell_period(drive)) d86f_log("[%i, %i] Bitcell period mismatch (%i != %i)\n", drive, side, fdc_get_bitcell_period(), d86f_get_bitcell_period(drive));
|
||||
if (!fdd_can_read_medium(real_drive(drive))) d86f_log("[%i, %i] Drive can not read medium (hole = %01X)\n", drive, side, d86f_hole(drive));
|
||||
if (fdc_is_mfm() != d86f_is_mfm(drive)) d86f_log("[%i, %i] Encoding mismatch\n", drive, side);
|
||||
if (d86f_get_encoding(drive) > 1) d86f_log("[%i, %i] Image encoding (%s) not FM or MFM\n", drive, side, (d86f_get_encoding(drive) == 2) ? "M2FM" : "GCR"); */
|
||||
|
||||
d86f[drive].state = STATE_SECTOR_NOT_FOUND;
|
||||
}
|
||||
@@ -2387,11 +2388,11 @@ void d86f_poll(int drive)
|
||||
case STATE_16_FIND_DATA:
|
||||
if (mfm)
|
||||
{
|
||||
d86f_find_address_mark_mfm(drive, side, &(d86f[drive].data_find), 0x5545, 0x554A, fdc_is_sk() | 2);
|
||||
d86f_find_address_mark_mfm(drive, side, &(d86f[drive].data_find), 0x5545, 0x554A, fdc_is_sk(d86f_fdc) | 2);
|
||||
}
|
||||
else
|
||||
{
|
||||
d86f_find_address_mark_fm(drive, side, &(d86f[drive].data_find), 0xF56F, 0xF56A, fdc_is_sk() | 2);
|
||||
d86f_find_address_mark_fm(drive, side, &(d86f[drive].data_find), 0xF56F, 0xF56A, fdc_is_sk(d86f_fdc) | 2);
|
||||
}
|
||||
break;
|
||||
case STATE_05_FIND_DATA:
|
||||
@@ -2408,11 +2409,11 @@ void d86f_poll(int drive)
|
||||
case STATE_0C_FIND_DATA:
|
||||
if (mfm)
|
||||
{
|
||||
d86f_find_address_mark_mfm(drive, side, &(d86f[drive].data_find), 0x554A, 0x5545, fdc_is_sk() | 2);
|
||||
d86f_find_address_mark_mfm(drive, side, &(d86f[drive].data_find), 0x554A, 0x5545, fdc_is_sk(d86f_fdc) | 2);
|
||||
}
|
||||
else
|
||||
{
|
||||
d86f_find_address_mark_fm(drive, side, &(d86f[drive].data_find), 0xF56A, 0xF56F, fdc_is_sk() | 2);
|
||||
d86f_find_address_mark_fm(drive, side, &(d86f[drive].data_find), 0xF56A, 0xF56F, fdc_is_sk(d86f_fdc) | 2);
|
||||
}
|
||||
break;
|
||||
case STATE_02_READ_DATA:
|
||||
@@ -2466,7 +2467,7 @@ void d86f_poll(int drive)
|
||||
if (d86f_wrong_densel(drive) && (d86f[drive].state != STATE_IDLE))
|
||||
{
|
||||
d86f[drive].state = STATE_IDLE;
|
||||
fdc_noidam();
|
||||
fdc_noidam(d86f_fdc);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -2477,7 +2478,7 @@ void d86f_poll(int drive)
|
||||
case STATE_0A_FIND_ID:
|
||||
case STATE_SECTOR_NOT_FOUND:
|
||||
d86f[drive].state = STATE_IDLE;
|
||||
fdc_noidam();
|
||||
fdc_noidam(d86f_fdc);
|
||||
break;
|
||||
case STATE_02_FIND_DATA:
|
||||
case STATE_06_FIND_DATA:
|
||||
@@ -2487,7 +2488,7 @@ void d86f_poll(int drive)
|
||||
case STATE_09_FIND_DATA:
|
||||
case STATE_0C_FIND_DATA:
|
||||
d86f[drive].state = STATE_IDLE;
|
||||
fdc_nodataam();
|
||||
fdc_nodataam(d86f_fdc);
|
||||
break;
|
||||
case STATE_02_SPIN_TO_INDEX:
|
||||
case STATE_02_READ_DATA:
|
||||
@@ -2509,21 +2510,21 @@ void d86f_poll(int drive)
|
||||
{
|
||||
if ((d86f[drive].error_condition & 0x18) == 0x08)
|
||||
{
|
||||
fdc_badcylinder();
|
||||
fdc_badcylinder(d86f_fdc);
|
||||
}
|
||||
if ((d86f[drive].error_condition & 0x10) == 0x10)
|
||||
{
|
||||
fdc_wrongcylinder();
|
||||
fdc_wrongcylinder(d86f_fdc);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
fdc_nosector();
|
||||
fdc_nosector(d86f_fdc);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
fdc_noidam();
|
||||
fdc_noidam(d86f_fdc);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -2543,7 +2544,7 @@ void d86f_poll(int drive)
|
||||
void d86f_poll()
|
||||
{
|
||||
int drive = 0;
|
||||
drive = fdc_get_drive();
|
||||
drive = fdc_get_drive(d86f_fdc);
|
||||
d86f_poll_per_drive(drive);
|
||||
}
|
||||
#endif
|
||||
@@ -2897,6 +2898,21 @@ void d86f_read_track(int drive, int track, int thin_track, int side, uint16_t *d
|
||||
}
|
||||
}
|
||||
|
||||
void d86f_zero_track(int drive)
|
||||
{
|
||||
int sides, side;
|
||||
sides = d86f_get_sides(drive);
|
||||
|
||||
for (side = 0; side < sides; side++)
|
||||
{
|
||||
if (d86f_has_surface_desc(drive))
|
||||
{
|
||||
memset(d86f[drive].track_surface_data[side], 0, 106096);
|
||||
}
|
||||
memset(d86f[drive].track_encoded_data[side], 0, 106096);
|
||||
}
|
||||
}
|
||||
|
||||
void d86f_seek(int drive, int track)
|
||||
{
|
||||
int sides;
|
||||
@@ -2921,14 +2937,7 @@ void d86f_seek(int drive, int track)
|
||||
}
|
||||
}
|
||||
|
||||
for (side = 0; side < sides; side++)
|
||||
{
|
||||
if (d86f_has_surface_desc(drive))
|
||||
{
|
||||
memset(d86f[drive].track_surface_data[side], 0, 106096);
|
||||
}
|
||||
memset(d86f[drive].track_encoded_data[side], 0, 106096);
|
||||
}
|
||||
d86f_zero_track(drive);
|
||||
|
||||
d86f[drive].cur_track = track;
|
||||
|
||||
@@ -2955,23 +2964,23 @@ void d86f_seek(int drive, int track)
|
||||
d86f[drive].state = STATE_IDLE;
|
||||
}
|
||||
|
||||
void d86f_write_track(int drive, int side, uint16_t *da0, uint16_t *sa0)
|
||||
void d86f_write_track(int drive, FILE **f, int side, uint16_t *da0, uint16_t *sa0)
|
||||
{
|
||||
fwrite(&(d86f[drive].side_flags[side]), 1, 2, d86f[drive].f);
|
||||
fwrite(&(d86f[drive].side_flags[side]), 1, 2, *f);
|
||||
|
||||
if (d86f_has_extra_bit_cells(drive))
|
||||
{
|
||||
fwrite(&(d86f[drive].extra_bit_cells[side]), 1, 4, d86f[drive].f);
|
||||
fwrite(&(d86f[drive].extra_bit_cells[side]), 1, 4, *f);
|
||||
}
|
||||
|
||||
fwrite(&(d86f[drive].index_hole_pos[side]), 1, 4, d86f[drive].f);
|
||||
fwrite(&(d86f[drive].index_hole_pos[side]), 1, 4, *f);
|
||||
|
||||
if (d86f_has_surface_desc(drive))
|
||||
{
|
||||
fwrite(sa0, 1, d86f_get_array_size(drive, side) << 1, d86f[drive].f);
|
||||
fwrite(sa0, 1, d86f_get_array_size(drive, side) << 1, *f);
|
||||
}
|
||||
|
||||
fwrite(da0, 1, d86f_get_array_size(drive, side) << 1, d86f[drive].f);
|
||||
fwrite(da0, 1, d86f_get_array_size(drive, side) << 1, *f);
|
||||
}
|
||||
|
||||
int d86f_get_track_table_size(int drive)
|
||||
@@ -2986,29 +2995,17 @@ int d86f_get_track_table_size(int drive)
|
||||
return temp;
|
||||
}
|
||||
|
||||
void d86f_writeback(int drive)
|
||||
void d86f_set_cur_track(int drive, int track)
|
||||
{
|
||||
uint8_t header[32];
|
||||
int sides, header_size;
|
||||
d86f[drive].cur_track = track;
|
||||
}
|
||||
|
||||
void d86f_write_tracks(int drive, FILE **f)
|
||||
{
|
||||
int sides;
|
||||
int side, thin_track;
|
||||
uint32_t len;
|
||||
int ret = 0;
|
||||
int logical_track = 0;
|
||||
FILE *cf;
|
||||
sides = d86f_get_sides(drive);
|
||||
header_size = d86f_header_size(drive);
|
||||
|
||||
if (!d86f[drive].f)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
/* First write the track offsets table. */
|
||||
fseek(d86f[drive].f, 0, SEEK_SET);
|
||||
fread(header, 1, header_size, d86f[drive].f);
|
||||
|
||||
fseek(d86f[drive].f, 8, SEEK_SET);
|
||||
fwrite(d86f[drive].track_offset, 1, d86f_get_track_table_size(drive), d86f[drive].f);
|
||||
|
||||
if (!fdd_doublestep_40(drive))
|
||||
{
|
||||
@@ -3028,8 +3025,8 @@ void d86f_writeback(int drive)
|
||||
}
|
||||
if (d86f[drive].track_offset[logical_track])
|
||||
{
|
||||
fseek(d86f[drive].f, d86f[drive].track_offset[logical_track], SEEK_SET);
|
||||
d86f_write_track(drive, side, d86f[drive].thin_track_encoded_data[thin_track][side], d86f[drive].thin_track_surface_data[thin_track][side]);
|
||||
fseek(*f, d86f[drive].track_offset[logical_track], SEEK_SET);
|
||||
d86f_write_track(drive, f, side, d86f[drive].thin_track_encoded_data[thin_track][side], d86f[drive].thin_track_surface_data[thin_track][side]);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3048,11 +3045,35 @@ void d86f_writeback(int drive)
|
||||
}
|
||||
if (d86f[drive].track_offset[logical_track])
|
||||
{
|
||||
fseek(d86f[drive].f, d86f[drive].track_offset[logical_track], SEEK_SET);
|
||||
d86f_write_track(drive, side, d86f[drive].track_encoded_data[side], d86f[drive].track_surface_data[side]);
|
||||
fseek(*f, d86f[drive].track_offset[logical_track], SEEK_SET);
|
||||
d86f_write_track(drive, f, side, d86f[drive].track_encoded_data[side], d86f[drive].track_surface_data[side]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void d86f_writeback(int drive)
|
||||
{
|
||||
uint8_t header[32];
|
||||
int header_size;
|
||||
uint32_t len;
|
||||
int ret = 0;
|
||||
FILE *cf;
|
||||
header_size = d86f_header_size(drive);
|
||||
|
||||
if (!d86f[drive].f)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
/* First write the track offsets table. */
|
||||
fseek(d86f[drive].f, 0, SEEK_SET);
|
||||
fread(header, 1, header_size, d86f[drive].f);
|
||||
|
||||
fseek(d86f[drive].f, 8, SEEK_SET);
|
||||
fwrite(d86f[drive].track_offset, 1, d86f_get_track_table_size(drive), d86f[drive].f);
|
||||
|
||||
d86f_write_tracks(drive, &d86f[drive].f);
|
||||
|
||||
if (d86f[drive].is_compressed)
|
||||
{
|
||||
@@ -3094,7 +3115,7 @@ void d86f_stop(int drive)
|
||||
|
||||
int d86f_common_command(int drive, int sector, int track, int side, int rate, int sector_size)
|
||||
{
|
||||
d86f_log("d86f_common_command (drive %i): fdc_period=%i img_period=%i rate=%i sector=%i track=%i side=%i\n", drive, fdc_get_bitcell_period(), d86f_get_bitcell_period(drive), rate, sector, track, side);
|
||||
d86f_log("d86f_common_command (drive %i): fdc_period=%i img_period=%i rate=%i sector=%i track=%i side=%i\n", drive, fdc_get_bitcell_period(d86f_fdc), d86f_get_bitcell_period(drive), rate, sector, track, side);
|
||||
|
||||
d86f[drive].req_sector.id.c = track;
|
||||
d86f[drive].req_sector.id.h = side;
|
||||
@@ -3114,7 +3135,7 @@ int d86f_common_command(int drive, int sector, int track, int side, int rate, in
|
||||
|
||||
if (fdd_get_head(drive) && (d86f_get_sides(drive) == 1))
|
||||
{
|
||||
fdc_noidam();
|
||||
fdc_noidam(d86f_fdc);
|
||||
d86f[drive].state = STATE_IDLE;
|
||||
d86f[drive].index_count = 0;
|
||||
return 0;
|
||||
@@ -3141,7 +3162,7 @@ void d86f_readsector(int drive, int sector, int track, int side, int rate, int s
|
||||
else if (sector == SECTOR_NEXT)
|
||||
d86f[drive].state = STATE_02_FIND_ID;
|
||||
else
|
||||
d86f[drive].state = fdc_is_deleted() ? STATE_0C_FIND_ID : (fdc_is_verify() ? STATE_16_FIND_ID : STATE_06_FIND_ID);
|
||||
d86f[drive].state = fdc_is_deleted(d86f_fdc) ? STATE_0C_FIND_ID : (fdc_is_verify(d86f_fdc) ? STATE_16_FIND_ID : STATE_06_FIND_ID);
|
||||
}
|
||||
|
||||
void d86f_writesector(int drive, int sector, int track, int side, int rate, int sector_size)
|
||||
@@ -3150,7 +3171,7 @@ void d86f_writesector(int drive, int sector, int track, int side, int rate, int
|
||||
|
||||
if (writeprot[drive])
|
||||
{
|
||||
fdc_writeprotect();
|
||||
fdc_writeprotect(d86f_fdc);
|
||||
d86f[drive].state = STATE_IDLE;
|
||||
d86f[drive].index_count = 0;
|
||||
return;
|
||||
@@ -3159,7 +3180,7 @@ void d86f_writesector(int drive, int sector, int track, int side, int rate, int
|
||||
ret = d86f_common_command(drive, sector, track, side, rate, sector_size);
|
||||
if (!ret) return;
|
||||
|
||||
d86f[drive].state = fdc_is_deleted() ? STATE_09_FIND_ID : STATE_05_FIND_ID;
|
||||
d86f[drive].state = fdc_is_deleted(d86f_fdc) ? STATE_09_FIND_ID : STATE_05_FIND_ID;
|
||||
}
|
||||
|
||||
void d86f_comparesector(int drive, int sector, int track, int side, int rate, int sector_size)
|
||||
@@ -3176,7 +3197,7 @@ void d86f_readaddress(int drive, int side, int rate)
|
||||
{
|
||||
if (fdd_get_head(drive) && (d86f_get_sides(drive) == 1))
|
||||
{
|
||||
fdc_noidam();
|
||||
fdc_noidam(d86f_fdc);
|
||||
d86f[drive].state = STATE_IDLE;
|
||||
d86f[drive].index_count = 0;
|
||||
return;
|
||||
@@ -3237,7 +3258,7 @@ void d86f_common_format(int drive, int side, int rate, uint8_t fill, int proxy)
|
||||
|
||||
if (writeprot[drive])
|
||||
{
|
||||
fdc_writeprotect();
|
||||
fdc_writeprotect(d86f_fdc);
|
||||
d86f[drive].state = STATE_IDLE;
|
||||
d86f[drive].index_count = 0;
|
||||
return;
|
||||
@@ -3245,7 +3266,7 @@ void d86f_common_format(int drive, int side, int rate, uint8_t fill, int proxy)
|
||||
|
||||
if (!(d86f_can_format(drive)))
|
||||
{
|
||||
fdc_cannotformat();
|
||||
fdc_cannotformat(d86f_fdc);
|
||||
d86f[drive].state = STATE_IDLE;
|
||||
d86f[drive].index_count = 0;
|
||||
return;
|
||||
@@ -3259,7 +3280,7 @@ void d86f_common_format(int drive, int side, int rate, uint8_t fill, int proxy)
|
||||
|
||||
if (d86f[drive].cur_track > 256)
|
||||
{
|
||||
fdc_writeprotect();
|
||||
fdc_writeprotect(d86f_fdc);
|
||||
d86f[drive].state = STATE_IDLE;
|
||||
d86f[drive].index_count = 0;
|
||||
return;
|
||||
@@ -3294,9 +3315,9 @@ void d86f_common_format(int drive, int side, int rate, uint8_t fill, int proxy)
|
||||
if (!proxy)
|
||||
{
|
||||
d86f[drive].side_flags[side] = 0;
|
||||
d86f[drive].side_flags[side] |= (fdd_getrpm(real_drive(drive)) == 360) ? 0x20 : 0;
|
||||
d86f[drive].side_flags[side] |= fdc_get_bit_rate();
|
||||
d86f[drive].side_flags[side] |= fdc_is_mfm() ? 8 : 0;
|
||||
d86f[drive].side_flags[side] |= (fdd_getrpm(real_drive(d86f_fdc, drive)) == 360) ? 0x20 : 0;
|
||||
d86f[drive].side_flags[side] |= fdc_get_bit_rate(d86f_fdc);
|
||||
d86f[drive].side_flags[side] |= fdc_is_mfm(d86f_fdc) ? 8 : 0;
|
||||
|
||||
d86f[drive].index_hole_pos[side] = 0;
|
||||
}
|
||||
@@ -3332,7 +3353,6 @@ void d86f_common_handlers(int drive)
|
||||
drives[drive].writesector = d86f_writesector;
|
||||
drives[drive].comparesector=d86f_comparesector;
|
||||
drives[drive].readaddress = d86f_readaddress;
|
||||
drives[drive].hole = d86f_hole;
|
||||
drives[drive].byteperiod = d86f_byteperiod;
|
||||
drives[drive].poll = d86f_poll;
|
||||
drives[drive].format = d86f_proxy_format;
|
||||
@@ -3650,6 +3670,11 @@ void d86f_init()
|
||||
d86f[0].state = d86f[1].state = STATE_IDLE;
|
||||
}
|
||||
|
||||
void d86f_set_fdc(void *fdc)
|
||||
{
|
||||
d86f_fdc = (fdc_t *) fdc;
|
||||
}
|
||||
|
||||
void d86f_close(int drive)
|
||||
{
|
||||
wchar_t temp_file_name[2048];
|
||||
@@ -10,33 +10,36 @@
|
||||
* data in the form of FM/MFM-encoded transitions) which also
|
||||
* forms the core of the emulator's floppy disk emulation.
|
||||
*
|
||||
* Version: @(#)floppy_86f.h 1.0.2 2017/09/03
|
||||
* Version: @(#)floppy_86f.h 1.0.3 2018/01/17
|
||||
*
|
||||
* Author: Miran Grca, <mgrca8@gmail.com>
|
||||
* Copyright 2016-2017 Miran Grca.
|
||||
* Copyright 2016-2018 Miran Grca.
|
||||
*/
|
||||
#ifndef EMU_FLOPPY_86F_H
|
||||
# define EMU_FLOPPY_86F_H
|
||||
|
||||
|
||||
extern void d86f_init(void);
|
||||
extern void d86f_load(int drive, wchar_t *fn);
|
||||
extern void d86f_close(int drive);
|
||||
extern void d86f_seek(int drive, int track);
|
||||
extern int d86f_hole(int drive);
|
||||
extern double d86f_byteperiod(int drive);
|
||||
extern void d86f_stop(int drive);
|
||||
extern void d86f_poll(int drive);
|
||||
extern int d86f_realtrack(int track, int drive);
|
||||
extern void d86f_reset(int drive, int side);
|
||||
extern void d86f_readsector(int drive, int sector, int track, int side, int density, int sector_size);
|
||||
extern void d86f_writesector(int drive, int sector, int track, int side, int density, int sector_size);
|
||||
extern void d86f_comparesector(int drive, int sector, int track, int side, int rate, int sector_size);
|
||||
extern void d86f_readaddress(int drive, int side, int density);
|
||||
extern void d86f_format(int drive, int side, int density, uint8_t fill);
|
||||
extern void d86f_init(void);
|
||||
extern void d86f_load(int drive, wchar_t *fn);
|
||||
extern void d86f_close(int drive);
|
||||
extern void d86f_seek(int drive, int track);
|
||||
extern int d86f_hole(int drive);
|
||||
extern double d86f_byteperiod(int drive);
|
||||
extern void d86f_stop(int drive);
|
||||
extern void d86f_poll(int drive);
|
||||
extern int d86f_realtrack(int track, int drive);
|
||||
extern void d86f_reset(int drive, int side);
|
||||
extern void d86f_readsector(int drive, int sector, int track, int side, int density, int sector_size);
|
||||
extern void d86f_writesector(int drive, int sector, int track, int side, int density, int sector_size);
|
||||
extern void d86f_comparesector(int drive, int sector, int track, int side, int rate, int sector_size);
|
||||
extern void d86f_readaddress(int drive, int side, int density);
|
||||
extern void d86f_format(int drive, int side, int density, uint8_t fill);
|
||||
|
||||
extern void d86f_prepare_track_layout(int drive, int side);
|
||||
extern void d86f_set_version(int drive, uint16_t version);
|
||||
extern void d86f_prepare_track_layout(int drive, int side);
|
||||
extern void d86f_set_version(int drive, uint16_t version);
|
||||
extern uint16_t d86f_side_flags(int drive);
|
||||
extern uint16_t d86f_track_flags(int drive);
|
||||
extern void d86f_write_tracks(int drive, FILE **f);
|
||||
|
||||
#define length_gap0 80
|
||||
#define length_gap1 50
|
||||
@@ -8,10 +8,10 @@
|
||||
*
|
||||
* Shared code for all the floppy modules.
|
||||
*
|
||||
* Version: @(#)floppy_common.c 1.0.4 2017/11/04
|
||||
* Version: @(#)fdd_common.c 1.0.5 2018/01/16
|
||||
*
|
||||
* Author: Fred N. van Kempen, <decwiz@yahoo.com>
|
||||
* Copyright 2017 Fred N. van Kempen.
|
||||
* Copyright 2017,2018 Fred N. van Kempen.
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
@@ -19,15 +19,15 @@
|
||||
#include <stdlib.h>
|
||||
#include <wchar.h>
|
||||
#include "../86box.h"
|
||||
#include "../floppy/floppy.h"
|
||||
#include "floppy_common.h"
|
||||
#include "fdd.h"
|
||||
#include "fdd_common.h"
|
||||
|
||||
|
||||
uint8_t floppy_holes[6] = { 0, 0, 0, 1, 1, 2 };
|
||||
uint8_t fdd_holes[6] = { 0, 0, 0, 1, 1, 2 };
|
||||
|
||||
uint8_t floppy_rates[6] = { 2, 2, 1, 4, 0, 3 };
|
||||
uint8_t fdd_rates[6] = { 2, 2, 1, 4, 0, 3 };
|
||||
|
||||
double floppy_bit_rates_300[6] = {
|
||||
double fdd_bit_rates_300[6] = {
|
||||
(250.0 * 300.0) / 360.0,
|
||||
250.0,
|
||||
300.0,
|
||||
@@ -46,7 +46,7 @@ double floppy_bit_rates_300[6] = {
|
||||
* Disks formatted at 300 kbps @ 300 RPM can be read with any 300 RPM
|
||||
* single-RPM drive by setting the rate to 300 kbps.
|
||||
*/
|
||||
uint8_t floppy_max_sectors[8][6] = {
|
||||
uint8_t fdd_max_sectors[8][6] = {
|
||||
{ 26, 31, 38, 53, 64, 118 }, /* 128 */
|
||||
{ 15, 19, 23, 32, 38, 73 }, /* 256 */
|
||||
{ 7, 10, 12, 17, 22, 41 }, /* 512 */
|
||||
@@ -57,12 +57,12 @@ uint8_t floppy_max_sectors[8][6] = {
|
||||
{ 0, 0, 0, 0, 0, 1 } /* 16384 */
|
||||
};
|
||||
|
||||
uint8_t floppy_dmf_r[21] = {
|
||||
uint8_t fdd_dmf_r[21] = {
|
||||
12,2,13,3,14,4,15,5,16,6,17,7,18,8,19,9,20,10,21,11,1
|
||||
};
|
||||
|
||||
|
||||
static uint8_t floppy_gap3_sizes[5][8][48] = {
|
||||
static uint8_t fdd_gap3_sizes[5][8][48] = {
|
||||
{ { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* [0][0] */
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
@@ -348,14 +348,14 @@ static uint8_t floppy_gap3_sizes[5][8][48] = {
|
||||
|
||||
|
||||
int
|
||||
floppy_get_gap3_size(int rate, int size, int sector)
|
||||
fdd_get_gap3_size(int rate, int size, int sector)
|
||||
{
|
||||
return(floppy_gap3_sizes[rate][size][sector]);
|
||||
return(fdd_gap3_sizes[rate][size][sector]);
|
||||
}
|
||||
|
||||
|
||||
uint8_t
|
||||
floppy_sector_size_code(int size)
|
||||
fdd_sector_size_code(int size)
|
||||
{
|
||||
int ret = 2;
|
||||
|
||||
@@ -401,14 +401,14 @@ floppy_sector_size_code(int size)
|
||||
|
||||
|
||||
int
|
||||
floppy_sector_code_size(uint8_t code)
|
||||
fdd_sector_code_size(uint8_t code)
|
||||
{
|
||||
return(128 << code);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
floppy_bps_valid(uint16_t bps)
|
||||
fdd_bps_valid(uint16_t bps)
|
||||
{
|
||||
int i;
|
||||
|
||||
@@ -423,7 +423,7 @@ floppy_bps_valid(uint16_t bps)
|
||||
|
||||
|
||||
int
|
||||
floppy_interleave(int sector, int skew, int spt)
|
||||
fdd_interleave(int sector, int skew, int spt)
|
||||
{
|
||||
uint32_t add = (spt & 1);
|
||||
uint32_t adjust = (spt >> 1);
|
||||
34
src/floppy/fdd_common.h
Normal file
34
src/floppy/fdd_common.h
Normal file
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* 86Box A hypervisor and IBM PC system emulator that specializes in
|
||||
* running old operating systems and software designed for IBM
|
||||
* PC systems and compatibles from 1981 through fairly recent
|
||||
* system designs based on the PCI bus.
|
||||
*
|
||||
* This file is part of the 86Box distribution.
|
||||
*
|
||||
* Shared code for all the floppy modules.
|
||||
*
|
||||
* Version: @(#)fdd_common.h 1.0.2 2018/01/16
|
||||
*
|
||||
* Author: Fred N. van Kempen, <decwiz@yahoo.com>
|
||||
* Copyright 2017,2018 Fred N. van Kempen.
|
||||
*/
|
||||
#ifndef fdd_COMMON_H
|
||||
# define fdd_COMMON_H
|
||||
|
||||
|
||||
extern uint8_t fdd_holes[6];
|
||||
extern uint8_t fdd_rates[6];
|
||||
extern double fdd_bit_rates_300[6];
|
||||
extern uint8_t fdd_max_sectors[8][6];
|
||||
extern uint8_t fdd_dmf_r[21];
|
||||
|
||||
|
||||
extern int fdd_get_gap3_size(int rate, int size, int sector);
|
||||
extern uint8_t fdd_sector_size_code(int size);
|
||||
extern int fdd_sector_code_size(uint8_t code);
|
||||
extern int fdd_bps_valid(uint16_t bps);
|
||||
extern int fdd_interleave(int sector, int skew, int spt);
|
||||
|
||||
|
||||
#endif /*fdd_COMMON_H*/
|
||||
@@ -9,13 +9,13 @@
|
||||
* Implementation of the FDI floppy stream image format
|
||||
* interface to the FDI2RAW module.
|
||||
*
|
||||
* Version: @(#)floppy_fdi.c 1.0.6 2017/12/14
|
||||
* Version: @(#)fdd_fdi.c 1.0.7 2018/01/16
|
||||
*
|
||||
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
*
|
||||
* Copyright 2008-2017 Sarah Walker.
|
||||
* Copyright 2016,2017 Miran Grca.
|
||||
* Copyright 2008-2018 Sarah Walker.
|
||||
* Copyright 2016-2018 Miran Grca.
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
@@ -23,12 +23,11 @@
|
||||
#include <wchar.h>
|
||||
#include "../86box.h"
|
||||
#include "../plat.h"
|
||||
#include "floppy.h"
|
||||
#include "floppy_86f.h"
|
||||
#include "floppy_img.h"
|
||||
#include "floppy_fdi.h"
|
||||
#include "fdc.h"
|
||||
#include "fdd.h"
|
||||
#include "fdd_86f.h"
|
||||
#include "fdd_img.h"
|
||||
#include "fdd_fdi.h"
|
||||
#include "fdc.h"
|
||||
#include "fdi2raw.h"
|
||||
|
||||
|
||||
@@ -47,6 +46,8 @@ static struct
|
||||
int lasttrack;
|
||||
} fdi[FDD_NUM];
|
||||
|
||||
static fdc_t *fdi_fdc;
|
||||
|
||||
uint16_t fdi_disk_flags(int drive)
|
||||
{
|
||||
uint16_t temp_disk_flags = 0x80; /* We ALWAYS claim to have extra bit cells, even if the actual amount is 0. */
|
||||
@@ -111,12 +112,12 @@ uint16_t fdi_side_flags(int drive)
|
||||
|
||||
int fdi_density()
|
||||
{
|
||||
if (!fdc_is_mfm())
|
||||
if (!fdc_is_mfm(fdi_fdc))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
switch (fdc_get_bit_rate())
|
||||
switch (fdc_get_bit_rate(fdi_fdc))
|
||||
{
|
||||
case 0:
|
||||
return 2;
|
||||
@@ -142,9 +143,9 @@ int32_t fdi_extra_bit_cells(int drive, int side)
|
||||
|
||||
density = fdi_density();
|
||||
|
||||
is_300_rpm = (fdd_getrpm(real_drive(drive)) == 300);
|
||||
is_300_rpm = (fdd_getrpm(drive) == 300);
|
||||
|
||||
switch (fdc_get_bit_rate())
|
||||
switch (fdc_get_bit_rate(fdi_fdc))
|
||||
{
|
||||
case 0:
|
||||
raw_size = is_300_rpm ? 200000 : 166666;
|
||||
@@ -322,15 +323,25 @@ void fdi_seek(int drive, int track)
|
||||
track /= 2;
|
||||
}
|
||||
}
|
||||
|
||||
d86f_set_cur_track(drive, track);
|
||||
|
||||
if (!fdi[drive].f)
|
||||
return;
|
||||
if (track < 0)
|
||||
track = 0;
|
||||
|
||||
#if 0
|
||||
if (track > fdi[drive].lasttrack)
|
||||
track = fdi[drive].lasttrack - 1;
|
||||
#endif
|
||||
|
||||
fdi[drive].track = track;
|
||||
|
||||
fdi_read_revolution(drive);
|
||||
}
|
||||
|
||||
void fdi_set_fdc(void *fdc)
|
||||
{
|
||||
fdi_fdc = (fdc_t *) fdc;
|
||||
}
|
||||
@@ -8,10 +8,10 @@
|
||||
*
|
||||
* Implementation of the IMD floppy image format.
|
||||
*
|
||||
* Version: @(#)floppy_imd.c 1.0.5 2017/11/04
|
||||
* Version: @(#)fdd_imd.c 1.0.6 2018/01/16
|
||||
*
|
||||
* Author: Miran Grca, <mgrca8@gmail.com>
|
||||
* Copyright 2016,2017 Miran Grca.
|
||||
* Copyright 2016-2018 Miran Grca.
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
@@ -20,10 +20,9 @@
|
||||
#include <wchar.h>
|
||||
#include "../86box.h"
|
||||
#include "../plat.h"
|
||||
#include "floppy.h"
|
||||
#include "floppy_imd.h"
|
||||
#include "fdc.h"
|
||||
#include "fdd.h"
|
||||
#include "fdd_imd.h"
|
||||
#include "fdc.h"
|
||||
|
||||
|
||||
typedef struct
|
||||
@@ -59,6 +58,8 @@ static struct
|
||||
uint8_t track_buffer[2][25000];
|
||||
} imd[FDD_NUM];
|
||||
|
||||
static fdc_t *imd_fdc;
|
||||
|
||||
void imd_init()
|
||||
{
|
||||
memset(imd, 0, sizeof(imd));
|
||||
@@ -529,6 +530,8 @@ void imd_seek(int drive, int track)
|
||||
if (!imd[drive].track_width && fdd_doublestep_40(drive))
|
||||
track /= 2;
|
||||
|
||||
d86f_set_cur_track(drive, track);
|
||||
|
||||
is_trackx = (track == 0) ? 0 : 1;
|
||||
|
||||
imd[drive].track = track;
|
||||
@@ -542,6 +545,12 @@ void imd_seek(int drive, int track)
|
||||
d86f_zero_bit_field(drive, 0);
|
||||
d86f_zero_bit_field(drive, 1);
|
||||
|
||||
if (track > imd[drive].track_count)
|
||||
{
|
||||
d86f_zero_track(drive);
|
||||
return;
|
||||
}
|
||||
|
||||
for (side = 0; side < imd[drive].sides; side++)
|
||||
{
|
||||
track_rate = imd[drive].current_side_flags[side] & 7;
|
||||
@@ -797,11 +806,16 @@ int imd_format_conditions(int drive)
|
||||
int side = 0;
|
||||
int temp = 0;
|
||||
side = fdd_get_head(drive);
|
||||
temp = (fdc_get_format_sectors() == imd[drive].tracks[track][side].params[3]);
|
||||
temp = temp && (fdc_get_format_n() == imd[drive].tracks[track][side].params[4]);
|
||||
temp = (fdc_get_format_sectors(imd_fdc) == imd[drive].tracks[track][side].params[3]);
|
||||
temp = temp && (fdc_get_format_n(imd_fdc) == imd[drive].tracks[track][side].params[4]);
|
||||
return temp;
|
||||
}
|
||||
|
||||
void imd_set_fdc(void *fdc)
|
||||
{
|
||||
imd_fdc = (fdc_t *) fdc;
|
||||
}
|
||||
|
||||
void d86f_register_imd(int drive)
|
||||
{
|
||||
d86f_handler[drive].disk_flags = imd_disk_flags;
|
||||
@@ -9,13 +9,13 @@
|
||||
* Implementation of the raw sector-based floppy image format,
|
||||
* as well as the Japanese FDI, CopyQM, and FDF formats.
|
||||
*
|
||||
* Version: @(#)floppy_img.c 1.0.7 2017/11/04
|
||||
* Version: @(#)fdd_img.c 1.0.8 2018/01/16
|
||||
*
|
||||
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
*
|
||||
* Copyright 2008-2017 Sarah Walker.
|
||||
* Copyright 2016,2017 Miran Grca.
|
||||
* Copyright 2008-2018 Sarah Walker.
|
||||
* Copyright 2016-2018 Miran Grca.
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
@@ -25,10 +25,9 @@
|
||||
#include "../86box.h"
|
||||
#include "../config.h"
|
||||
#include "../plat.h"
|
||||
#include "floppy.h"
|
||||
#include "floppy_img.h"
|
||||
#include "fdc.h"
|
||||
#include "fdd.h"
|
||||
#include "fdd_img.h"
|
||||
#include "fdc.h"
|
||||
|
||||
|
||||
static struct
|
||||
@@ -57,6 +56,8 @@ static struct
|
||||
uint8_t skew;
|
||||
} img[FDD_NUM];
|
||||
|
||||
static fdc_t *img_fdc;
|
||||
|
||||
uint8_t dmf_r[21] = { 12, 2, 13, 3, 14, 4, 15, 5, 16, 6, 17, 7, 18, 8, 19, 9, 20, 10, 21, 11, 1 };
|
||||
static uint8_t xdf_logical_sectors[2][2] = { { 38, 6 }, { 46, 8 } };
|
||||
uint8_t xdf_physical_sectors[2][2] = { { 16, 3 }, { 19, 4 } };
|
||||
@@ -930,6 +931,7 @@ void img_seek(int drive, int track)
|
||||
track /= 2;
|
||||
|
||||
img[drive].track = track;
|
||||
d86f_set_cur_track(drive, track);
|
||||
|
||||
is_t0 = (track == 0) ? 1 : 0;
|
||||
|
||||
@@ -961,6 +963,12 @@ void img_seek(int drive, int track)
|
||||
d86f_zero_bit_field(drive, 0);
|
||||
d86f_zero_bit_field(drive, 1);
|
||||
|
||||
if (track > img[drive].tracks)
|
||||
{
|
||||
d86f_zero_track(drive);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!img[drive].xdf_type || img[drive].is_cqm)
|
||||
{
|
||||
for (side = 0; side < img[drive].sides; side++)
|
||||
@@ -1129,12 +1137,17 @@ void img_poll_write_data(int drive, int side, uint16_t pos, uint8_t data)
|
||||
|
||||
int img_format_conditions(int drive)
|
||||
{
|
||||
int temp = (fdc_get_format_sectors() == img[drive].sectors);
|
||||
temp = temp && (fdc_get_format_n() == img[drive].sector_size);
|
||||
int temp = (fdc_get_format_sectors(img_fdc) == img[drive].sectors);
|
||||
temp = temp && (fdc_get_format_n(img_fdc) == img[drive].sector_size);
|
||||
temp = temp && (img[drive].xdf_type == 0);
|
||||
return temp;
|
||||
}
|
||||
|
||||
void img_set_fdc(void *fdc)
|
||||
{
|
||||
img_fdc = (fdc_t *) fdc;
|
||||
}
|
||||
|
||||
void d86f_register_img(int drive)
|
||||
{
|
||||
d86f_handler[drive].disk_flags = img_disk_flags;
|
||||
@@ -8,11 +8,11 @@
|
||||
*
|
||||
* Implementation of the PCjs JSON floppy image format.
|
||||
*
|
||||
* Version: @(#)floppy_json.c 1.0.9 2017/11/04
|
||||
* Version: @(#)fdd_json.c 1.0.10 2018/01/16
|
||||
*
|
||||
* Author: Fred N. van Kempen, <decwiz@yahoo.com>
|
||||
*
|
||||
* Copyright 2017 Fred N. van Kempen.
|
||||
* Copyright 2017,2018 Fred N. van Kempen.
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
@@ -21,11 +21,10 @@
|
||||
#include <wchar.h>
|
||||
#include "../86box.h"
|
||||
#include "../plat.h"
|
||||
#include "floppy.h"
|
||||
#include "fdc.h"
|
||||
#include "fdd.h"
|
||||
#include "floppy_common.h"
|
||||
#include "floppy_json.h"
|
||||
#include "fdc.h"
|
||||
#include "fdd_common.h"
|
||||
#include "fdd_json.h"
|
||||
|
||||
|
||||
#define NTRACKS 256
|
||||
@@ -96,7 +95,7 @@ handle(json_t *img, char *name, char *str)
|
||||
}
|
||||
|
||||
/* Encode the sector size. */
|
||||
sec->size = floppy_sector_size_code(sec->size);
|
||||
sec->size = fdd_sector_size_code(sec->size);
|
||||
|
||||
/* Set up the rest of the Sector ID. */
|
||||
sec->track = img->track;
|
||||
@@ -353,6 +352,7 @@ json_seek(int drive, int track)
|
||||
|
||||
/* Set the new track. */
|
||||
img->track = track;
|
||||
d86f_set_cur_track(drive, track);
|
||||
|
||||
/* Reset the 86F state machine. */
|
||||
d86f_reset_index_hole_pos(drive, 0);
|
||||
@@ -361,13 +361,19 @@ json_seek(int drive, int track)
|
||||
d86f_zero_bit_field(drive, 1);
|
||||
|
||||
interleave_type = 0;
|
||||
|
||||
if (track > img->tracks) {
|
||||
d86f_zero_track(drive);
|
||||
return;
|
||||
}
|
||||
|
||||
for (side=0; side<img->sides; side++) {
|
||||
/* Get transfer rate for this side. */
|
||||
rate = img->track_flags & 0x07;
|
||||
if (!rate && (img->track_flags & 0x20)) rate = 4;
|
||||
|
||||
/* Get correct GAP3 value for this side. */
|
||||
gap3 = floppy_get_gap3_size(rate,
|
||||
gap3 = fdd_get_gap3_size(rate,
|
||||
img->sects[track][side][0].size,
|
||||
img->spt[track][side]);
|
||||
|
||||
@@ -381,14 +387,14 @@ json_seek(int drive, int track)
|
||||
rsec = img->sects[track][side][sector].sector;
|
||||
asec = sector;
|
||||
} else {
|
||||
rsec = floppy_dmf_r[sector];
|
||||
rsec = fdd_dmf_r[sector];
|
||||
asec = img->interleave_ordered[rsec][side];
|
||||
}
|
||||
id[0] = track;
|
||||
id[1] = side;
|
||||
id[2] = rsec;
|
||||
id[3] = img->sects[track][side][asec].size;
|
||||
ssize = floppy_sector_code_size(img->sects[track][side][asec].size);
|
||||
ssize = fdd_sector_code_size(img->sects[track][side][asec].size);
|
||||
|
||||
pos = d86f_prepare_sector(
|
||||
drive, side, pos, id,
|
||||
@@ -521,11 +527,11 @@ json_load(int drive, wchar_t *fn)
|
||||
temp_rate = 0xff;
|
||||
sec = &img->sects[0][0][0];
|
||||
for (i=0; i<6; i++) {
|
||||
if (img->spt[0][0] > floppy_max_sectors[sec->size][i]) continue;
|
||||
if (img->spt[0][0] > fdd_max_sectors[sec->size][i]) continue;
|
||||
|
||||
bit_rate = floppy_bit_rates_300[i];
|
||||
temp_rate = floppy_rates[i];
|
||||
img->disk_flags |= (floppy_holes[i] << 1);
|
||||
bit_rate = fdd_bit_rates_300[i];
|
||||
temp_rate = fdd_rates[i];
|
||||
img->disk_flags |= (fdd_holes[i] << 1);
|
||||
|
||||
if ((bit_rate == 500.0) && (img->spt[0][0] == 21) &&
|
||||
(sec->size == 2) && (img->tracks >= 80) &&
|
||||
@@ -569,7 +575,7 @@ json_load(int drive, wchar_t *fn)
|
||||
if (img->dmf) {
|
||||
img->gap3_len = 8;
|
||||
} else {
|
||||
img->gap3_len = floppy_get_gap3_size(temp_rate,sec->size,img->spt[0][0]);
|
||||
img->gap3_len = fdd_get_gap3_size(temp_rate,sec->size,img->spt[0][0]);
|
||||
}
|
||||
|
||||
if (! img->gap3_len) {
|
||||
@@ -8,18 +8,18 @@
|
||||
*
|
||||
* Implementation of the Teledisk floppy image format.
|
||||
*
|
||||
* Version: @(#)floppy_td0.c 1.0.6 2017/11/04
|
||||
* Version: @(#)fdd_td0.c 1.0.7 2018/01/16
|
||||
*
|
||||
* Authors: Milodrag Milanovic,
|
||||
* Haruhiko OKUMURA,
|
||||
* Haruyasu YOSHIZAKI,
|
||||
* Kenji RIKITAKE,
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
* Copyright 1988-2017 Haruhiko OKUMURA.
|
||||
* Copyright 1988-2017 Haruyasu YOSHIZAKI.
|
||||
* Copyright 1988-2017 Kenji RIKITAKE.
|
||||
* Copyright 2013-2017 Milodrag Milanovic.
|
||||
* Copyright 2016-2017 Miran Grca.
|
||||
* Copyright 1988-2018 Haruhiko OKUMURA.
|
||||
* Copyright 1988-2018 Haruyasu YOSHIZAKI.
|
||||
* Copyright 1988-2018 Kenji RIKITAKE.
|
||||
* Copyright 2013-2018 Milodrag Milanovic.
|
||||
* Copyright 2016-2018 Miran Grca.
|
||||
*/
|
||||
|
||||
/* license:BSD-3-Clause
|
||||
@@ -44,10 +44,9 @@
|
||||
#include <wchar.h>
|
||||
#include "../86box.h"
|
||||
#include "../plat.h"
|
||||
#include "floppy.h"
|
||||
#include "floppy_td0.h"
|
||||
#include "fdc.h"
|
||||
#include "fdd.h"
|
||||
#include "fdd_td0.h"
|
||||
#include "fdc.h"
|
||||
|
||||
|
||||
#define BUFSZ 512 /* new input buffer */
|
||||
@@ -80,8 +79,8 @@ typedef struct {
|
||||
|
||||
typedef struct
|
||||
{
|
||||
FILE *floppy_file;
|
||||
uint64_t floppy_file_offset;
|
||||
FILE *fdd_file;
|
||||
uint64_t fdd_file_offset;
|
||||
|
||||
tdlzhuf tdctl;
|
||||
uint8_t text_buf[N + F - 1];
|
||||
@@ -136,7 +135,7 @@ typedef struct
|
||||
td0_t td0[FDD_NUM];
|
||||
|
||||
|
||||
void floppy_image_read(int drive, char *buffer, uint32_t offset, uint32_t len)
|
||||
void fdd_image_read(int drive, char *buffer, uint32_t offset, uint32_t len)
|
||||
{
|
||||
fseek(td0[drive].f, offset, SEEK_SET);
|
||||
fread(buffer, 1, len, td0[drive].f);
|
||||
@@ -146,7 +145,7 @@ int td0_dsk_identify(int drive)
|
||||
{
|
||||
char header[2];
|
||||
|
||||
floppy_image_read(drive, header, 0, 2);
|
||||
fdd_image_read(drive, header, 0, 2);
|
||||
if (header[0]=='T' && header[1]=='D') {
|
||||
return 1;
|
||||
} else if (header[0]=='t' && header[1]=='d') {
|
||||
@@ -159,14 +158,14 @@ int td0_dsk_identify(int drive)
|
||||
int td0_state_data_read(td0dsk_t *state, uint8_t *buf, uint16_t size)
|
||||
{
|
||||
uint32_t image_size = 0;
|
||||
fseek(state->floppy_file, 0, SEEK_END);
|
||||
image_size = ftell(state->floppy_file);
|
||||
if (size > image_size - state->floppy_file_offset) {
|
||||
size = image_size - state->floppy_file_offset;
|
||||
fseek(state->fdd_file, 0, SEEK_END);
|
||||
image_size = ftell(state->fdd_file);
|
||||
if (size > image_size - state->fdd_file_offset) {
|
||||
size = image_size - state->fdd_file_offset;
|
||||
}
|
||||
fseek(state->floppy_file, state->floppy_file_offset, SEEK_SET);
|
||||
fread(buf, 1, size, state->floppy_file);
|
||||
state->floppy_file_offset += size;
|
||||
fseek(state->fdd_file, state->fdd_file_offset, SEEK_SET);
|
||||
fread(buf, 1, size, state->fdd_file);
|
||||
state->fdd_file_offset += size;
|
||||
return size;
|
||||
}
|
||||
|
||||
@@ -711,9 +710,9 @@ int td0_initialize(int drive)
|
||||
if(header[0] == 't')
|
||||
{
|
||||
pclog("TD0: File is compressed\n");
|
||||
disk_decode.floppy_file = td0[drive].f;
|
||||
disk_decode.fdd_file = td0[drive].f;
|
||||
td0_state_init_Decode(&disk_decode);
|
||||
disk_decode.floppy_file_offset = 12;
|
||||
disk_decode.fdd_file_offset = 12;
|
||||
td0_state_Decode(&disk_decode, imagebuf, max_size);
|
||||
}
|
||||
else
|
||||
@@ -1100,6 +1099,8 @@ void td0_seek(int drive, int track)
|
||||
if (!td0[drive].track_width && fdd_doublestep_40(drive))
|
||||
track /= 2;
|
||||
|
||||
d86f_set_cur_track(drive, track);
|
||||
|
||||
is_trackx = (track == 0) ? 0 : 1;
|
||||
|
||||
td0[drive].track = track;
|
||||
@@ -1113,6 +1114,12 @@ void td0_seek(int drive, int track)
|
||||
d86f_zero_bit_field(drive, 0);
|
||||
d86f_zero_bit_field(drive, 1);
|
||||
|
||||
if (track > td0[drive].tracks)
|
||||
{
|
||||
d86f_zero_track(drive);
|
||||
return;
|
||||
}
|
||||
|
||||
for (side = 0; side < td0[drive].sides; side++)
|
||||
{
|
||||
track_rate = td0[drive].current_side_flags[side] & 7;
|
||||
@@ -1,428 +0,0 @@
|
||||
/*
|
||||
* 86Box A hypervisor and IBM PC system emulator that specializes in
|
||||
* running old operating systems and software designed for IBM
|
||||
* PC systems and compatibles from 1981 through fairly recent
|
||||
* system designs based on the PCI bus.
|
||||
*
|
||||
* This file is part of the 86Box distribution.
|
||||
*
|
||||
* Generic floppy disk interface that communicates with the
|
||||
* other handlers.
|
||||
*
|
||||
* Version: @(#)floppy.c 1.0.13 2017/12/14
|
||||
*
|
||||
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
*
|
||||
* Copyright 2008-2017 Sarah Walker.
|
||||
* Copyright 2016,2017 Miran Grca.
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <wchar.h>
|
||||
#include "../86box.h"
|
||||
#include "../machine/machine.h"
|
||||
#include "../mem.h"
|
||||
#include "../rom.h"
|
||||
#include "../config.h"
|
||||
#include "../timer.h"
|
||||
#include "../plat.h"
|
||||
#include "../ui.h"
|
||||
#include "floppy.h"
|
||||
#include "floppy_86f.h"
|
||||
#include "floppy_fdi.h"
|
||||
#include "floppy_imd.h"
|
||||
#include "floppy_img.h"
|
||||
#include "floppy_json.h"
|
||||
#include "floppy_td0.h"
|
||||
#include "fdc.h"
|
||||
#include "fdd.h"
|
||||
|
||||
|
||||
extern int driveempty[4];
|
||||
|
||||
wchar_t floppyfns[4][512];
|
||||
|
||||
int64_t floppy_poll_time[FDD_NUM] = { 16LL, 16LL, 16LL, 16LL };
|
||||
|
||||
int floppy_track[FDD_NUM];
|
||||
int writeprot[FDD_NUM], fwriteprot[FDD_NUM];
|
||||
|
||||
DRIVE drives[FDD_NUM];
|
||||
int drive_type[FDD_NUM];
|
||||
|
||||
int curdrive = 0;
|
||||
|
||||
int swwp = 0;
|
||||
int disable_write = 0;
|
||||
|
||||
int defaultwriteprot = 0;
|
||||
|
||||
int fdc_time;
|
||||
int floppy_time;
|
||||
|
||||
int fdc_ready;
|
||||
|
||||
int drive_empty[FDD_NUM] = {1, 1, 1, 1};
|
||||
int floppy_changed[FDD_NUM];
|
||||
|
||||
int motorspin;
|
||||
int64_t motoron[FDD_NUM];
|
||||
|
||||
int fdc_indexcount = 52;
|
||||
|
||||
#if 0 //FIXME:
|
||||
void (*fdc_callback)();
|
||||
void (*fdc_data)(uint8_t dat);
|
||||
void (*fdc_spindown)();
|
||||
void (*fdc_finishread)();
|
||||
void (*fdc_notfound)();
|
||||
void (*fdc_datacrcerror)();
|
||||
void (*fdc_headercrcerror)();
|
||||
void (*fdc_writeprotect)();
|
||||
int (*fdc_getdata)(int last);
|
||||
void (*fdc_sectorid)(uint8_t track, uint8_t side, uint8_t sector, uint8_t size, uint8_t crc1, uint8_t crc2);
|
||||
void (*fdc_indexpulse)();
|
||||
#endif
|
||||
|
||||
|
||||
static struct
|
||||
{
|
||||
wchar_t *ext;
|
||||
void (*load)(int drive, wchar_t *fn);
|
||||
void (*close)(int drive);
|
||||
int size;
|
||||
} loaders[]=
|
||||
{
|
||||
{L"001", img_load, img_close, -1},
|
||||
{L"002", img_load, img_close, -1},
|
||||
{L"003", img_load, img_close, -1},
|
||||
{L"004", img_load, img_close, -1},
|
||||
{L"005", img_load, img_close, -1},
|
||||
{L"006", img_load, img_close, -1},
|
||||
{L"007", img_load, img_close, -1},
|
||||
{L"008", img_load, img_close, -1},
|
||||
{L"009", img_load, img_close, -1},
|
||||
{L"010", img_load, img_close, -1},
|
||||
{L"12", img_load, img_close, -1},
|
||||
{L"144", img_load, img_close, -1},
|
||||
{L"360", img_load, img_close, -1},
|
||||
{L"720", img_load, img_close, -1},
|
||||
{L"86F", d86f_load, d86f_close, -1},
|
||||
{L"BIN", img_load, img_close, -1},
|
||||
{L"CQ", img_load, img_close, -1},
|
||||
{L"CQM", img_load, img_close, -1},
|
||||
{L"DSK", img_load, img_close, -1},
|
||||
{L"FDI", fdi_load, fdi_close, -1},
|
||||
{L"FDF", img_load, img_close, -1},
|
||||
{L"FLP", img_load, img_close, -1},
|
||||
{L"HDM", img_load, img_close, -1},
|
||||
{L"IMA", img_load, img_close, -1},
|
||||
{L"IMD", imd_load, imd_close, -1},
|
||||
{L"IMG", img_load, img_close, -1},
|
||||
{L"JSON", json_load, json_close, -1},
|
||||
{L"TD0", td0_load, td0_close, -1},
|
||||
{L"VFD", img_load, img_close, -1},
|
||||
{L"XDF", img_load, img_close, -1},
|
||||
{0,0,0}
|
||||
};
|
||||
|
||||
static int driveloaders[4];
|
||||
|
||||
void floppy_load(int drive, wchar_t *fn)
|
||||
{
|
||||
int c = 0, size;
|
||||
wchar_t *p;
|
||||
FILE *f;
|
||||
if (!fn) return;
|
||||
p = plat_get_extension(fn);
|
||||
if (!p) return;
|
||||
f = plat_fopen(fn, L"rb");
|
||||
if (!f) return;
|
||||
fseek(f, -1, SEEK_END);
|
||||
size = ftell(f) + 1;
|
||||
fclose(f);
|
||||
while (loaders[c].ext)
|
||||
{
|
||||
if (!wcscasecmp(p, loaders[c].ext) && (size == loaders[c].size || loaders[c].size == -1))
|
||||
{
|
||||
driveloaders[drive] = c;
|
||||
memcpy(floppyfns[drive], fn, (wcslen(fn) << 1) + 2);
|
||||
loaders[c].load(drive, floppyfns[drive]);
|
||||
drive_empty[drive] = 0;
|
||||
fdd_forced_seek(real_drive(drive), 0);
|
||||
floppy_changed[drive] = 1;
|
||||
return;
|
||||
}
|
||||
c++;
|
||||
}
|
||||
pclog("Couldn't load %ls %s\n",fn,p);
|
||||
drive_empty[drive] = 1;
|
||||
fdd_set_head(real_drive(drive), 0);
|
||||
memset(floppyfns[drive], 0, sizeof(floppyfns[drive]));
|
||||
ui_sb_update_icon_state(drive, 1);
|
||||
}
|
||||
|
||||
void floppy_close(int drive)
|
||||
{
|
||||
if (loaders[driveloaders[drive]].close) loaders[driveloaders[drive]].close(drive);
|
||||
drive_empty[drive] = 1;
|
||||
fdd_set_head(real_drive(drive), 0);
|
||||
floppyfns[drive][0] = 0;
|
||||
drives[drive].hole = NULL;
|
||||
drives[drive].poll = NULL;
|
||||
drives[drive].seek = NULL;
|
||||
drives[drive].readsector = NULL;
|
||||
drives[drive].writesector = NULL;
|
||||
drives[drive].comparesector = NULL;
|
||||
drives[drive].readaddress = NULL;
|
||||
drives[drive].format = NULL;
|
||||
drives[drive].byteperiod = NULL;
|
||||
drives[drive].stop = NULL;
|
||||
ui_sb_update_icon_state(drive, 1);
|
||||
}
|
||||
|
||||
int floppy_notfound=0;
|
||||
static int floppy_period = 32;
|
||||
|
||||
int floppy_hole(int drive)
|
||||
{
|
||||
drive = real_drive(drive);
|
||||
|
||||
if (drives[drive].hole)
|
||||
{
|
||||
return drives[drive].hole(drive);
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
double floppy_byteperiod(int drive)
|
||||
{
|
||||
drive = real_drive(drive);
|
||||
|
||||
if (drives[drive].byteperiod)
|
||||
{
|
||||
return drives[drive].byteperiod(drive);
|
||||
}
|
||||
else
|
||||
{
|
||||
return 32.0;
|
||||
}
|
||||
}
|
||||
|
||||
double floppy_real_period(int drive)
|
||||
{
|
||||
double ddbp;
|
||||
double dusec;
|
||||
|
||||
ddbp = floppy_byteperiod(real_drive(drive));
|
||||
|
||||
dusec = (double) TIMER_USEC;
|
||||
|
||||
/* This is a giant hack but until the timings become even more correct, this is needed to make floppies work right on that BIOS. */
|
||||
if (fdd_get_turbo(drive))
|
||||
{
|
||||
return (32.0 * dusec);
|
||||
}
|
||||
|
||||
if (romset == ROM_MRTHOR)
|
||||
{
|
||||
return (ddbp * dusec) / 4.0;
|
||||
}
|
||||
else
|
||||
{
|
||||
return (ddbp * dusec);
|
||||
}
|
||||
}
|
||||
|
||||
void floppy_poll(int drive)
|
||||
{
|
||||
if (drive >= FDD_NUM)
|
||||
{
|
||||
fatal("Attempting to poll floppy drive %i that is not supposed to be there\n", drive);
|
||||
}
|
||||
|
||||
floppy_poll_time[drive] += (int64_t) floppy_real_period(drive);
|
||||
|
||||
if (drives[drive].poll)
|
||||
drives[drive].poll(drive);
|
||||
|
||||
if (floppy_notfound)
|
||||
{
|
||||
floppy_notfound--;
|
||||
if (!floppy_notfound)
|
||||
fdc_noidam();
|
||||
}
|
||||
}
|
||||
|
||||
void floppy_poll_0(void *priv)
|
||||
{
|
||||
floppy_poll(0);
|
||||
}
|
||||
|
||||
void floppy_poll_1(void *priv)
|
||||
{
|
||||
floppy_poll(1);
|
||||
}
|
||||
|
||||
void floppy_poll_2(void *priv)
|
||||
{
|
||||
floppy_poll(2);
|
||||
}
|
||||
|
||||
void floppy_poll_3(void *priv)
|
||||
{
|
||||
floppy_poll(3);
|
||||
}
|
||||
|
||||
int floppy_get_bitcell_period(int rate)
|
||||
{
|
||||
int bit_rate = 250;
|
||||
|
||||
switch (rate)
|
||||
{
|
||||
case 0: /*High density*/
|
||||
bit_rate = 500;
|
||||
break;
|
||||
case 1: /*Double density (360 rpm)*/
|
||||
bit_rate = 300;
|
||||
break;
|
||||
case 2: /*Double density*/
|
||||
bit_rate = 250;
|
||||
break;
|
||||
case 3: /*Extended density*/
|
||||
bit_rate = 1000;
|
||||
break;
|
||||
}
|
||||
|
||||
return 1000000 / bit_rate*2; /*Bitcell period in ns*/
|
||||
}
|
||||
|
||||
|
||||
void floppy_set_rate(int drive, int drvden, int rate)
|
||||
{
|
||||
switch (rate)
|
||||
{
|
||||
case 0: /*High density*/
|
||||
floppy_period = 16;
|
||||
break;
|
||||
case 1:
|
||||
switch(drvden)
|
||||
{
|
||||
case 0: /*Double density (360 rpm)*/
|
||||
floppy_period = 26;
|
||||
break;
|
||||
case 1: /*High density (360 rpm)*/
|
||||
floppy_period = 16;
|
||||
break;
|
||||
case 2:
|
||||
floppy_period = 4;
|
||||
break;
|
||||
}
|
||||
case 2: /*Double density*/
|
||||
floppy_period = 32;
|
||||
break;
|
||||
case 3: /*Extended density*/
|
||||
floppy_period = 8;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void floppy_reset()
|
||||
{
|
||||
curdrive = 0;
|
||||
floppy_period = 32;
|
||||
timer_add(floppy_poll_0, &(floppy_poll_time[0]), &(motoron[0]), NULL);
|
||||
timer_add(floppy_poll_1, &(floppy_poll_time[1]), &(motoron[1]), NULL);
|
||||
timer_add(floppy_poll_2, &(floppy_poll_time[2]), &(motoron[2]), NULL);
|
||||
timer_add(floppy_poll_3, &(floppy_poll_time[3]), &(motoron[3]), NULL);
|
||||
}
|
||||
|
||||
void floppy_init()
|
||||
{
|
||||
drives[0].poll = drives[1].poll = drives[2].poll = drives[3].poll = 0;
|
||||
drives[0].seek = drives[1].seek = drives[2].seek = drives[3].seek = 0;
|
||||
drives[0].readsector = drives[1].readsector = drives[2].readsector = drives[3].readsector = 0;
|
||||
floppy_reset();
|
||||
}
|
||||
|
||||
int oldtrack[FDD_NUM] = {0, 0, 0, 0};
|
||||
void floppy_seek(int drive, int track)
|
||||
{
|
||||
if (drives[drive].seek)
|
||||
drives[drive].seek(drive, track);
|
||||
}
|
||||
|
||||
void floppy_readsector(int drive, int sector, int track, int side, int density, int sector_size)
|
||||
{
|
||||
drive = real_drive(drive);
|
||||
|
||||
if (drives[drive].readsector)
|
||||
drives[drive].readsector(drive, sector, track, side, density, sector_size);
|
||||
else
|
||||
floppy_notfound = 1000;
|
||||
}
|
||||
|
||||
void floppy_writesector(int drive, int sector, int track, int side, int density, int sector_size)
|
||||
{
|
||||
drive = real_drive(drive);
|
||||
|
||||
if (drives[drive].writesector)
|
||||
drives[drive].writesector(drive, sector, track, side, density, sector_size);
|
||||
else
|
||||
floppy_notfound = 1000;
|
||||
}
|
||||
|
||||
void floppy_comparesector(int drive, int sector, int track, int side, int density, int sector_size)
|
||||
{
|
||||
drive = real_drive(drive);
|
||||
|
||||
if (drives[drive].comparesector)
|
||||
drives[drive].comparesector(drive, sector, track, side, density, sector_size);
|
||||
else
|
||||
floppy_notfound = 1000;
|
||||
}
|
||||
|
||||
void floppy_readaddress(int drive, int side, int density)
|
||||
{
|
||||
drive = real_drive(drive);
|
||||
|
||||
if (drives[drive].readaddress)
|
||||
drives[drive].readaddress(drive, side, density);
|
||||
}
|
||||
|
||||
void floppy_format(int drive, int side, int density, uint8_t fill)
|
||||
{
|
||||
drive = real_drive(drive);
|
||||
|
||||
if (drives[drive].format)
|
||||
drives[drive].format(drive, side, density, fill);
|
||||
else
|
||||
floppy_notfound = 1000;
|
||||
}
|
||||
|
||||
void floppy_stop(int drive)
|
||||
{
|
||||
drive = real_drive(drive);
|
||||
|
||||
if (drives[drive].stop)
|
||||
drives[drive].stop(drive);
|
||||
}
|
||||
|
||||
void floppy_general_init(void)
|
||||
{
|
||||
floppy_init();
|
||||
img_init();
|
||||
d86f_init();
|
||||
td0_init();
|
||||
imd_init();
|
||||
|
||||
floppy_load(0, floppyfns[0]);
|
||||
floppy_load(1, floppyfns[1]);
|
||||
floppy_load(2, floppyfns[2]);
|
||||
floppy_load(3, floppyfns[3]);
|
||||
}
|
||||
@@ -1,248 +0,0 @@
|
||||
/*
|
||||
* 86Box A hypervisor and IBM PC system emulator that specializes in
|
||||
* running old operating systems and software designed for IBM
|
||||
* PC systems and compatibles from 1981 through fairly recent
|
||||
* system designs based on the PCI bus.
|
||||
*
|
||||
* This file is part of the 86Box distribution.
|
||||
*
|
||||
* Generic floppy disk interface that communicates with the
|
||||
* other handlers.
|
||||
*
|
||||
* Version: @(#)floppy.h 1.0.6 2017/11/04
|
||||
*
|
||||
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
*
|
||||
* Copyright 2008-2017 Sarah Walker.
|
||||
* Copyright 2016,2017 Miran Grca.
|
||||
*/
|
||||
#ifndef EMU_FLOPPY_H
|
||||
# define EMU_FLOPPY_H
|
||||
|
||||
|
||||
#define FDD_NUM 4
|
||||
|
||||
|
||||
typedef struct {
|
||||
void (*seek)(int drive, int track);
|
||||
void (*readsector)(int drive, int sector, int track, int side, int density, int sector_size);
|
||||
void (*writesector)(int drive, int sector, int track, int side, int density, int sector_size);
|
||||
void (*comparesector)(int drive, int sector, int track, int side, int density, int sector_size);
|
||||
void (*readaddress)(int drive, int side, int density);
|
||||
void (*format)(int drive, int side, int density, uint8_t fill);
|
||||
int (*hole)(int drive);
|
||||
double (*byteperiod)(int drive);
|
||||
void (*stop)(int drive);
|
||||
void (*poll)(int drive);
|
||||
} DRIVE;
|
||||
|
||||
|
||||
extern DRIVE drives[FDD_NUM];
|
||||
extern wchar_t floppyfns[FDD_NUM][512];
|
||||
extern int driveempty[FDD_NUM];
|
||||
extern int64_t floppy_poll_time[FDD_NUM];
|
||||
extern int ui_writeprot[FDD_NUM];
|
||||
|
||||
extern int curdrive;
|
||||
|
||||
extern int floppy_time;
|
||||
extern int64_t floppytime;
|
||||
|
||||
|
||||
extern void floppy_load(int drive, wchar_t *fn);
|
||||
extern void floppy_new(int drive, char *fn);
|
||||
extern void floppy_close(int drive);
|
||||
extern void floppy_init(void);
|
||||
extern void floppy_general_init(void);
|
||||
extern void floppy_reset(void);
|
||||
extern void floppy_poll(int drive);
|
||||
extern void floppy_poll_0(void* priv);
|
||||
extern void floppy_poll_1(void* priv);
|
||||
extern void floppy_poll_2(void* priv);
|
||||
extern void floppy_poll_3(void* priv);
|
||||
extern void floppy_seek(int drive, int track);
|
||||
extern void floppy_readsector(int drive, int sector, int track,
|
||||
int side, int density, int sector_size);
|
||||
extern void floppy_writesector(int drive, int sector, int track,
|
||||
int side, int density, int sector_size);
|
||||
extern void floppy_comparesector(int drive, int sector, int track,
|
||||
int side, int density, int sector_size);
|
||||
extern void floppy_readaddress(int drive, int side, int density);
|
||||
extern void floppy_format(int drive, int side, int density, uint8_t fill);
|
||||
extern int floppy_hole(int drive);
|
||||
extern double floppy_byteperiod(int drive);
|
||||
extern void floppy_stop(int drive);
|
||||
extern int floppy_empty(int drive);
|
||||
extern void floppy_set_rate(int drive, int drvden, int rate);
|
||||
|
||||
extern void fdc_callback(void *priv);
|
||||
extern int fdc_data(uint8_t dat);
|
||||
extern void fdc_spindown(void);
|
||||
extern void fdc_finishread(void);
|
||||
extern void fdc_datacrcerror(void);
|
||||
extern void fdc_headercrcerror(void);
|
||||
extern void fdc_writeprotect(void);
|
||||
extern int fdc_getdata(int last);
|
||||
extern void fdc_sectorid(uint8_t track, uint8_t side, uint8_t sector,
|
||||
uint8_t size, uint8_t crc1, uint8_t crc2);
|
||||
extern void fdc_indexpulse(void);
|
||||
|
||||
#if 0
|
||||
extern int fdc_time;
|
||||
extern int fdc_ready;
|
||||
extern int fdc_indexcount;
|
||||
#endif
|
||||
|
||||
extern int motorspin;
|
||||
extern int64_t motoron[FDD_NUM];
|
||||
|
||||
extern int swwp;
|
||||
extern int disable_write;
|
||||
|
||||
extern int defaultwriteprot;
|
||||
|
||||
extern int writeprot[FDD_NUM], fwriteprot[FDD_NUM];
|
||||
extern int floppy_track[FDD_NUM];
|
||||
extern int floppy_changed[FDD_NUM];
|
||||
extern int drive_empty[FDD_NUM];
|
||||
extern int drive_type[FDD_NUM];
|
||||
|
||||
/*Used in the Read A Track command. Only valid for floppy_readsector(). */
|
||||
#define SECTOR_FIRST -2
|
||||
#define SECTOR_NEXT -1
|
||||
|
||||
#if 0
|
||||
/* Bits 0-3 define byte type, bit 5 defines whether it is a per-track (0) or per-sector (1) byte, if bit 7 is set, the byte is the index hole. */
|
||||
#define BYTE_GAP0 0x00
|
||||
#define BYTE_GAP1 0x10
|
||||
#define BYTE_GAP4 0x20
|
||||
#define BYTE_GAP2 0x40
|
||||
#define BYTE_GAP3 0x50
|
||||
#define BYTE_I_SYNC 0x01
|
||||
#define BYTE_ID_SYNC 0x41
|
||||
#define BYTE_DATA_SYNC 0x51
|
||||
#define BYTE_IAM_SYNC 0x02
|
||||
#define BYTE_IDAM_SYNC 0x42
|
||||
#define BYTE_DATAAM_SYNC 0x52
|
||||
#define BYTE_IAM 0x03
|
||||
#define BYTE_IDAM 0x43
|
||||
#define BYTE_DATAAM 0x53
|
||||
#define BYTE_ID 0x44
|
||||
#define BYTE_DATA 0x54
|
||||
#define BYTE_ID_CRC 0x45
|
||||
#define BYTE_DATA_CRC 0x55
|
||||
|
||||
#define BYTE_IS_FUZZY 0x80
|
||||
#define BYTE_INDEX_HOLE 0x80 /* 1 = index hole, 0 = regular byte */
|
||||
#define BYTE_IS_SECTOR 0x40 /* 1 = per-sector, 0 = per-track */
|
||||
#define BYTE_IS_POST_TRACK 0x20 /* 1 = after all sectors, 0 = before or during all sectors */
|
||||
#define BYTE_IS_DATA 0x10 /* 1 = data, 0 = id */
|
||||
#define BYTE_TYPE 0x0F /* 5 = crc, 4 = data, 3 = address mark, 2 = address mark sync, 1 = sync, 0 = gap */
|
||||
|
||||
#define BYTE_TYPE_GAP 0x00
|
||||
#define BYTE_TYPE_SYNC 0x01
|
||||
#define BYTE_TYPE_AM_SYNC 0x02
|
||||
#define BYTE_TYPE_AM 0x03
|
||||
#define BYTE_TYPE_DATA 0x04
|
||||
#define BYTE_TYPE_CRC 0x05
|
||||
#endif
|
||||
|
||||
typedef union {
|
||||
uint16_t word;
|
||||
uint8_t bytes[2];
|
||||
} crc_t;
|
||||
|
||||
void floppy_calccrc(uint8_t byte, crc_t *crc_var);
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint16_t (*disk_flags)(int drive);
|
||||
uint16_t (*side_flags)(int drive);
|
||||
void (*writeback)(int drive);
|
||||
void (*set_sector)(int drive, int side, uint8_t c, uint8_t h, uint8_t r, uint8_t n);
|
||||
uint8_t (*read_data)(int drive, int side, uint16_t pos);
|
||||
void (*write_data)(int drive, int side, uint16_t pos, uint8_t data);
|
||||
int (*format_conditions)(int drive);
|
||||
int32_t (*extra_bit_cells)(int drive, int side);
|
||||
uint16_t* (*encoded_data)(int drive, int side);
|
||||
void (*read_revolution)(int drive);
|
||||
uint32_t (*index_hole_pos)(int drive, int side);
|
||||
uint32_t (*get_raw_size)(int drive, int side);
|
||||
uint8_t check_crc;
|
||||
} d86f_handler_t;
|
||||
|
||||
d86f_handler_t d86f_handler[FDD_NUM];
|
||||
|
||||
void d86f_common_handlers(int drive);
|
||||
|
||||
int d86f_is_40_track(int drive);
|
||||
|
||||
void d86f_reset_index_hole_pos(int drive, int side);
|
||||
|
||||
uint16_t d86f_prepare_pretrack(int drive, int side, int iso);
|
||||
uint16_t d86f_prepare_sector(int drive, int side, int prev_pos, uint8_t *id_buf, uint8_t *data_buf, int data_len, int gap2, int gap3, int deleted, int bad_crc);
|
||||
|
||||
extern int gap3_sizes[5][8][48];
|
||||
|
||||
void null_writeback(int drive);
|
||||
void null_write_data(int drive, int side, uint16_t pos, uint8_t data);
|
||||
int null_format_conditions(int drive);
|
||||
void d86f_unregister(int drive);
|
||||
|
||||
extern uint8_t dmf_r[21];
|
||||
extern uint8_t xdf_physical_sectors[2][2];
|
||||
extern uint8_t xdf_gap3_sizes[2][2];
|
||||
extern uint16_t xdf_trackx_spos[2][8];
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint8_t h;
|
||||
uint8_t r;
|
||||
} xdf_id_t;
|
||||
|
||||
typedef union
|
||||
{
|
||||
uint16_t word;
|
||||
xdf_id_t id;
|
||||
} xdf_sector_t;
|
||||
|
||||
extern xdf_sector_t xdf_img_layout[2][2][46];
|
||||
extern xdf_sector_t xdf_disk_layout[2][2][38];
|
||||
|
||||
uint32_t td0_get_raw_tsize(int side_flags, int slower_rpm);
|
||||
|
||||
void d86f_set_track_pos(int drive, uint32_t track_pos);
|
||||
|
||||
int32_t null_extra_bit_cells(int drive, int side);
|
||||
uint16_t* common_encoded_data(int drive, int side);
|
||||
|
||||
void common_read_revolution(int drive);
|
||||
void null_set_sector(int drive, int side, uint8_t c, uint8_t h, uint8_t r, uint8_t n);
|
||||
|
||||
uint32_t null_index_hole_pos(int drive, int side);
|
||||
|
||||
uint32_t common_get_raw_size(int drive, int side);
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint8_t c;
|
||||
uint8_t h;
|
||||
uint8_t r;
|
||||
uint8_t n;
|
||||
} sector_id_fields_t;
|
||||
|
||||
typedef union
|
||||
{
|
||||
uint32_t dword;
|
||||
uint8_t byte_array[4];
|
||||
sector_id_fields_t id;
|
||||
} sector_id_t;
|
||||
|
||||
void d86f_set_version(int drive, uint16_t version);
|
||||
|
||||
void d86f_initialize_last_sector_id(int drive, int c, int h, int r, int n);
|
||||
void d86f_zero_bit_field(int drive, int side);
|
||||
|
||||
|
||||
#endif /*EMU_FLOPPY_H*/
|
||||
@@ -1,34 +0,0 @@
|
||||
/*
|
||||
* 86Box A hypervisor and IBM PC system emulator that specializes in
|
||||
* running old operating systems and software designed for IBM
|
||||
* PC systems and compatibles from 1981 through fairly recent
|
||||
* system designs based on the PCI bus.
|
||||
*
|
||||
* This file is part of the 86Box distribution.
|
||||
*
|
||||
* Shared code for all the floppy modules.
|
||||
*
|
||||
* Version: @(#)floppy_common.h 1.0.1 2017/09/10
|
||||
*
|
||||
* Author: Fred N. van Kempen, <decwiz@yahoo.com>
|
||||
* Copyright 2017 Fred N. van Kempen.
|
||||
*/
|
||||
#ifndef FLOPPY_COMMON_H
|
||||
# define FLOPPY_COMMON_H
|
||||
|
||||
|
||||
extern uint8_t floppy_holes[6];
|
||||
extern uint8_t floppy_rates[6];
|
||||
extern double floppy_bit_rates_300[6];
|
||||
extern uint8_t floppy_max_sectors[8][6];
|
||||
extern uint8_t floppy_dmf_r[21];
|
||||
|
||||
|
||||
extern int floppy_get_gap3_size(int rate, int size, int sector);
|
||||
extern uint8_t floppy_sector_size_code(int size);
|
||||
extern int floppy_sector_code_size(uint8_t code);
|
||||
extern int floppy_bps_valid(uint16_t bps);
|
||||
extern int floppy_interleave(int sector, int skew, int spt);
|
||||
|
||||
|
||||
#endif /*FLOPPY_COMMON_H*/
|
||||
Reference in New Issue
Block a user