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:
OBattler
2018-01-17 18:43:36 +01:00
parent 74ca5cdc21
commit 5318bc08d8
72 changed files with 3475 additions and 3345 deletions

View File

@@ -21,7 +21,7 @@ Building
--------
In order to compile 86Box from this repository, please follow this step-by-step
guide:
1. Download the development environment from http://tinyurl.com/pcemude.
1. Download the development environment from http://tinyurl.com/de86box.
Afterwards, extract it to your desired location. Of course, also clone
the repository in your desired location. Downloading ZIPs is not recommended,
as it makes it more inconvenient to keep the code up-to-date. To avoid

View File

@@ -9,7 +9,7 @@
* Implementation of the CD-ROM drive with SCSI(-like)
* commands, for both ATAPI and SCSI usage.
*
* Version: @(#)cdrom.c 1.0.27 2018/01/10
* Version: @(#)cdrom.c 1.0.28 2018/01/17
*
* Author: Miran Grca, <mgrca8@gmail.com>
*
@@ -235,6 +235,53 @@ static const mode_sense_pages_t cdrom_mode_sense_pages_default =
{ GPMODE_CAPABILITIES_PAGE, 0x14, 0x3B, 0, 0x71, 0x60, 0x29, 0, 0x02, 0xC2, 0, 2, 0, 0, 0x02, 0xC2, 0, 0, 0, 0, 0, 0 }
} };
static const mode_sense_pages_t cdrom_mode_sense_pages_default_scsi =
{ {
{ 0, 0 },
{ GPMODE_R_W_ERROR_PAGE, 6, 0, 5, 0, 0, 0, 0 },
{ 0, 0 },
{ 0, 0 },
{ 0, 0 },
{ 0, 0 },
{ 0, 0 },
{ 0, 0 },
{ 0, 0 },
{ 0, 0 },
{ 0, 0 },
{ 0, 0 },
{ 0, 0 },
{ GPMODE_CDROM_PAGE, 6, 0, 1, 0, 60, 0, 75 },
{ 0x8E, 0xE, 5, 4, 0,0x80,0, 75, 1, 0xFF, 2, 0xFF, 0, 0, 0, 0 },
{ 0, 0 },
{ 0, 0 },
{ 0, 0 },
{ 0, 0 },
{ 0, 0 },
{ 0, 0 },
{ 0, 0 },
{ 0, 0 },
{ 0, 0 },
{ 0, 0 },
{ 0, 0 },
{ 0, 0 },
{ 0, 0 },
{ 0, 0 },
{ 0, 0 },
{ 0, 0 },
{ 0, 0 },
{ 0, 0 },
{ 0, 0 },
{ 0, 0 },
{ 0, 0 },
{ 0, 0 },
{ 0, 0 },
{ 0, 0 },
{ 0, 0 },
{ 0, 0 },
{ 0, 0 },
{ GPMODE_CAPABILITIES_PAGE, 0x14, 0x3B, 0, 0x71, 0x60, 0x29, 0, 0x02, 0xC2, 0, 2, 0, 0, 0x02, 0xC2, 0, 0, 0, 0, 0, 0 }
} };
static const mode_sense_pages_t cdrom_mode_sense_pages_changeable =
{ {
{ 0, 0 },
@@ -251,7 +298,7 @@ static const mode_sense_pages_t cdrom_mode_sense_pages_changeable =
{ 0, 0 },
{ 0, 0 },
{ GPMODE_CDROM_PAGE, 6, 0, 1, 0, 60, 0, 75 },
{ 0x8E, 0xE, 4, 0, 0, 0, 0, 75, 1, 0xFF, 2, 0xFF, 0, 0, 0, 0 },
{ 0x8E, 0xE, 5, 4, 0,0x80,0, 75, 1, 0xFF, 2, 0xFF, 0, 0, 0, 0 },
{ 0, 0 },
{ 0, 0 },
{ 0, 0 },
@@ -509,11 +556,18 @@ void cdrom_mode_sense_load(uint8_t id)
int i;
memset(&cdrom_mode_sense_pages_saved[id], 0, sizeof(mode_sense_pages_t));
for (i = 0; i < 0x3f; i++) {
if (cdrom_mode_sense_pages_default.pages[i][1] != 0)
memcpy(cdrom_mode_sense_pages_saved[id].pages[i], cdrom_mode_sense_pages_default.pages[i], cdrom_mode_sense_pages_default.pages[i][1] + 2);
if (cdrom_mode_sense_pages_default.pages[i][1] != 0) {
if (cdrom_drives[id].bus_type == CDROM_BUS_SCSI)
memcpy(cdrom_mode_sense_pages_saved[id].pages[i], cdrom_mode_sense_pages_default_scsi.pages[i], cdrom_mode_sense_pages_default_scsi.pages[i][1] + 2);
else
memcpy(cdrom_mode_sense_pages_saved[id].pages[i], cdrom_mode_sense_pages_default.pages[i], cdrom_mode_sense_pages_default.pages[i][1] + 2);
}
}
memset(file_name, 0, 512 * sizeof(wchar_t));
swprintf(file_name, 512, L"cdrom_%02i_mode_sense_bin", id);
if (cdrom_drives[id].bus_type == CDROM_BUS_SCSI)
swprintf(file_name, 512, L"scsi_cdrom_%02i_mode_sense_bin", id);
else
swprintf(file_name, 512, L"cdrom_%02i_mode_sense_bin", id);
f = plat_fopen(nvr_path(file_name), L"rb");
if (f) {
fread(cdrom_mode_sense_pages_saved[id].pages[GPMODE_CDROM_AUDIO_PAGE], 1, 0x10, f);
@@ -526,7 +580,10 @@ void cdrom_mode_sense_save(uint8_t id)
FILE *f;
wchar_t file_name[512];
memset(file_name, 0, 512 * sizeof(wchar_t));
swprintf(file_name, 512, L"cdrom_%02i_mode_sense_bin", id);
if (cdrom_drives[id].bus_type == CDROM_BUS_SCSI)
swprintf(file_name, 512, L"scsi_cdrom_%02i_mode_sense_bin", id);
else
swprintf(file_name, 512, L"cdrom_%02i_mode_sense_bin", id);
f = plat_fopen(nvr_path(file_name), L"wb");
if (f) {
fwrite(cdrom_mode_sense_pages_saved[id].pages[GPMODE_CDROM_AUDIO_PAGE], 1, 0x10, f);
@@ -576,7 +633,10 @@ uint8_t cdrom_mode_sense_read(uint8_t id, uint8_t page_control, uint8_t page, ui
return cdrom_mode_sense_pages_changeable.pages[page][pos];
break;
case 2:
return cdrom_mode_sense_pages_default.pages[page][pos];
if (cdrom_drives[id].bus_type == CDROM_BUS_SCSI)
return cdrom_mode_sense_pages_default_scsi.pages[page][pos];
else
return cdrom_mode_sense_pages_default.pages[page][pos];
break;
}
@@ -2515,7 +2575,10 @@ uint8_t cdrom_phase_data_out(uint8_t id)
pos += page_len;
val = cdrom_mode_sense_pages_default.pages[page][0] & 0x80;
if (cdrom_drives[id].bus_type == CDROM_BUS_SCSI)
val = cdrom_mode_sense_pages_default_scsi.pages[page][0] & 0x80;
else
val = cdrom_mode_sense_pages_default.pages[page][0] & 0x80;
if (cdrom[id].do_page_save && val)
cdrom_mode_sense_save(id);

View File

@@ -8,16 +8,16 @@
*
* Configuration file handler.
*
* Version: @(#)config.c 1.0.36 2017/12/28
* Version: @(#)config.c 1.0.37 2018/01/16
*
* Authors: Sarah Walker,
* Miran Grca, <mgrca8@gmail.com>
* Fred N. van Kempen, <decwiz@yahoo.com>
* Overdoze,
*
* Copyright 2008-2017 Sarah Walker.
* Copyright 2016,2017 Miran Grca.
* Copyright 2017 Fred N. van Kempen.
* Copyright 2008-2018 Sarah Walker.
* Copyright 2016-2018 Miran Grca.
* Copyright 2017,2018 Fred N. van Kempen.
*
* NOTE: Forcing config files to be in Unicode encoding breaks
* it on Windows XP, and possibly also Vista. Use the
@@ -39,9 +39,8 @@
#include "disk/hdd.h"
#include "disk/hdc.h"
#include "disk/hdc_ide.h"
#include "floppy/floppy.h"
#include "floppy/fdc.h"
#include "floppy/fdd.h"
#include "floppy/fdc.h"
#include "game/gameport.h"
#include "machine/machine.h"
#include "mouse.h"

View File

@@ -16,7 +16,7 @@
#include "../pic.h"
#include "../pit.h"
#include "../timer.h"
#include "../floppy/floppy.h"
#include "../floppy/fdd.h"
#include "../floppy/fdc.h"
#include "386_common.h"

View File

@@ -17,7 +17,7 @@
#include "../nmi.h"
#include "../pic.h"
#include "../timer.h"
#include "../floppy/floppy.h"
#include "../floppy/fdd.h"
#include "../floppy/fdc.h"
#ifdef USE_DYNAREC
#include "codegen.h"

File diff suppressed because it is too large Load Diff

View File

@@ -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*/

View File

@@ -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]);
}

View File

@@ -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
}

View File

@@ -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];

View File

@@ -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

View File

@@ -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
View 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*/

View File

@@ -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;
}

View File

@@ -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;

View File

@@ -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;

View File

@@ -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) {

View File

@@ -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;

View File

@@ -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]);
}

View File

@@ -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*/

View File

@@ -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*/

View File

@@ -8,15 +8,15 @@
*
* Intel 8042 (AT keyboard controller) emulation.
*
* Version: @(#)keyboard_at.c 1.0.22 2018/01/09
* Version: @(#)keyboard_at.c 1.0.24 2018/01/17
*
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
* Miran Grca, <mgrca8@gmail.com>
* Fred N. van Kempen, <decwiz@yahoo.com>
*
* Copyright 2008-2018 Sarah Walker.
* Copyright 2016,2018 Miran Grca.
* Copyright 2018 Fred N. van Kempen.
* Copyright 2016-2018 Miran Grca.
* Copyright 2017,2018 Fred N. van Kempen.
*/
#include <stdio.h>
#include <stdint.h>
@@ -37,7 +37,7 @@
#include "timer.h"
#include "machine/machine.h"
#include "machine/m_at_t3100e.h"
#include "floppy/floppy.h"
#include "floppy/fdd.h"
#include "floppy/fdc.h"
#include "sound/sound.h"
#include "sound/snd_speaker.h"
@@ -936,8 +936,6 @@ kbd_output_write(atkbd_t *kbd, uint8_t val)
static void
kbd_cmd_write(atkbd_t *kbd, uint8_t val)
{
uint8_t temp_op = kbd->output_port;
kbdlog("Write command byte: %02X (old: %02X)\n", val, kbd->mem[0]);
if ((val & 1) && (kbd->status & STAT_OFULL))
@@ -959,9 +957,6 @@ kbd_cmd_write(atkbd_t *kbd, uint8_t val)
kbdlog("ATkbd: keyboard is now %s\n", mouse_scan ? "enabled" : "disabled");
kbdlog("ATkbd: keyboard interrupt is now %s\n", (val & 0x01) ? "enabled" : "disabled");
temp_op &= 0xbf;
temp_op |= (keyboard_scan ? 0x40 : 0x00);
/* ISA AT keyboard controllers use bit 5 for keyboard mode (1 = PC/XT, 2 = AT);
PS/2 (and EISA/PCI) keyboard controllers use it as the PS/2 mouse enable switch. */
if ((kbd->flags & KBC_TYPE_MASK) >= KBC_TYPE_PS2_1) {
@@ -970,9 +965,6 @@ kbd_cmd_write(atkbd_t *kbd, uint8_t val)
mouse_scan = !(val & 0x20);
kbdlog("ATkbd: mouse is now %s\n", mouse_scan ? "enabled" : "disabled");
temp_op &= 0xf7;
temp_op |= (mouse_scan ? 0x08 : 0x00);
kbdlog("ATkbd: mouse interrupt is now %s\n", (val & 0x02) ? "enabled" : "disabled");
}
@@ -1033,21 +1025,24 @@ kbd_write64_generic(void *p, uint8_t val)
kbdlog("ATkbd: check if password installed\n");
kbd_adddata(0xf1);
return 0;
}
} else
kbdlog("ATkbd: bad command A4\n");
break;
case 0xa7: /*Disable mouse port*/
if ((kbd->flags & KBC_TYPE_MASK) >= KBC_TYPE_PS2_1) {
kbdlog("ATkbd: disable mouse port\n");
kbd_mouse_set(kbd, 0);
return 0;
}
} else
kbdlog("ATkbd: bad command A7\n");
break;
case 0xa8: /*Enable mouse port*/
if ((kbd->flags & KBC_TYPE_MASK) >= KBC_TYPE_PS2_1) {
kbdlog("ATkbd: enable mouse port\n");
kbd_mouse_set(kbd, 1);
return 0;
}
} else
kbdlog("ATkbd: bad command A8\n");
break;
case 0xa9: /*Test mouse port*/
kbdlog("ATkbd: test mouse port\n");
@@ -1057,7 +1052,9 @@ kbd_write64_generic(void *p, uint8_t val)
else
kbd_adddata(0xff); /*no mouse*/
return 0;
}
} else
kbdlog("ATkbd: bad command A9\n");
break;
case 0xaf: /*Read keyboard version*/
kbdlog("ATkbd: read keyboard version\n");
kbd_adddata(0x00);
@@ -1475,10 +1472,13 @@ kbd_write(uint16_t port, uint8_t val, void *priv)
case 0xd4: /*Write to mouse*/
kbdlog("ATkbd: write to mouse (%02X)\n", val);
kbd_mouse_set(kbd, 1);
if (mouse_write && ((kbd->flags & KBC_TYPE_MASK) >= KBC_TYPE_PS2_1))
if (mouse_write && ((kbd->flags & KBC_TYPE_MASK) >= KBC_TYPE_PS2_1)) {
pclog("Mouse write\n");
mouse_write(val, mouse_p);
else if (!mouse_write && ((kbd->flags & KBC_TYPE_MASK) >= KBC_TYPE_PS2_1))
} else if (!mouse_write && ((kbd->flags & KBC_TYPE_MASK) >= KBC_TYPE_PS2_1)) {
pclog("Adding 0xFF to queue\n");
keyboard_at_adddata_mouse(0xff);
}
break;
default:
@@ -1786,6 +1786,7 @@ kbd_read(uint16_t port, void *priv)
switch (port) {
case 0x60:
ret = kbd->out;
pclog("Reading: %02X\n", ret);
kbd->status &= ~(STAT_OFULL);
picintc(kbd->last_irq);
kbd->last_irq = 0;
@@ -1806,7 +1807,9 @@ kbd_read(uint16_t port, void *priv)
case 0x64:
ret = (kbd->status & 0xFB) | (keyboard_mode & CCB_SYSTEM);
ret |= STAT_LOCK;
kbd->status &= ~(STAT_RTIMEOUT | STAT_TTIMEOUT);
/* The transmit timeout (TTIMEOUT) flag should *NOT* be cleared, otherwise
the IBM PS/2 Model 80's BIOS gives error 8601 (mouse error). */
kbd->status &= ~(STAT_RTIMEOUT/* | STAT_TTIMEOUT*/);
break;
}
@@ -2035,6 +2038,7 @@ keyboard_at_adddata_keyboard_raw(uint8_t val)
void
keyboard_at_adddata_mouse(uint8_t val)
{
pclog("Adding mouse data: %02X\n", val);
mouse_queue[mouse_queue_end] = val;
mouse_queue_end = (mouse_queue_end + 1) & 0xf;
}

View File

@@ -32,15 +32,15 @@
* in alpha mode, but in highres ("ECD350") mode, it displays
* some semi-random junk. Video-memory pointer maybe?
*
* Version: @(#)m_amstrad.c 1.0.5 2018/01/09
* Version: @(#)m_amstrad.c 1.0.5 2018/01/16
*
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
* Miran Grca, <mgrca8@gmail.com>
* Fred N. van Kempen, <decwiz@yahoo.com>
*
* Copyright 2008-2018 Sarah Walker.
* Copyright 2016,2018 Miran Grca.
* Copyright 2018 Fred N. van Kempen.
* Copyright 2016-2018 Miran Grca.
* Copyright 2017,2018 Fred N. van Kempen.
*/
#include <stdio.h>
#include <stdint.h>
@@ -63,7 +63,6 @@
#include "../mouse.h"
#include "../game/gameport.h"
#include "../lpt.h"
#include "../floppy/floppy.h"
#include "../floppy/fdd.h"
#include "../floppy/fdc.h"
#include "../sound/sound.h"
@@ -1274,5 +1273,5 @@ machine_amstrad_init(machine_t *model)
if (joystick_type != 7)
device_add(&gameport_device);
device_add(&fdc_xt_amstrad_device);

View File

@@ -11,10 +11,10 @@
* NOTE: The NEAT 82c206 code should be moved into a 82c206 module,
* so it can be re-used by other boards.
*
* Version: @(#)m_4gpv31.c 1.0.3 2018/01/04
* Version: @(#)m_4gpv31.c 1.0.4 2018/01/16
*
* Author: Fred N. van Kempen, <decwiz@yahoo.com>
* Copyright 2018 Fred N. van Kempen.
* Copyright 2017,2018 Fred N. van Kempen.
*/
#include <stdio.h>
#include <stdint.h>
@@ -25,6 +25,8 @@
#include "../io.h"
#include "../device.h"
#include "../keyboard.h"
#include "../floppy/fdd.h"
#include "../floppy/fdc.h"
#include "machine.h"
@@ -145,6 +147,7 @@ machine_at_4gpv31_init(machine_t *model)
{
machine_at_common_ide_init(model);
device_add(&keyboard_at_ami_device);
device_add(&fdc_at_device);
neat_init();
}

View File

@@ -11,6 +11,8 @@
#include "../mem.h"
#include "../device.h"
#include "../keyboard.h"
#include "../floppy/fdd.h"
#include "../floppy/fdc.h"
#include "../disk/hdc.h"
#include "../disk/hdc_ide.h"
#include "machine.h"
@@ -101,7 +103,9 @@ machine_at_ali1429_init(machine_t *model)
ali1429_reset();
machine_at_common_ide_init(model);
device_add(&keyboard_at_ami_device);
device_add(&fdc_at_device);
ali1429_init();

View File

@@ -3,9 +3,12 @@
#include <string.h>
#include <wchar.h>
#include "../86box.h"
#include "../device.h"
#include "../io.h"
#include "../lpt.h"
#include "../serial.h"
#include "../floppy/fdd.h"
#include "../floppy/fdc.h"
#include "machine.h"
@@ -46,6 +49,7 @@ void
machine_at_cmdpc_init(machine_t *model)
{
machine_at_ide_top_remap_init(model);
device_add(&fdc_at_device);
cbm_io_init();
}

View File

@@ -8,14 +8,14 @@
*
* Emulation of various Compaq PC's.
*
* Version: @(#)m_at_compaq.c 1.0.2 2017/12/29
* Version: @(#)m_at_compaq.c 1.0.3 2018/01/16
*
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
* Miran Grca, <mgrca8@gmail.com>
* TheCollector1995, <mariogplayer@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>
@@ -26,6 +26,8 @@
#include "../mem.h"
#include "../rom.h"
#include "../device.h"
#include "../floppy/fdd.h"
#include "../floppy/fdc.h"
#include "../disk/hdc.h"
#include "../disk/hdc_ide.h"
#include "machine.h"
@@ -99,6 +101,7 @@ void
machine_at_compaq_init(machine_t *model)
{
machine_at_top_remap_init(model);
device_add(&fdc_at_device);
mem_mapping_add(&ram_mapping, 0xfa0000, 0x60000,
read_ram, read_ramw, read_raml,

View File

@@ -12,6 +12,8 @@
#include "../device.h"
#include "../keyboard.h"
#include "../mem.h"
#include "../floppy/fdd.h"
#include "../floppy/fdc.h"
#include "machine.h"
@@ -71,7 +73,9 @@ void
machine_at_headland_init(machine_t *model)
{
machine_at_common_ide_init(model);
device_add(&keyboard_at_ami_device);
device_add(&fdc_at_device);
headland_init();
}

View File

@@ -10,6 +10,8 @@
#include "../device.h"
#include "../io.h"
#include "../keyboard.h"
#include "../floppy/fdd.h"
#include "../floppy/fdc.h"
#include "machine.h"
@@ -89,6 +91,7 @@ void
machine_at_neat_init(machine_t *model)
{
machine_at_init(model);
device_add(&fdc_at_device);
neat_init();
}
@@ -98,7 +101,9 @@ void
machine_at_neat_ami_init(machine_t *model)
{
machine_at_common_init(model);
device_add(&keyboard_at_ami_device);
device_add(&fdc_at_device);
neat_init();
}

View File

@@ -261,6 +261,8 @@ SeeAlso: #P0178,#P0187
#include "../device.h"
#include "../keyboard.h"
#include "../mem.h"
#include "../floppy/fdd.h"
#include "../floppy/fdc.h"
#include "machine.h"
@@ -324,7 +326,9 @@ void
machine_at_opti495_init(machine_t *model)
{
machine_at_common_ide_init(model);
device_add(&keyboard_at_device);
device_add(&fdc_at_device);
opti495_init();
}
@@ -334,7 +338,9 @@ void
machine_at_opti495_ami_init(machine_t *model)
{
machine_at_common_ide_init(model);
device_add(&keyboard_at_ami_device);
device_add(&fdc_at_device);
opti495_init();
}

View File

@@ -10,20 +10,23 @@
*
* Re-worked version based on the 82C235 datasheet and errata.
*
* Version: @(#)m_at_scat.c 1.0.7 2018/01/05
* Version: @(#)m_at_scat.c 1.0.8 2018/01/16
*
* Authors: Original by GreatPsycho for PCem.
* Fred N. van Kempen, <decwiz@yahoo.com>
*
* Copyright 2018 Fred N. van Kempen.
* Copyright 2017,2018 Fred N. van Kempen.
*/
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <wchar.h>
#include "../86box.h"
#include "../device.h"
#include "../cpu/cpu.h"
#include "../cpu/x86.h"
#include "../floppy/fdd.h"
#include "../floppy/fdc.h"
#include "../io.h"
#include "../mem.h"
#include "machine.h"
@@ -736,6 +739,7 @@ void
machine_at_scat_init(machine_t *model)
{
machine_at_init(model);
device_add(&fdc_at_device);
scat_init();
}

View File

@@ -9,11 +9,11 @@
* SiS sis85c471 Super I/O Chip
* Used by DTK PKM-0038S E-2
*
* Version: @(#)m_at_sis85c471.c 1.0.8 2017/11/04
* Version: @(#)m_at_sis85c471.c 1.0.9 2018/01/16
*
* Author: Miran Grca, <mgrca8@gmail.com>
*
* Copyright 2017 Miran Grca.
* Copyright 2015-2018 Miran Grca.
*/
#include <stdio.h>
#include <stdint.h>
@@ -27,9 +27,8 @@
#include "../serial.h"
#include "../disk/hdc.h"
#include "../disk/hdc_ide.h"
#include "../floppy/floppy.h"
#include "../floppy/fdc.h"
#include "../floppy/fdd.h"
#include "../floppy/fdc.h"
#include "machine.h"
@@ -236,9 +235,6 @@ static void sis_85c471_init(void)
sis_85c471_regs[0x23] = 0xF0;
sis_85c471_regs[0x26] = 1;
fdc_update_densel_polarity(1);
fdc_update_densel_force(0);
fdd_swap = 0;
io_sethandler(0x0022, 0x0002, sis_85c471_read, NULL, NULL, sis_85c471_write, NULL, NULL, NULL);
}
@@ -247,6 +243,7 @@ void
machine_at_dtk486_init(machine_t *model)
{
machine_at_ide_init(model);
device_add(&fdc_at_device);
memregs_init();
sis_85c471_init();

View File

@@ -12,6 +12,7 @@
#include "../keyboard.h"
#include "../cpu/cpu.h"
#include "../floppy/fdd.h"
#include "../floppy/fdc.h"
#include "../video/vid_t3100e.h"
#include "machine.h"
@@ -685,7 +686,9 @@ void machine_at_t3100e_init(machine_t *model)
memset(&t3100e_ems, 0, sizeof(t3100e_ems));
machine_at_common_ide_init(model);
device_add(&keyboard_at_toshiba_device);
device_add(&fdc_at_device);
/* Hook up system control port */
io_sethandler(0x8084, 0x0001,

View File

@@ -11,7 +11,7 @@
#include "../keyboard.h"
#include "../mem.h"
#include "../serial.h"
#include "../floppy/floppy.h"
#include "../floppy/fdd.h"
#include "../floppy/fdc.h"
#include "../video/vid_paradise.h"
#include "machine.h"
@@ -23,6 +23,9 @@ static uint16_t wd76c10_2872;
static uint16_t wd76c10_5872;
static fdc_t *wd76c10_fdc;
static uint16_t
wd76c10_read(uint16_t port, void *priv)
{
@@ -89,9 +92,9 @@ wd76c10_write(uint16_t port, uint16_t val, void *priv)
case 0x2872:
wd76c10_2872 = val;
fdc_remove();
fdc_remove(wd76c10_fdc);
if (!(val & 1))
fdc_add();
fdc_set_base(wd76c10_fdc, 0x03f0);
break;
case 0x5872:
@@ -142,7 +145,9 @@ void
machine_at_wd76c10_init(machine_t *model)
{
machine_at_common_ide_init(model);
device_add(&keyboard_ps2_quadtel_device);
wd76c10_fdc = device_add(&fdc_at_device);
wd76c10_init();

View File

@@ -67,7 +67,7 @@
*
* WARNING THIS IS A WORK-IN-PROGRESS MODULE. USE AT OWN RISK.
*
* Version: @(#)europc.c 1.0.5 2017/11/18
* Version: @(#)europc.c 1.0.6 2018/01/16
*
* Author: Fred N. van Kempen, <decwiz@yahoo.com>
*
@@ -76,7 +76,7 @@
* Schneider's schematics and technical manuals, and the
* input from people with real EuroPC hardware.
*
* Copyright 2017 Fred N. van Kempen.
* Copyright 2017,2018 Fred N. van Kempen.
*/
#include <stdio.h>
#include <stdint.h>
@@ -90,6 +90,8 @@
#include "../rom.h"
#include "../nvr.h"
#include "../device.h"
#include "../floppy/fdd.h"
#include "../floppy/fdc.h"
#include "../disk/hdc.h"
#include "../keyboard.h"
#include "../mouse.h"
@@ -700,6 +702,9 @@ machine_europc_init(machine_t *model)
/* Initialize the actual NVR. */
nvr_init(&vm->nvr);
/* Enable and set up the FDC. */
device_add(&fdc_xt_device);
/* Enable and set up the mainboard device. */
device_add(&europc_device);
}

View File

@@ -8,15 +8,15 @@
*
* Emulation of the Olivetti M24.
*
* Version: @(#)m_olivetti_m24.c 1.0.8 2018/01/09
* Version: @(#)m_olivetti_m24.c 1.0.9 2018/01/16
*
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
* Miran Grca, <mgrca8@gmail.com>
* Fred N. van Kempen, <decwiz@yahoo.com>
*
* Copyright 2008-2018 Sarah Walker.
* Copyright 2016,2018 Miran Grca.
* Copyright 2018 Fred N. van Kempen.
* Copyright 2016-2018 Miran Grca.
* Copyright 2017,2018 Fred N. van Kempen.
*/
#include <stdio.h>
#include <stdint.h>
@@ -36,6 +36,8 @@
#include "../nvr.h"
#include "../keyboard.h"
#include "../mouse.h"
#include "../floppy/fdd.h"
#include "../floppy/fdc.h"
#include "../game/gameport.h"
#include "../sound/sound.h"
#include "../sound/snd_speaker.h"
@@ -807,6 +809,7 @@ machine_olim24_init(machine_t *model)
memset(m24, 0x00, sizeof(olim24_t));
machine_common_init(model);
device_add(&fdc_xt_device);
io_sethandler(0x0066, 2, m24_read, NULL, NULL, NULL, NULL, NULL, m24);

View File

@@ -8,15 +8,15 @@
*
* Emulation of the IBM PCjr.
*
* Version: @(#)m_pcjr.c 1.0.3 2018/01/09
* Version: @(#)m_pcjr.c 1.0.4 2018/01/16
*
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
* Miran Grca, <mgrca8@gmail.com>
* Fred N. van Kempen, <decwiz@yahoo.com>
*
* Copyright 2008-2018 Sarah Walker.
* Copyright 2016,2018 Miran Grca.
* Copyright 2018 Fred N. van Kempen.
* Copyright 2016-2018 Miran Grca.
* Copyright 2017,2018 Fred N. van Kempen.
*/
#include <stdio.h>
#include <stdint.h>
@@ -34,9 +34,8 @@
#include "../device.h"
#include "../serial.h"
#include "../keyboard.h"
#include "../floppy/floppy.h"
#include "../floppy/fdc.h"
#include "../floppy/fdd.h"
#include "../floppy/fdc.h"
#include "../sound/sound.h"
#include "../sound/snd_speaker.h"
#include "../sound/snd_sn76489.h"
@@ -765,9 +764,9 @@ machine_pcjr_init(machine_t *model)
keyboard_set_table(scancode_xt);
keyboard_send = kbd_adddata_ex;
fdc_add_pcjr();
device_add(&sn76489_device);
nmi_mask = 0x80;
device_add(&fdc_pcjr_device);
}

View File

@@ -28,15 +28,15 @@
* boot. Sometimes, they do, and then it shows an "Incorrect
* DOS" error message?? --FvK
*
* Version: @(#)m_ps1.c 1.0.4 2018/01/04
* Version: @(#)m_ps1.c 1.0.5 2018/01/16
*
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
* Miran Grca, <mgrca8@gmail.com>
* Fred N. van Kempen, <decwiz@yahoo.com>
*
* Copyright 2008-2018 Sarah Walker.
* Copyright 2016,2018 Miran Grca.
* Copyright 2018 Fred N. van Kempen.
* Copyright 2016-2018 Miran Grca.
* Copyright 2017,2018 Fred N. van Kempen.
*/
#include <stdio.h>
#include <stdint.h>
@@ -61,7 +61,6 @@
#include "../keyboard.h"
#include "../disk/hdc.h"
#include "../disk/hdc_ide.h"
#include "../floppy/floppy.h"
#include "../floppy/fdd.h"
#include "../floppy/fdc.h"
#include "../sound/sound.h"
@@ -554,8 +553,13 @@ ps1_common_init(machine_t *model)
device_add(&keyboard_ps2_device);
if (romset != ROM_IBMPS1_2133) {
fdc_set_dskchg_activelow();
if (romset == ROM_IBMPS1_2133)
device_add(&fdc_at_device);
else {
if ((romset == ROM_IBMPS1_2121) || (romset == ROM_IBMPS1_2121_ISA))
device_add(&fdc_at_ps1_device);
else
device_add(&fdc_at_actlow_device);
device_add(&snd_device);
}
@@ -580,8 +584,6 @@ machine_ps1_m2121_init(machine_t *model)
ps1_common_init(model);
ps1_setup(2121);
fdc_set_ps1();
}

View File

@@ -15,7 +15,6 @@
#include "../keyboard.h"
#include "../lpt.h"
#include "../serial.h"
#include "../floppy/floppy.h"
#include "../floppy/fdd.h"
#include "../floppy/fdc.h"
#include "../video/vid_vga.h"
@@ -152,6 +151,7 @@ void
machine_ps2_m30_286_init(machine_t *model)
{
machine_common_init(model);
device_add(&fdc_at_ps1_device);
pit_set_out_func(&pit, 1, pit_refresh_timer_at);
dma16_init();
@@ -159,7 +159,5 @@ machine_ps2_m30_286_init(machine_t *model)
nvr_at_init(8);
pic2_init();
ps2board_init();
fdc_set_dskchg_activelow();
fdc_set_ps1();
device_add(&ps1vga_device);
}

View File

@@ -14,6 +14,8 @@
#include "../nmi.h"
#include "../rom.h"
#include "../device.h"
#include "../floppy/fdd.h"
#include "../floppy/fdc.h"
#include "../nvr.h"
#include "../nvr_ps2.h"
#include "../keyboard.h"
@@ -790,6 +792,7 @@ static void
machine_ps2_common_init(machine_t *model)
{
machine_common_init(model);
device_add(&fdc_at_device);
dma16_init();
ps2_dma_init();

View File

@@ -8,13 +8,13 @@
*
* Emulation of Tandy models 1000, 1000HX and 1000SL2.
*
* Version: @(#)m_tandy.c 1.0.1 2018/01/10
* Version: @(#)m_tandy.c 1.0.2 2018/01/16
*
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
* Miran Grca, <mgrca8@gmail.com>
*
* Copyright 2008-2018 Sarah Walker.
* Copyright 2016,2018 Miran Grca.
* Copyright 2016-2018 Miran Grca.
*/
#include <stdio.h>
#include <stdint.h>
@@ -31,6 +31,8 @@
#include "../timer.h"
#include "../device.h"
#include "../nvr.h"
#include "../floppy/fdd.h"
#include "../floppy/fdc.h"
#include "../game/gameport.h"
#include "../keyboard.h"
#include "../sound/sound.h"
@@ -1688,6 +1690,8 @@ machine_tandy1k_init(machine_t *model)
device_add(&keyboard_tandy_device);
keyboard_set_table(scancode_tandy);
device_add(&fdc_xt_device);
switch(romset) {
case ROM_TANDY:
io_sethandler(0x00a0, 1,

View File

@@ -7,6 +7,8 @@
#include "../pit.h"
#include "../mem.h"
#include "../device.h"
#include "../floppy/fdd.h"
#include "../floppy/fdc.h"
#include "../game/gameport.h"
#include "../keyboard.h"
#include "machine.h"
@@ -20,6 +22,7 @@ machine_xt_init(machine_t *model)
pit_set_out_func(&pit, 1, pit_refresh_timer_xt);
device_add(&keyboard_xt_device);
device_add(&fdc_xt_device);
nmi_init();
if (joystick_type != 7)
device_add(&gameport_device);

View File

@@ -8,14 +8,14 @@
*
* Emulation of various Compaq XT-class PC's.
*
* Version: @(#)m_xt_compaq.c 1.0.1 2017/11/11
* Version: @(#)m_xt_compaq.c 1.0.2 2018/01/16
*
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
* Miran Grca, <mgrca8@gmail.com>
* TheCollector1995, <mariogplayer@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>
@@ -28,6 +28,8 @@
#include "../mem.h"
#include "../rom.h"
#include "../device.h"
#include "../floppy/fdd.h"
#include "../floppy/fdc.h"
#include "../game/gameport.h"
#include "../keyboard.h"
#include "machine.h"
@@ -41,6 +43,7 @@ machine_xt_compaq_init(machine_t *model)
pit_set_out_func(&pit, 1, pit_refresh_timer_xt);
device_add(&keyboard_xt_device);
device_add(&fdc_xt_device);
nmi_init();
if (joystick_type != 7)
device_add(&gameport_device);

View File

@@ -8,7 +8,7 @@
*
* Handling of the emulated machines.
*
* Version: @(#)machine.c 1.0.28 2018/01/01
* Version: @(#)machine.c 1.0.29 2018/01/16
*
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
* Miran Grca, <mgrca8@gmail.com>
@@ -16,7 +16,7 @@
*
* Copyright 2008-2018 Sarah Walker.
* Copyright 2016-2018 Miran Grca.
* Copyright 2018 Fred N. van Kempen.
* Copyright 2017,2018 Fred N. van Kempen.
*/
#include <stdio.h>
#include <stdint.h>
@@ -31,9 +31,6 @@
#include "../rom.h"
#include "../lpt.h"
#include "../serial.h"
#include "../floppy/floppy.h"
#include "../floppy/fdd.h"
#include "../floppy/fdc.h"
#include "../disk/hdc.h"
#include "../disk/hdc_ide.h"
#include "machine.h"
@@ -80,6 +77,4 @@ machine_common_init(machine_t *model)
if (serial_enabled[1])
serial_setup(2, SERIAL2_ADDR, SERIAL2_IRQ);
fdc_add();
}

View File

@@ -256,6 +256,34 @@ int mmu_page_fault_check(uint32_t addr, int rw, uint32_t flags, int pde, int is_
#define PAGE_DIRTY 0x40
#define PAGE_ACCESSED 0x20
/* This is needed so that mmutranslate reads things from the correct place
if it has to read something from a remapped mapping. */
uint32_t mem_readl_phys(uint32_t addr)
{
uint8_t i, temp[4];
uint32_t ta;
for (i = 0; i < 4; i++) {
ta = addr + i;
temp[i] = _mem_exec[ta >> 14][ta & 0x3fff];
}
return *(uint32_t *) temp;
}
void mem_writel_phys(uint32_t addr, uint32_t val)
{
uint8_t i, temp[4];
uint32_t ta;
*(uint32_t *) temp = val;
for (i = 0; i < 4; i++) {
ta = addr + i;
_mem_exec[ta >> 14][ta & 0x3fff] = temp[i];
}
}
/* rw means 0 = read, 1 = write */
uint32_t mmutranslate(uint32_t addr, int rw, int is_abrt)
{
@@ -277,7 +305,7 @@ uint32_t mmutranslate(uint32_t addr, int rw, int is_abrt)
table_addr = dir_base + ((addr >> 20) & 0xffc);
/* First check the flags of the page directory entry. */
table_flags = ((uint32_t *)ram)[table_addr >> 2];
table_flags = mem_readl_phys(table_addr);
if ((table_flags & 0x80) && (cr4 & CR4_PSE))
{
@@ -291,7 +319,7 @@ uint32_t mmutranslate(uint32_t addr, int rw, int is_abrt)
if (is_abrt)
{
mmu_perm = table_flags & 4;
((uint32_t *)ram)[table_addr >> 2] |= (rw ? PAGE_DIRTY_AND_ACCESSED : PAGE_ACCESSED);
mem_writel_phys(table_addr, table_flags | (rw ? PAGE_DIRTY_AND_ACCESSED : PAGE_ACCESSED));
}
return (table_flags & ~0x3FFFFF) + (addr & 0x3FFFFF);
@@ -309,7 +337,7 @@ uint32_t mmutranslate(uint32_t addr, int rw, int is_abrt)
page_addr += ((addr >> 10) & 0xffc);
/* Then check the flags of the page table entry. */
page_flags = ((uint32_t *)ram)[page_addr >> 2];
page_flags = mem_readl_phys(page_addr);
if (mmu_page_fault_check(addr, rw, page_flags & 7, 1, is_abrt) == -1)
{
@@ -319,8 +347,8 @@ uint32_t mmutranslate(uint32_t addr, int rw, int is_abrt)
if (is_abrt)
{
mmu_perm = page_flags & 4;
((uint32_t *)ram)[table_addr >> 2] |= PAGE_ACCESSED;
((uint32_t *)ram)[page_addr >> 2] |= (rw ? PAGE_DIRTY_AND_ACCESSED : PAGE_ACCESSED);
mem_writel_phys(table_addr, table_flags | PAGE_ACCESSED);
mem_writel_phys(page_addr, page_flags | (rw ? PAGE_DIRTY_AND_ACCESSED : PAGE_ACCESSED));
}
return (page_flags & ~0xFFF) + (addr & 0xFFF);
@@ -947,7 +975,7 @@ uint8_t mem_readb_phys_dma(uint32_t addr)
if (_mem_read_b[addr >> 14]) {
if (_mem_mapping_r[addr >> 14] && (_mem_mapping_r[addr >> 14]->flags & MEM_MAPPING_INTERNAL)) {
return ram[addr];
return _mem_exec[addr >> 14][addr & 0x3fff];
} else
return _mem_read_b[addr >> 14](addr, _mem_priv_r[addr >> 14]);
}
@@ -980,7 +1008,7 @@ void mem_writeb_phys_dma(uint32_t addr, uint8_t val)
if (_mem_write_b[addr >> 14]) {
if (_mem_mapping_w[addr >> 14] && (_mem_mapping_w[addr >> 14]->flags & MEM_MAPPING_INTERNAL)) {
ram[addr] = val;
_mem_exec[addr >> 14][addr & 0x3fff] = val;
} else
_mem_write_b[addr >> 14](addr, val, _mem_priv_w[addr >> 14]);
}

View File

@@ -8,15 +8,15 @@
*
* Main emulator module where most things are controlled.
*
* Version: @(#)pc.c 1.0.51 2017/12/16
* Version: @(#)pc.c 1.0.52 2018/01/16
*
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
* Miran Grca, <mgrca8@gmail.com>
* Fred N. van Kempen, <decwiz@yahoo.com>
*
* Copyright 2008-2017 Sarah Walker.
* Copyright 2016,2017 Miran Grca.
* Copyright 2017 Fred N. van Kempen.
* Copyright 2008-2018 Sarah Walker.
* Copyright 2016-2018 Miran Grca.
* Copyright 2017,2018 Fred N. van Kempen.
*/
#include <stdio.h>
#include <stdint.h>
@@ -50,7 +50,7 @@
#include "keyboard.h"
#include "mouse.h"
#include "game/gameport.h"
#include "floppy/floppy.h"
#include "floppy/fdd.h"
#include "floppy/fdc.h"
#include "disk/hdd.h"
#include "disk/hdc.h"
@@ -503,7 +503,7 @@ pc_reload(wchar_t *fn)
config_write(cfg_path);
for (i=0; i<FDD_NUM; i++)
floppy_close(i);
fdd_close(i);
for (i=0; i<CDROM_NUM; i++) {
cdrom_drives[i].handler->exit(i);
if (cdrom_drives[i].host_drive == 200)
@@ -532,10 +532,10 @@ pc_reload(wchar_t *fn)
cdrom_null_open(i, cdrom_drives[i].host_drive);
}
floppy_load(0, floppyfns[0]);
floppy_load(1, floppyfns[1]);
floppy_load(2, floppyfns[2]);
floppy_load(3, floppyfns[3]);
fdd_load(0, floppyfns[0]);
fdd_load(1, floppyfns[1]);
fdd_load(2, floppyfns[2]);
fdd_load(3, floppyfns[3]);
mem_resize();
rom_load_bios(romset);
@@ -638,9 +638,7 @@ again2:
sound_reset();
fdc_init();
floppy_general_init();
fdd_init();
sound_init();
@@ -755,10 +753,6 @@ pc_reset_hard_init(void)
inital();
sound_reset();
fdc_init();
fdc_update_is_nsc(0);
floppy_reset();
#ifndef WALTJE_SERIAL
/* This is needed to initialize the serial timer. */
serial_init();
@@ -767,6 +761,8 @@ pc_reset_hard_init(void)
/* Initialize the actual machine and its basic modules. */
machine_init();
fdd_reset();
/*
* Once the machine has been initialized, all that remains
* should be resetting all devices set up for it, to their
@@ -791,14 +787,11 @@ pc_reset_hard_init(void)
* serial_init() doesn't break the serial mouse by resetting
* the RCR callback to NULL.
*/
// mouse_reset();
mouse_reset();
/* Reset the video card. */
video_reset(gfxcard);
/* Reset the Floppy Disk controller. */
fdc_reset();
/* Reset the Hard Disk Controller module. */
hdc_reset();
@@ -857,8 +850,6 @@ pc_reset_hard_init(void)
setpitclock(machines[machine].cpu[cpu_manufacturer].cpus[cpu].rspeed);
else
setpitclock(14318184.0);
mouse_reset();
}
@@ -920,7 +911,7 @@ pc_close(thread_t *ptr)
cdrom_drives[i].handler->exit(i);
for (i=0; i<FDD_NUM; i++)
floppy_close(i);
fdd_close(i);
if (dump_on_exit)
dumppic();

View File

@@ -16,8 +16,6 @@
#include "cdrom/cdrom.h"
#include "disk/hdc.h"
#include "disk/hdc_ide.h"
#include "floppy/floppy.h"
#include "floppy/fdc.h"
static uint64_t pci_irq_hold[16];
@@ -651,8 +649,6 @@ static void trc_reset(uint8_t val)
pci_reset_handler.pci_set_reset();
}
fdc_hard_reset();
if (pci_reset_handler.super_io_reset)
{
pci_reset_handler.super_io_reset();

View File

@@ -1,10 +1,27 @@
/*
* 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.
*
* Super I/O chip detection code.
*
* Version: @(#)sio_detect.c 1.0.0 2018/01/16
*
* Authors: Miran Grca, <mgrca8@gmail.com>
*
* Copyright 2016-2018 Miran Grca.
*/
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <wchar.h>
#include "86box.h"
#include "device.h"
#include "io.h"
#include "floppy/floppy.h"
#include "floppy/fdd.h"
#include "floppy/fdc.h"
#include "sio.h"
@@ -32,8 +49,7 @@ static uint8_t superio_detect_read(uint16_t port, void *priv)
void superio_detect_init(void)
{
fdc_remove();
fdc_add_for_superio();
device_add(&fdc_at_smc_device);
io_sethandler(0x24, 0x0002, superio_detect_read, NULL, NULL, superio_detect_write, NULL, NULL, NULL);
io_sethandler(0x26, 0x0002, superio_detect_read, NULL, NULL, superio_detect_write, NULL, NULL, NULL);

View File

@@ -8,10 +8,10 @@
*
* Implementation of the SMC FDC37C669 Super I/O Chip.
*
* Version: @(#)sio_fdc37c669.c 1.0.6 2017/11/04
* Version: @(#)sio_fdc37c669.c 1.0.7 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>
@@ -25,9 +25,8 @@
#include "serial.h"
#include "disk/hdc.h"
#include "disk/hdc_ide.h"
#include "floppy/floppy.h"
#include "floppy/fdc.h"
#include "floppy/fdd.h"
#include "floppy/fdc.h"
#include "sio.h"
@@ -36,6 +35,7 @@ static int fdc37c669_rw_locked = 0;
static int fdc37c669_curreg = 0;
static uint8_t fdc37c669_regs[42];
static uint8_t tries;
static fdc_t *fdc37c669_fdc;
static uint16_t make_port(uint8_t reg)
{
@@ -131,8 +131,8 @@ process_value:
#endif
if (valxor & 8)
{
fdc_remove();
if ((fdc37c669_regs[0] & 8) && (fdc37c669_regs[0x20] & 0xc0)) fdc_set_base(make_port(0x20), 1);
fdc_remove(fdc37c669_fdc);
if ((fdc37c669_regs[0] & 8) && (fdc37c669_regs[0x20] & 0xc0)) fdc_set_base(fdc37c669_fdc, make_port(0x20));
}
break;
case 1:
@@ -174,21 +174,21 @@ process_value:
}
break;
case 3:
if (valxor & 2) fdc_update_enh_mode((val & 2) ? 1 : 0);
if (valxor & 2) fdc_update_enh_mode(fdc37c669_fdc, (val & 2) ? 1 : 0);
break;
case 5:
if (valxor & 0x18) fdc_update_densel_force((val & 0x18) >> 3);
if (valxor & 0x20) fdd_swap = ((val & 0x20) >> 5);
if (valxor & 0x18) fdc_update_densel_force(fdc37c669_fdc, (val & 0x18) >> 3);
if (valxor & 0x20) fdc_set_swap(fdc37c669_fdc, (val & 0x20) >> 5);
break;
case 0xB:
if (valxor & 3) fdc_update_rwc(0, val & 3);
if (valxor & 0xC) fdc_update_rwc(1, (val & 0xC) >> 2);
if (valxor & 3) fdc_update_rwc(fdc37c669_fdc, 0, val & 3);
if (valxor & 0xC) fdc_update_rwc(fdc37c669_fdc, 1, (val & 0xC) >> 2);
break;
case 0x20:
if (valxor & 0xfc)
{
fdc_remove();
if ((fdc37c669_regs[0] & 8) && (fdc37c669_regs[0x20] & 0xc0)) fdc_set_base(make_port(0x20), 1);
fdc_remove(fdc37c669_fdc);
if ((fdc37c669_regs[0] & 8) && (fdc37c669_regs[0x20] & 0xc0)) fdc_set_base(fdc37c669_fdc, make_port(0x20));
}
break;
case 0x21:
@@ -294,10 +294,7 @@ uint8_t fdc37c669_read(uint16_t port, void *priv)
void fdc37c669_reset(void)
{
fdc_remove();
fdc_add_for_superio();
fdc_update_is_nsc(0);
fdc_reset(fdc37c669_fdc);
serial_remove(1);
serial_setup(1, SERIAL1_ADDR, SERIAL1_IRQ);
@@ -309,7 +306,7 @@ void fdc37c669_reset(void)
lpt1_remove();
lpt1_init(0x378);
memset(fdc37c669_regs, 0, 42);
fdc37c669_regs[0] = 0x28;
fdc37c669_regs[1] = 0x9C;
@@ -337,15 +334,14 @@ void fdc37c669_reset(void)
fdc37c669_regs[0x27] = (6 << 4) | 7;
fdc37c669_regs[0x28] = (4 << 4) | 3;
fdc_update_densel_polarity(1);
fdc_update_densel_force(0);
fdd_swap = 0;
fdc37c669_locked = 0;
fdc37c669_rw_locked = 0;
}
void fdc37c669_init()
{
fdc37c669_fdc = device_add(&fdc_at_smc_device);
io_sethandler(0x3f0, 0x0002, fdc37c669_read, NULL, NULL, fdc37c669_write, NULL, NULL, NULL);
fdc37c669_reset();

View File

@@ -9,13 +9,13 @@
* Implementation of the SMC FDC37C663 and FDC37C665 Super
* I/O Chips.
*
* Version: @(#)sio_fdc37c66x.c 1.0.9 2017/11/04
* Version: @(#)sio_fdc37c66x.c 1.0.10 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>
@@ -29,9 +29,8 @@
#include "serial.h"
#include "disk/hdc.h"
#include "disk/hdc_ide.h"
#include "floppy/floppy.h"
#include "floppy/fdc.h"
#include "floppy/fdd.h"
#include "floppy/fdc.h"
#include "sio.h"
@@ -39,14 +38,15 @@ static uint8_t fdc37c66x_lock[2];
static int fdc37c66x_curreg;
static uint8_t fdc37c66x_regs[16];
static int com3_addr, com4_addr;
static fdc_t *fdc37c66x_fdc;
static void write_lock(uint8_t val)
{
if (val == 0x55 && fdc37c66x_lock[1] == 0x55)
fdc_3f1_enable(0);
fdc_3f1_enable(fdc37c66x_fdc, 0);
if (fdc37c66x_lock[0] == 0x55 && fdc37c66x_lock[1] == 0x55 && val != 0x55)
fdc_3f1_enable(1);
fdc_3f1_enable(fdc37c66x_fdc, 1);
fdc37c66x_lock[0] = fdc37c66x_lock[1];
fdc37c66x_lock[1] = val;
@@ -235,7 +235,7 @@ static void fdc37c66x_write(uint16_t port, uint8_t val, void *priv)
case 3:
if (valxor & 2)
{
fdc_update_enh_mode((fdc37c66x_regs[3] & 2) ? 1 : 0);
fdc_update_enh_mode(fdc37c66x_fdc, (fdc37c66x_regs[3] & 2) ? 1 : 0);
}
break;
case 5:
@@ -245,11 +245,11 @@ static void fdc37c66x_write(uint16_t port, uint8_t val, void *priv)
}
if (valxor & 0x18)
{
fdc_update_densel_force((fdc37c66x_regs[5] & 0x18) >> 3);
fdc_update_densel_force(fdc37c66x_fdc, (fdc37c66x_regs[5] & 0x18) >> 3);
}
if (valxor & 0x20)
{
fdd_swap = ((fdc37c66x_regs[5] & 0x20) >> 5);
fdc_set_swap(fdc37c66x_fdc, (fdc37c66x_regs[5] & 0x20) >> 5);
}
break;
}
@@ -277,11 +277,6 @@ static void fdc37c66x_reset(void)
com3_addr = 0x338;
com4_addr = 0x238;
fdc_remove();
fdc_add_for_superio();
fdc_update_is_nsc(0);
serial_remove(1);
serial_setup(1, SERIAL1_ADDR, SERIAL1_IRQ);
@@ -292,6 +287,8 @@ static void fdc37c66x_reset(void)
lpt1_remove();
lpt1_init(0x378);
fdc_reset(fdc37c66x_fdc);
memset(fdc37c66x_lock, 0, 2);
memset(fdc37c66x_regs, 0, 16);
@@ -301,10 +298,6 @@ static void fdc37c66x_reset(void)
fdc37c66x_regs[0x3] = 0x78;
fdc37c66x_regs[0x6] = 0xff;
fdc37c66x_regs[0xe] = 0x01;
fdc_update_densel_polarity(1);
fdc_update_densel_force(0);
fdd_swap = 0;
}
static void fdc37c663_reset(void)
@@ -321,6 +314,8 @@ static void fdc37c665_reset(void)
void fdc37c663_init()
{
fdc37c66x_fdc = device_add(&fdc_at_smc_device);
io_sethandler(0x03f0, 0x0002, fdc37c66x_read, NULL, NULL, fdc37c66x_write, NULL, NULL, NULL);
fdc37c663_reset();
@@ -330,6 +325,8 @@ void fdc37c663_init()
void fdc37c665_init()
{
fdc37c66x_fdc = device_add(&fdc_at_smc_device);
io_sethandler(0x03f0, 0x0002, fdc37c66x_read, NULL, NULL, fdc37c66x_write, NULL, NULL, NULL);
fdc37c665_reset();

View File

@@ -9,10 +9,10 @@
* Implementation of the SMC FDC37C932FR and FDC37C935 Super
* I/O Chips.
*
* Version: @(#)sio_fdc37c93x.c 1.0.10 2018/01/04
* Version: @(#)sio_fdc37c93x.c 1.0.10 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>
@@ -26,9 +26,8 @@
#include "serial.h"
#include "disk/hdc.h"
#include "disk/hdc_ide.h"
#include "floppy/floppy.h"
#include "floppy/fdc.h"
#include "floppy/fdd.h"
#include "floppy/fdc.h"
#include "sio.h"
@@ -38,6 +37,7 @@ static int fdc37c93x_gpio_reg = 0;
static uint8_t fdc37c93x_regs[48];
static uint8_t fdc37c93x_ld_regs[10][256];
static uint8_t fdc37c93x_gpio_base = 0x00EA;
static fdc_t *fdc37c93x_fdc;
static uint8_t tries;
@@ -70,14 +70,14 @@ static void fdc37c93x_fdc_handler(void)
uint8_t global_enable = !!(fdc37c93x_regs[0x22] & (1 << 0));
uint8_t local_enable = !!fdc37c93x_ld_regs[0][0x30];
fdc_remove();
fdc_remove(fdc37c93x_fdc);
/* pclog("fdc37c93x: Removing FDC (%i, %i)\n", global_enable, local_enable); */
if (global_enable && local_enable)
{
ld_port = make_port(0);
/* pclog("fdc37c93x: Setting FDC port to %04X\n", ld_port); */
if ((ld_port >= 0x0100) && (ld_port <= 0x0FF8)) {
fdc_set_base(ld_port, 1);
fdc_set_base(fdc37c93x_fdc, ld_port);
}
}
}
@@ -216,7 +216,7 @@ static void fdc37c93x_write(uint16_t port, uint8_t val, void *priv)
if (tries)
{
fdc37c93x_locked = 1;
fdc_3f1_enable(0);
fdc_3f1_enable(fdc37c93x_fdc, 0);
tries = 0;
}
else
@@ -231,7 +231,7 @@ static void fdc37c93x_write(uint16_t port, uint8_t val, void *priv)
if (val == 0xaa)
{
fdc37c93x_locked = 0;
fdc_3f1_enable(1);
fdc_3f1_enable(fdc37c93x_fdc, 1);
return;
}
fdc37c93x_curreg = val;
@@ -306,29 +306,29 @@ process_value:
}
break;
case 0xF0:
if (valxor & 0x01) fdc_update_enh_mode(val & 0x01);
if (valxor & 0x10) fdd_swap = ((val & 0x10) >> 4);
if (valxor & 0x01) fdc_update_enh_mode(fdc37c93x_fdc, val & 0x01);
if (valxor & 0x10) fdc_set_swap(fdc37c93x_fdc, (val & 0x10) >> 4);
break;
case 0xF1:
if (valxor & 0xC) fdc_update_densel_force((val & 0xC) >> 2);
if (valxor & 0xC) fdc_update_densel_force(fdc37c93x_fdc, (val & 0xC) >> 2);
break;
case 0xF2:
if (valxor & 0xC0) fdc_update_rwc(3, (valxor & 0xC0) >> 6);
if (valxor & 0x30) fdc_update_rwc(2, (valxor & 0x30) >> 4);
if (valxor & 0x0C) fdc_update_rwc(1, (valxor & 0x0C) >> 2);
if (valxor & 0x03) fdc_update_rwc(0, (valxor & 0x03));
if (valxor & 0xC0) fdc_update_rwc(fdc37c93x_fdc, 3, (valxor & 0xC0) >> 6);
if (valxor & 0x30) fdc_update_rwc(fdc37c93x_fdc, 2, (valxor & 0x30) >> 4);
if (valxor & 0x0C) fdc_update_rwc(fdc37c93x_fdc, 1, (valxor & 0x0C) >> 2);
if (valxor & 0x03) fdc_update_rwc(fdc37c93x_fdc, 0, (valxor & 0x03));
break;
case 0xF4:
if (valxor & 0x18) fdc_update_drvrate(0, (val & 0x18) >> 3);
if (valxor & 0x18) fdc_update_drvrate(fdc37c93x_fdc, 0, (val & 0x18) >> 3);
break;
case 0xF5:
if (valxor & 0x18) fdc_update_drvrate(1, (val & 0x18) >> 3);
if (valxor & 0x18) fdc_update_drvrate(fdc37c93x_fdc, 1, (val & 0x18) >> 3);
break;
case 0xF6:
if (valxor & 0x18) fdc_update_drvrate(2, (val & 0x18) >> 3);
if (valxor & 0x18) fdc_update_drvrate(fdc37c93x_fdc, 2, (val & 0x18) >> 3);
break;
case 0xF7:
if (valxor & 0x18) fdc_update_drvrate(3, (val & 0x18) >> 3);
if (valxor & 0x18) fdc_update_drvrate(fdc37c93x_fdc, 3, (val & 0x18) >> 3);
break;
}
break;
@@ -428,7 +428,7 @@ static uint8_t fdc37c93x_read(uint16_t port, void *priv)
}
else
{
if ((fdc37c93x_regs[7] == 0) && (fdc37c93x_curreg == 0xF2)) return (fdc_get_rwc(0) | (fdc_get_rwc(1) << 2));
if ((fdc37c93x_regs[7] == 0) && (fdc37c93x_curreg == 0xF2)) return (fdc_get_rwc(fdc37c93x_fdc, 0) | (fdc_get_rwc(fdc37c93x_fdc, 1) << 2));
return fdc37c93x_ld_regs[fdc37c93x_regs[7]][fdc37c93x_curreg];
}
}
@@ -521,22 +521,17 @@ static void fdc37c93x_reset(void)
/* Logical device 9: ACCESS.bus */
fdc_update_densel_force(0);
fdd_swap = 0;
fdc_update_rwc(0, 0);
fdc_update_rwc(1, 0);
fdc_update_rwc(2, 0);
fdc_update_rwc(3, 0);
fdc_update_drvrate(0, 0);
fdc_update_drvrate(1, 0);
fdc_update_drvrate(2, 0);
fdc_update_drvrate(3, 0);
fdc_update_max_track(79);
io_removehandler(fdc37c93x_gpio_base, 0x0001, fdc37c93x_gpio_read, NULL, NULL, fdc37c93x_gpio_write, NULL, NULL, NULL);
fdc37c93x_gpio_base = 0x00EA;
io_sethandler(fdc37c93x_gpio_base, 0x0001, fdc37c93x_gpio_read, NULL, NULL, fdc37c93x_gpio_write, NULL, NULL, NULL);
fdc37c93x_lpt_handler();
fdc37c93x_serial_handler(1);
fdc37c93x_serial_handler(2);
fdc37c93x_auxio_handler();
fdc_reset(fdc37c93x_fdc);
fdc37c93x_locked = 0;
}
@@ -545,6 +540,8 @@ static void fdc37c932fr_reset(void)
fdc37c93x_reset();
fdc37c93x_regs[0x20] = 3;
fdc37c932fr_access_bus_handler();
}
static void fdc37c935_reset(void)
@@ -558,8 +555,7 @@ static void fdc37c93x_init(void)
{
lpt2_remove();
fdc_remove();
fdc_add_for_superio();
fdc37c93x_fdc = device_add(&fdc_at_smc_device);
fdc37c93x_gpio_reg = 0xFD;

View File

@@ -8,10 +8,10 @@
*
* Emulation of the NatSemi PC87306 Super I/O chip.
*
* Version: @(#)sio_pc87306.c 1.0.8 2018/01/12
* Version: @(#)sio_pc87306.c 1.0.8 2018/01/16
*
* Author: Miran Grca, <mgrca8@gmail.com>
* Copyright 2016,2018 Miran Grca.
* Copyright 2016-2018 Miran Grca.
*/
#include <stdio.h>
#include <stdint.h>
@@ -25,15 +25,15 @@
#include "serial.h"
#include "disk/hdc.h"
#include "disk/hdc_ide.h"
#include "floppy/floppy.h"
#include "floppy/fdc.h"
#include "floppy/fdd.h"
#include "floppy/fdc.h"
#include "sio.h"
static int pc87306_curreg;
static uint8_t pc87306_regs[29];
static uint8_t pc87306_gpio[2] = {0xFF, 0xFB};
static fdc_t *pc87306_fdc;
static uint8_t tries;
static uint16_t lpt_port;
@@ -234,10 +234,10 @@ process_value:
}
if (valxor & 0x28)
{
fdc_remove();
fdc_remove(pc87306_fdc);
if (val & 8)
{
fdc_set_base((val & 0x20) ? 0x370 : 0x3f0, 0);
fdc_set_base(pc87306_fdc, (val & 0x20) ? 0x370 : 0x3f0);
}
}
if (valxor & 0xc0)
@@ -304,7 +304,7 @@ process_value:
lpt1_remove();
serial_remove(1);
serial_remove(2);
fdc_remove();
fdc_remove(pc87306_fdc);
}
else
{
@@ -322,7 +322,7 @@ process_value:
}
if (pc87306_regs[0] & 8)
{
fdc_set_base((pc87306_regs[0] & 0x20) ? 0x370 : 0x3f0, 0);
fdc_set_base(pc87306_fdc, (pc87306_regs[0] & 0x20) ? 0x370 : 0x3f0);
}
}
}
@@ -330,8 +330,8 @@ process_value:
case 9:
if (valxor & 0x44)
{
fdc_update_enh_mode((val & 4) ? 1 : 0);
fdc_update_densel_polarity((val & 0x40) ? 1 : 0);
fdc_update_enh_mode(pc87306_fdc, (val & 4) ? 1 : 0);
fdc_update_densel_polarity(pc87306_fdc, (val & 0x40) ? 1 : 0);
}
break;
case 0xF:
@@ -456,22 +456,21 @@ void pc87306_reset(void)
0 = 360 rpm @ 500 kbps for 3.5"
1 = Default, 300 rpm @ 500,300,250,1000 kbps for 3.5"
*/
fdc_update_is_nsc(1);
fdc_update_enh_mode(0);
fdc_update_densel_polarity(1);
fdc_update_max_track(85);
fdc_remove();
fdc_set_base(0x3f0, 0);
fdd_swap = 0;
lpt1_remove();
lpt2_remove();
lpt1_handler();
serial_remove(1);
serial_remove(2);
serial1_handler();
serial2_handler();
fdc_reset(pc87306_fdc);
pc87306_gpio_init();
}
void pc87306_init()
{
device_add(&fdc_at_nsc_device);
lpt2_remove();
pc87306_reset();

View File

@@ -26,11 +26,11 @@ PnP registers :
#include <string.h>
#include <wchar.h>
#include "86box.h"
#include "device.h"
#include "io.h"
#include "pci.h"
#include "lpt.h"
#include "serial.h"
#include "floppy/floppy.h"
#include "floppy/fdd.h"
#include "floppy/fdc.h"
#include "sio.h"
@@ -51,6 +51,8 @@ typedef struct um8669f_t
int irq;
int dma;
} dev[8];
fdc_t *fdc;
} um8669f_t;
@@ -120,9 +122,9 @@ void um8669f_pnp_write(uint16_t port, uint8_t val, void *p)
case DEV_FDC:
if ((um8669f->cur_reg == REG_ENABLE) && valxor)
{
fdc_remove();
fdc_remove(um8669f_global.fdc);
if (um8669f->dev[DEV_FDC].enable & 1)
fdc_add();
fdc_set_base(um8669f_global.fdc, 0x03f0);
}
break;
case DEV_COM1:
@@ -235,8 +237,8 @@ uint8_t um8669f_read(uint16_t port, void *p)
void um8669f_reset(void)
{
fdc_update_is_nsc(0);
fdc_reset(um8669f_global.fdc);
serial_remove(1);
serial_setup(1, SERIAL1_ADDR, SERIAL1_IRQ);
@@ -252,11 +254,6 @@ void um8669f_reset(void)
um8669f_global.locked = 1;
fdc_update_densel_polarity(1);
fdc_update_densel_force(0);
fdd_swap = 0;
io_removehandler(0x0279, 0x0001, NULL, NULL, NULL, um8669f_pnp_write, NULL, NULL, &um8669f_global);
io_removehandler(0x0a79, 0x0001, NULL, NULL, NULL, um8669f_pnp_write, NULL, NULL, &um8669f_global);
io_removehandler(0x03e3, 0x0001, um8669f_pnp_read, NULL, NULL, NULL, NULL, NULL, &um8669f_global);
@@ -282,6 +279,8 @@ void um8669f_reset(void)
void um8669f_init(void)
{
um8669f_global.fdc = device_add(&fdc_at_device);
io_sethandler(0x0108, 0x0002, um8669f_read, NULL, NULL, um8669f_write, NULL, NULL, &um8669f_global);
um8669f_reset();

View File

@@ -11,10 +11,10 @@
* Winbond W83877F Super I/O Chip
* Used by the Award 430HX
*
* Version: @(#)sio_w83877f.c 1.0.7 2017/12/28
* Version: @(#)sio_w83877f.c 1.0.8 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>
@@ -22,15 +22,15 @@
#include <wchar.h>
#include "86box.h"
#include "machine/machine.h"
#include "device.h"
#include "io.h"
#include "pci.h"
#include "mem.h"
#include "rom.h"
#include "lpt.h"
#include "serial.h"
#include "floppy/floppy.h"
#include "floppy/fdc.h"
#include "floppy/fdd.h"
#include "floppy/fdc.h"
#include "sio.h"
@@ -39,6 +39,7 @@ static int w83877f_rw_locked = 0;
static int w83877f_curreg = 0;
static uint8_t w83877f_regs[0x2A];
static uint8_t tries;
static fdc_t *w83877f_fdc;
static int winbond_port = 0x3f0;
static int winbond_key = 0x89;
@@ -378,8 +379,9 @@ process_value:
case 1:
if (valxor & 0x80)
{
fdd_setswap((w83877f_regs[1] & 0x80) ? 1 : 0);
fdc_set_swap(w83877f_fdc, (w83877f_regs[1] & 0x80) ? 1 : 0);
}
break;
case 4:
if (valxor & 0x10)
{
@@ -398,25 +400,25 @@ process_value:
case 6:
if (valxor & 0x08)
{
fdc_remove();
if (!(w83877f_regs[6] & 0x08)) fdc_add();
fdc_remove(w83877f_fdc);
if (!(w83877f_regs[6] & 0x08)) fdc_set_base(w83877f_fdc, 0x03f0);
}
break;
case 7:
if (valxor & 3) fdc_update_rwc(0, FDDA_TYPE);
if (valxor & 0xC) fdc_update_rwc(1, FDDB_TYPE);
if (valxor & 0x30) fdc_update_rwc(2, FDDC_TYPE);
if (valxor & 0xC0) fdc_update_rwc(3, FDDD_TYPE);
if (valxor & 3) fdc_update_rwc(w83877f_fdc, 0, FDDA_TYPE);
if (valxor & 0xC) fdc_update_rwc(w83877f_fdc, 1, FDDB_TYPE);
if (valxor & 0x30) fdc_update_rwc(w83877f_fdc, 2, FDDC_TYPE);
if (valxor & 0xC0) fdc_update_rwc(w83877f_fdc, 3, FDDD_TYPE);
break;
case 8:
if (valxor & 3) fdc_update_boot_drive(FD_BOOT);
if (valxor & 0x10) swwp = SWWP ? 1 : 0;
if (valxor & 0x20) disable_write = DISFDDWR ? 1 : 0;
if (valxor & 3) fdc_update_boot_drive(w83877f_fdc, FD_BOOT);
if (valxor & 0x10) fdc_set_swwp(w83877f_fdc, SWWP ? 1 : 0);
if (valxor & 0x20) fdc_set_diswr(w83877f_fdc, DISFDDWR ? 1 : 0);
break;
case 9:
if (valxor & 0x20)
{
fdc_update_enh_mode(EN3MODE ? 1 : 0);
fdc_update_enh_mode(w83877f_fdc, EN3MODE ? 1 : 0);
}
if (valxor & 0x40)
{
@@ -424,8 +426,8 @@ process_value:
}
break;
case 0xB:
if (valxor & 1) fdc_update_drv2en(DRV2EN_NEG ? 0 : 1);
if (valxor & 2) fdc_update_densel_polarity(INVERTZ ? 1 : 0);
if (valxor & 1) fdc_update_drv2en(w83877f_fdc, DRV2EN_NEG ? 0 : 1);
if (valxor & 2) fdc_update_densel_polarity(w83877f_fdc, INVERTZ ? 1 : 0);
break;
case 0xC:
if (valxor & 0x20) w83877f_remap();
@@ -488,9 +490,7 @@ uint8_t w83877f_read(uint16_t port, void *priv)
{
if ((w83877f_curreg < 0x18) && w83877f_rw_locked) return 0xff;
if (w83877f_curreg == 7)
{
return (fdc_get_rwc(0) | (fdc_get_rwc(1) << 2));
}
return (fdc_get_rwc(w83877f_fdc, 0) | (fdc_get_rwc(w83877f_fdc, 1) << 2));
return w83877f_regs[w83877f_curreg];
}
}
@@ -501,8 +501,7 @@ void w83877f_reset(void)
lpt1_remove();
lpt1_init(0x378);
fdc_remove();
fdc_add_for_superio();
fdc_reset(w83877f_fdc);
w83877f_regs[3] = 0x30;
w83877f_regs[7] = 0xF5;
@@ -523,18 +522,6 @@ void w83877f_reset(void)
w83877f_regs[0x28] = (4 << 4) | 3;
w83877f_regs[0x29] = 0x62;
fdc_update_densel_polarity(1);
fdc_update_densel_force(0);
fdc_update_rwc(0, 1);
fdc_update_rwc(1, 1);
fdc_update_drvrate(0, 0);
fdc_update_drvrate(1, 0);
fdc_update_enh_mode(0);
fdc_update_max_track(85);
swwp = 0;
disable_write = 0;
fdc_update_drv2en(1);
fdd_setswap(0);
serial_setup(1, SERIAL1_ADDR, SERIAL1_IRQ);
serial_setup(2, SERIAL2_ADDR, SERIAL2_IRQ);
w83877f_remap();
@@ -545,6 +532,8 @@ void w83877f_reset(void)
void w83877f_init(void)
{
w83877f_fdc = device_add(&fdc_at_winbond_device);
lpt2_remove();
w83877f_reset();

View File

@@ -8,13 +8,13 @@
*
* Interface to the OpenAL sound processing library.
*
* Version: @(#)openal.c 1.0.2 2017/12/15
* Version: @(#)openal.c 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.
*/
#include <math.h>
#include <stdio.h>
@@ -221,9 +221,7 @@ givealbuffer_common(void *buf, uint8_t src, int size, int freq)
int processed;
int state;
ALuint buffer;
#if 0
double gain;
#endif
alGetSourcei(source[src], AL_SOURCE_STATE, &state);
@@ -233,11 +231,9 @@ givealbuffer_common(void *buf, uint8_t src, int size, int freq)
alGetSourcei(source[src], AL_BUFFERS_PROCESSED, &processed);
if (processed >= 1) {
#if 0
gain = pow(10.0, (double)sound_gain[src] / 20.0);
alSourcef(source[src], AL_GAIN, gain);
#endif
alListenerf(AL_GAIN, gain);
alSourceUnqueueBuffers(source[src], 1, &buffer);

View File

@@ -116,7 +116,8 @@ enum {
FULLSCR_SCALE_FULL = 0,
FULLSCR_SCALE_43,
FULLSCR_SCALE_SQ,
FULLSCR_SCALE_INT
FULLSCR_SCALE_INT,
FULLSCR_SCALE_KEEPRATIO
};

View File

@@ -8,12 +8,12 @@
*
* Application resource script for Windows.
*
* Version: @(#)86Box.rc 1.0.22 2017/12/09
* Version: @(#)86Box.rc 1.0.22 2018/01/17
*
* Authors: Miran Grca, <mgrca8@gmail.com>
* Fred N. van Kempen, <decwiz@yahoo.com>
*
* Copyright 2016,2017 Miran Grca.
* Copyright 2016-2018 Miran Grca.
*/
#include <inttypes.h>
#define IN_RESOURCE_H
@@ -88,6 +88,7 @@ BEGIN
MENUITEM "&4:3", IDM_VID_FS_43
MENUITEM "&Square pixels", IDM_VID_FS_SQ
MENUITEM "&Integer scale", IDM_VID_FS_INT
MENUITEM "&Keep size", IDM_VID_FS_KEEPRATIO
END
POPUP "E&GA/(S)VGA settings"
BEGIN
@@ -116,11 +117,10 @@ BEGIN
BEGIN
MENUITEM "&Settings...", IDM_CONFIG
MENUITEM SEPARATOR
MENUITEM "&Load configuration...", IDM_CONFIG_LOAD
MENUITEM "&Save configuration...", IDM_CONFIG_SAVE
MENUITEM SEPARATOR
MENUITEM "S&tatus", IDM_STATUS
MENUITEM "Take s&creenshot\tCtrl+F11", IDM_ACTION_SCREENSHOT
MENUITEM SEPARATOR
MENUITEM "S&ound gain...", IDM_SND_GAIN
END
#if defined(ENABLE_LOG_TOGGLES) || defined(ENABLE_LOG_COMMANDS)
POPUP "&Logging"
@@ -238,6 +238,39 @@ BEGIN
LTEXT "1",IDT_STEXT,16,186,180,1000
END
DLG_SND_GAIN DIALOG DISCARDABLE 0, 0, 174, 136
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Sound Gain"
FONT 8, "MS Sans Serif"
BEGIN
DEFPUSHBUTTON "OK",IDOK,117,7,50,14
PUSHBUTTON "Cancel",IDCANCEL,117,24,50,14
CONTROL "Main",IDC_SLIDER_MAIN,"msctls_trackbar32",TBS_VERT |
TBS_BOTH | TBS_AUTOTICKS | WS_TABSTOP,15,20,20,109
CONTROL "CD",IDC_SLIDER_CD,"msctls_trackbar32",TBS_VERT |
TBS_BOTH | TBS_AUTOTICKS | WS_TABSTOP,45,20,20,109
CONTROL "MIDI",IDC_SLIDER_MIDI,"msctls_trackbar32",TBS_VERT |
TBS_BOTH | TBS_AUTOTICKS | WS_TABSTOP,77,20,20,109
CTEXT "Main",IDT_1746,7,7,32,9,SS_CENTERIMAGE
CTEXT "CD",IDT_1747,38,7,32,9,SS_CENTERIMAGE
CTEXT "MIDI",IDT_1748,70,7,32,9,SS_CENTERIMAGE
END
DLG_NEW_FLOPPY DIALOG DISCARDABLE 0, 0, 186, 65
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "New Floppy Image"
FONT 8, "MS Sans Serif"
BEGIN
DEFPUSHBUTTON "OK",IDOK,74,44,50,14
PUSHBUTTON "Cancel",IDCANCEL,129,44,50,14
LTEXT "File name:",IDT_1749,7,6,34,12,SS_CENTERIMAGE
LTEXT "Disk size:",IDT_1750,7,25,34,12,SS_CENTERIMAGE
EDITTEXT IDC_EDIT_FILE_NAME,43,7,124,12,ES_AUTOHSCROLL | ES_READONLY
COMBOBOX IDC_COMBO_DISK_SIZE,43,25,136,14,CBS_DROPDOWN | CBS_SORT |
WS_VSCROLL | WS_TABSTOP
PUSHBUTTON "...",IDC_CFILE,166,7,13,12
END
DLG_CONFIG DIALOG DISCARDABLE 0, 0, 366, 241
STYLE DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "86Box Settings"
@@ -606,6 +639,22 @@ END
#ifdef APSTUDIO_INVOKED
GUIDELINES DESIGNINFO DISCARDABLE
BEGIN
DLG_SND_GAIN, DIALOG
BEGIN
LEFTMARGIN, 7
RIGHTMARGIN, 167
TOPMARGIN, 7
BOTTOMMARGIN, 129
END
DLG_NEW_FLOPPY, DIALOG
BEGIN
LEFTMARGIN, 7
RIGHTMARGIN, 179
TOPMARGIN, 7
BOTTOMMARGIN, 58
END
DLG_CFG_MAIN, DIALOG
BEGIN
RIGHTMARGIN, 365

View File

@@ -8,7 +8,7 @@
#
# Makefile for Win32 (MinGW32) environment.
#
# Version: @(#)Makefile.mingw 1.0.91 2018/01/01
# Version: @(#)Makefile.mingw 1.0.92 2018/01/16
#
# Authors: Miran Grca, <mgrca8@gmail.com>
# Fred N. van Kempen, <decwiz@yahoo.com>
@@ -255,7 +255,8 @@ ifneq ($(WX), n)
else
UIOBJ := win_ui.o win_ddraw.o win_d3d.o win_png.o \
win_dialog.o win_about.o win_status.o win_stbar.o \
win_settings.o win_devconf.o win_jsconf.o
win_settings.o win_devconf.o \
win_snd_gain.o win_jsconf.o
endif
ifeq ($(OPENAL), y)
@@ -394,9 +395,9 @@ DEVOBJ := bugger.o lpt.o $(SERIAL) \
mouse_serial.o mouse_ps2.o mouse_bus.o
FDDOBJ := fdd.o fdc.o fdi2raw.o \
floppy.o floppy_common.o floppy_86f.o \
floppy_fdi.o floppy_imd.o floppy_img.o floppy_json.o \
floppy_td0.o
fdd_common.o fdd_86f.o \
fdd_fdi.o fdd_imd.o fdd_img.o fdd_json.o \
fdd_td0.o
HDDOBJ := hdd.o \
hdd_image.o hdd_table.o \

View File

@@ -8,14 +8,14 @@
*
* Windows resource defines.
*
* Version: @(#)resource.h 1.0.15 2017/12/09
* Version: @(#)resource.h 1.0.16 2018/01/17
*
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
* Miran Grca, <mgrca8@gmail.com>
* Fred N. van Kempem, <decwiz@yahoo.com>
* Fred N. van Kempen, <decwiz@yahoo.com>
*
* Copyright 2008-2017 Sarah Walker.
* Copyright 2016,2017 Miran Grca.
* Copyright 2008-2018 Sarah Walker.
* Copyright 2016-2018 Miran Grca.
*/
#ifndef WIN_RESOURCE_H
# define WIN_RESOURCE_H
@@ -24,6 +24,8 @@
/* Dialog IDs. */
#define DLG_ABOUT 101 /* top-level dialog */
#define DLG_STATUS 102 /* top-level dialog */
#define DLG_SND_GAIN 103 /* top-level dialog */
#define DLG_NEW_FLOPPY 104 /* top-level dialog */
#define DLG_CONFIG 110 /* top-level dialog */
#define DLG_CFG_MACHINE 111 /* sub-dialog of config */
#define DLG_CFG_VIDEO 112 /* sub-dialog of config */
@@ -77,6 +79,11 @@
#define IDT_1743 1743 /* Channel: */
#define IDT_STEXT 1744 /* text in status window */
#define IDT_SDEVICE 1745 /* text in status window */
#define IDT_1746 1746 /* Main */
#define IDT_1747 1747 /* CD */
#define IDT_1748 1748 /* MIDI */
#define IDT_1749 1749 /* File name: */
#define IDT_1750 1750 /* Disk size: */
/*
@@ -180,6 +187,13 @@
#define IDC_BUTTON_CDROM_EDIT 1164 // status bar menu
#define IDC_BUTTON_CDROM_REMOVE 1165 // status bar menu
#define IDC_SLIDER_MAIN 1180 /* sound gain dialog */
#define IDC_SLIDER_CD 1181
#define IDC_SLIDER_MIDI 1182
#define IDC_EDIT_FILE_NAME 1190 /* new floppy image dialog */
#define IDC_COMBO_DISK_SIZE 1191
/* For the DeviceConfig code, re-do later. */
#define IDC_CONFIG_BASE 1200
@@ -213,6 +227,7 @@
#define IDM_CONFIG_LOAD 40021
#define IDM_CONFIG_SAVE 40022
#define IDM_STATUS 40030
#define IDM_SND_GAIN 40040
#define IDM_VID_RESIZE 40050
#define IDM_VID_REMEMBER 40051
#define IDM_VID_DDRAW 40060
@@ -228,8 +243,9 @@
#define IDM_VID_FS_43 40072
#define IDM_VID_FS_SQ 40073
#define IDM_VID_FS_INT 40074
#define IDM_VID_FORCE43 40075
#define IDM_VID_OVERSCAN 40076
#define IDM_VID_FS_KEEPRATIO 40075
#define IDM_VID_FORCE43 40076
#define IDM_VID_OVERSCAN 40077
#define IDM_VID_INVERT 40079
#define IDM_VID_CGACON 40080
#define IDM_VID_GRAYCT_601 40085

View File

@@ -110,6 +110,10 @@ extern int ui_init(int nCmdShow);
extern void AboutDialogCreate(HWND hwnd);
/* Functions in win_snd_gain.c: */
extern void SoundGainDialogCreate(HWND hwnd);
/* Functions in win_status.c: */
extern HWND hwndStatus;
extern void StatusWindowCreate(HWND hwnd);

View File

@@ -10,11 +10,9 @@
*
* Version: @(#)win_about.c 1.0.5 2017/12/13
*
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
* Miran Grca, <mgrca8@gmail.com>
* Authors: Miran Grca, <mgrca8@gmail.com>
* Fred N. van Kempen, <decwiz@yahoo.com>
*
* Copyright 2008-2017 Sarah Walker.
* Copyright 2016,2017 Miran Grca.
* Copyright 2017 Fred N. van Kempen.
*/

View File

@@ -9,13 +9,13 @@
* Implementation of the CD-ROM host drive IOCTL interface for
* Windows using SCSI Passthrough Direct.
*
* Version: @(#)cdrom_ioctl.c 1.0.8 2017/11/24
* Version: @(#)cdrom_ioctl.c 1.0.9 2018/01/17
*
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
* Miran Grca, <mgrca8@gmail.com>
*
* Copyright 2008-2016 Sarah Walker.
* Copyright 2016,2017 Miran Grca.
* Copyright 2008-2018 Sarah Walker.
* Copyright 2016-2018 Miran Grca.
*/
#define WINVER 0x0600
#include <windows.h>
@@ -573,13 +573,16 @@ static int is_track_audio(uint8_t id, uint32_t pos)
return 0;
}
for (c = 0; c <= cdrom_ioctl_windows[id].toc.LastTrack; c++)
for (c = 0; cdrom_ioctl_windows[id].toc.TrackData[c].TrackNumber != 0xaa; c++)
{
track_address = MSFtoLBA(cdrom_ioctl_windows[id].toc.TrackData[c].Address[1],cdrom_ioctl_windows[id].toc.TrackData[c].Address[2],cdrom_ioctl_windows[id].toc.TrackData[c].Address[3]);
if (track_address <= pos)
if (cdrom_ioctl_windows[id].toc.TrackData[c].TrackNumber >= cdrom_ioctl_windows[id].toc.FirstTrack &&
cdrom_ioctl_windows[id].toc.TrackData[c].TrackNumber <= cdrom_ioctl_windows[id].toc.LastTrack &&
track_address <= pos)
{
control = cdrom_ioctl_windows[id].toc.TrackData[c].Control;
break;
}
}
@@ -1048,7 +1051,6 @@ static int ioctl_readtoc(uint8_t id, unsigned char *b, unsigned char starttrack,
break;
}
}
b[2]=cdrom_ioctl_windows[id].toc.TrackData[c].TrackNumber;
last_block = 0;
for (c=d;c<=cdrom_ioctl_windows[id].toc.LastTrack;c++)
{

View File

@@ -8,15 +8,15 @@
*
* Rendering module for Microsoft Direct3D 9.
*
* Version: @(#)win_d3d.cpp 1.0.9 2017/12/15
* Version: @(#)win_d3d.cpp 1.0.10 2018/01/15
*
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
* Miran Grca, <mgrca8@gmail.com>
* Fred N. van Kempen, <decwiz@yahoo.com>
*
* Copyright 2008-2017 Sarah Walker.
* Copyright 2016,2017 Miran Grca.
* Copyright 2017 Fred N. van Kempen.
* Copyright 2008-2018 Sarah Walker.
* Copyright 2016-2018 Miran Grca.
* Copyright 2017,2018 Fred N. van Kempen.
*/
#include <stdio.h>
#include <stdint.h>
@@ -64,17 +64,25 @@ static CUSTOMVERTEX d3d_verts[] = {
};
static void
d3d_size_default(RECT w_rect, double *l, double *t, double *r, double *b)
{
*l = -0.5;
*t = -0.5;
*r = (w_rect.right - w_rect.left) - 0.5;
*b = (w_rect.bottom - w_rect.top) - 0.5;
}
static void
d3d_size(RECT w_rect, double *l, double *t, double *r, double *b, int w, int h)
{
int ratio_w, ratio_h;
double hsr, gsr, ra, d;
switch (video_fullscreen_scale) {
case FULLSCR_SCALE_FULL:
*l = -0.5;
*t = -0.5;
*r = (w_rect.right - w_rect.left) - 0.5;
*b = (w_rect.bottom - w_rect.top) - 0.5;
d3d_size_default(w_rect, l, t, r, b);
break;
case FULLSCR_SCALE_43:
@@ -113,6 +121,38 @@ d3d_size(RECT w_rect, double *l, double *t, double *r, double *b, int w, int h)
*t = ((w_rect.bottom - w_rect.top) / 2) - ((h * ratio_w) / 2) - 0.5;
*b = ((w_rect.bottom - w_rect.top) / 2) + ((h * ratio_w) / 2) - 0.5;
break;
case FULLSCR_SCALE_KEEPRATIO:
hsr = ((double) (w_rect.right - w_rect.left)) / ((double) (w_rect.bottom - w_rect.top));
gsr = ((double) w) / ((double) h);
if (hsr > gsr) {
/* Host ratio is bigger than guest ratio. */
ra = ((double) (w_rect.bottom - w_rect.top)) / ((double) h);
d = ((double) w) * ra;
d = (((double) (w_rect.right - w_rect.left)) - d) / 2.0;
*l = ((int) d) - 0.5;
*r = (w_rect.right - w_rect.left) - ((int) d) - 0.5;
*t = -0.5;
*b = (w_rect.bottom - w_rect.top) - 0.5;
} else if (hsr < gsr) {
/* Host ratio is smaller or rqual than guest ratio. */
ra = ((double) (w_rect.right - w_rect.left)) / ((double) w);
d = ((double) h) * ra;
d = (((double) (w_rect.bottom - w_rect.top)) - d) / 2.0;
*l = -0.5;
*r = (w_rect.right - w_rect.left) - 0.5;
*t = ((int) d) - 0.5;
*b = (w_rect.bottom - w_rect.top) - ((int) d) - 0.5;
} else {
/* Host ratio is equal to guest ratio. */
d3d_size_default(w_rect, l, t, r, b);
}
break;
}
}

View File

@@ -11,15 +11,15 @@
* NOTES: This code should be re-merged into a single init() with a
* 'fullscreen' argument, indicating FS mode is requested.
*
* Version: @(#)win_ddraw.cpp 1.0.4 2017/12/15
* Version: @(#)win_ddraw.cpp 1.0.5 2018/01/15
*
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
* Miran Grca, <mgrca8@gmail.com>
* Fred N. van Kempen, <decwiz@yahoo.com>
*
* Copyright 2008-2017 Sarah Walker.
* Copyright 2016,2017 Miran Grca.
* Copyright 2017 Fred N. van Kempen.
* Copyright 2008-2018 Sarah Walker.
* Copyright 2016-2018 Miran Grca.
* Copyright 2017,2018 Fred N. van Kempen.
*/
#include <stdio.h>
#include <stdint.h>
@@ -155,17 +155,27 @@ SaveBitmap(wchar_t *szFilename, HBITMAP hBitmap)
}
static void
ddraw_fs_size_default(RECT w_rect, RECT *r_dest)
{
r_dest->left = 0;
r_dest->top = 0;
r_dest->right = (w_rect.right - w_rect.left) - 1;
r_dest->bottom = (w_rect.bottom - w_rect.top) - 1;
}
static void
ddraw_fs_size(RECT w_rect, RECT *r_dest, int w, int h)
{
int ratio_w, ratio_h;
double hsr, gsr, ra, d;
pclog("video_fullscreen_scale = %i\n", video_fullscreen_scale);
switch (video_fullscreen_scale) {
case FULLSCR_SCALE_FULL:
r_dest->left = 0;
r_dest->top = 0;
r_dest->right = (w_rect.right - w_rect.left) - 1;
r_dest->bottom = (w_rect.bottom - w_rect.top) - 1;
ddraw_fs_size_default(w_rect, r_dest);
break;
case FULLSCR_SCALE_43:
@@ -204,6 +214,38 @@ ddraw_fs_size(RECT w_rect, RECT *r_dest, int w, int h)
r_dest->top = ((w_rect.bottom - w_rect.top) / 2) - ((h * ratio_w) / 2);
r_dest->bottom = ((w_rect.bottom - w_rect.top) / 2) + ((h * ratio_w) / 2) - 1;
break;
case FULLSCR_SCALE_KEEPRATIO:
hsr = ((double) (w_rect.right - w_rect.left)) / ((double) (w_rect.bottom - w_rect.top));
gsr = ((double) w) / ((double) h);
if (hsr > gsr) {
/* Host ratio is bigger than guest ratio. */
ra = ((double) (w_rect.bottom - w_rect.top)) / ((double) h);
d = ((double) w) * ra;
d = (((double) (w_rect.right - w_rect.left)) - d) / 2.0;
r_dest->left = ((int) d);
r_dest->right = (w_rect.right - w_rect.left) - ((int) d) - 1;
r_dest->top = 0;
r_dest->bottom = (w_rect.bottom - w_rect.top) - 1;
} else if (hsr < gsr) {
/* Host ratio is smaller or rqual than guest ratio. */
ra = ((double) (w_rect.right - w_rect.left)) / ((double) w);
d = ((double) h) * ra;
d = (((double) (w_rect.bottom - w_rect.top)) - d) / 2.0;
r_dest->left = 0;
r_dest->right = (w_rect.right - w_rect.left) - 1;
r_dest->top = ((int) d);
r_dest->bottom = (w_rect.bottom - w_rect.top) - ((int) d) - 1;
} else {
/* Host ratio is equal to guest ratio. */
ddraw_fs_size_default(w_rect, r_dest);
}
break;
}
}

View File

@@ -8,11 +8,11 @@
*
* Windows 86Box Settings dialog handler.
*
* Version: @(#)win_settings.c 1.0.27 2017/12/13
* Version: @(#)win_settings.c 1.0.28 2018/01/16
*
* Author: Miran Grca, <mgrca8@gmail.com>
*
* Copyright 2016,2017 Miran Grca.
* Copyright 2016-2018 Miran Grca.
*/
#define UNICODE
#define BITMAP WINDOWS_BITMAP
@@ -40,7 +40,6 @@
#include "../disk/hdd.h"
#include "../disk/hdc.h"
#include "../disk/hdc_ide.h"
#include "../floppy/floppy.h"
#include "../floppy/fdd.h"
#include "../scsi/scsi.h"
#include "../network/network.h"

View File

@@ -8,13 +8,13 @@
*
* Implement the application's Status Bar.
*
* Version: @(#)win_stbar.c 1.0.7 2017/12/13
* Version: @(#)win_stbar.c 1.0.8 2018/01/16
*
* Authors: Miran Grca, <mgrca8@gmail.com>
* Fred N. van Kempen, <decwiz@yahoo.com>
*
* Copyright 2016,2017 Miran Grca.
* Copyright 2017 Fred N. van Kempen.
* Copyright 2016-2018 Miran Grca.
* Copyright 2017,2018 Fred N. van Kempen.
*/
#define UNICODE
#define BITMAP WINDOWS_BITMAP
@@ -38,7 +38,6 @@
#include "../cdrom/cdrom_null.h"
#include "../disk/hdd.h"
#include "../disk/hdc.h"
#include "../floppy/floppy.h"
#include "../floppy/fdd.h"
#include "../scsi/scsi.h"
#include "../scsi/scsi_disk.h"
@@ -826,9 +825,9 @@ StatusBarProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
ret = file_dlg_w_st(hwnd, IDS_2159, floppyfns[id], 0);
if (! ret) {
floppy_close(id);
fdd_close(id);
ui_writeprot[id] = (item_id == IDM_FLOPPY_IMAGE_EXISTING_WP) ? 1 : 0;
floppy_load(id, wopenfilestring);
fdd_load(id, wopenfilestring);
ui_sb_update_icon_state(SB_FLOPPY | id, wcslen(floppyfns[id]) ? 0 : 1);
EnableMenuItem(sb_menu_handles[part], IDM_FLOPPY_EJECT | id, MF_BYCOMMAND | (wcslen(floppyfns[id]) ? MF_ENABLED : MF_GRAYED));
ui_sb_update_tip(SB_FLOPPY | id);
@@ -842,7 +841,7 @@ StatusBarProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
if ((part == -1) || (sb_menu_handles == NULL))
break;
floppy_close(id);
fdd_close(id);
ui_sb_update_icon_state(SB_FLOPPY | id, 1);
EnableMenuItem(sb_menu_handles[part], IDM_FLOPPY_EJECT | id, MF_BYCOMMAND | MF_GRAYED);
ui_sb_update_tip(SB_FLOPPY | id);

View File

@@ -8,15 +8,15 @@
*
* user Interface module for WinAPI on Windows.
*
* Version: @(#)win_ui.c 1.0.11 2017/12/28
* Version: @(#)win_ui.c 1.0.12 2018/01/15
*
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
* Miran Grca, <mgrca8@gmail.com>
* Fred N. van Kempen, <decwiz@yahoo.com>
*
* Copyright 2008-2017 Sarah Walker.
* Copyright 2016,2017 Miran Grca.
* Copyright 2017 Fred N. van Kempen.
* Copyright 2008-2018 Sarah Walker.
* Copyright 2016-2018 Miran Grca.
* Copyright 2017,2018 Fred N. van Kempen.
*/
#define UNICODE
#include <windows.h>
@@ -173,6 +173,7 @@ ResetAllMenus(void)
CheckMenuItem(menuMain, IDM_VID_FS_FULL+1, MF_UNCHECKED);
CheckMenuItem(menuMain, IDM_VID_FS_FULL+2, MF_UNCHECKED);
CheckMenuItem(menuMain, IDM_VID_FS_FULL+3, MF_UNCHECKED);
CheckMenuItem(menuMain, IDM_VID_FS_FULL+4, MF_UNCHECKED);
CheckMenuItem(menuMain, IDM_VID_REMEMBER, MF_UNCHECKED);
CheckMenuItem(menuMain, IDM_VID_SCALE_1X+0, MF_UNCHECKED);
CheckMenuItem(menuMain, IDM_VID_SCALE_1X+1, MF_UNCHECKED);
@@ -309,6 +310,10 @@ MainWindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
win_settings_open(hwnd);
break;
case IDM_SND_GAIN:
SoundGainDialogCreate(hwnd);
break;
case IDM_ABOUT:
AboutDialogCreate(hwnd);
break;
@@ -378,6 +383,7 @@ MainWindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
case IDM_VID_FS_43:
case IDM_VID_FS_SQ:
case IDM_VID_FS_INT:
case IDM_VID_FS_KEEPRATIO:
CheckMenuItem(hmenu, IDM_VID_FS_FULL+video_fullscreen_scale, MF_UNCHECKED);
video_fullscreen_scale = LOWORD(wParam) - IDM_VID_FS_FULL;
CheckMenuItem(hmenu, IDM_VID_FS_FULL+video_fullscreen_scale, MF_CHECKED);