Timer counters now 64-bit;

Cleaned up floppy code a lot and reverted to single poller;
Fixed segment present bit and limit checking at read/write within segment;
The ASUS boards now have memregs too;
RTC code improved based on suggestion by Sarah Walker;
Fixed SVGA odd/even emulation and added chain odd/even support;
Removed non-existent CPU's.
This commit is contained in:
OBattler
2016-07-19 02:44:32 +02:00
parent c667780aa6
commit b78b2fecaa
64 changed files with 937 additions and 1063 deletions

View File

@@ -21,7 +21,6 @@ extern uint16_t ea_rseg;
if (abrt) return 1; \
if (tempi) \
{ \
pclog("No I/O permission on port %04Xh\n", port); \
x86gpf("check_io_perm(): no permission",0); \
return 1; \
} \
@@ -45,7 +44,6 @@ extern uint16_t ea_rseg;
if (abrt) return 1; \
if (tempi) \
{ \
pclog("No I/O permission on port %04Xh\n", port); \
x86gpf("check_io_perm(): no permission",0); \
return 1; \
} \
@@ -61,7 +59,7 @@ extern uint16_t ea_rseg;
break; \
} \
}
#if 0
#define CHECK_READ(chseg, low, high) \
if ((low < (chseg)->limit_low) || (high > (chseg)->limit_high)) \
{ \
@@ -118,6 +116,52 @@ extern uint16_t ea_rseg;
x86np("Write (REP) to seg not present", (chseg)->seg & 0xfffc); \
break; \
}
#endif
#define CHECK_READ(chseg, low, high) \
if ((low < (chseg)->limit_low) || (high > (chseg)->limit_high)) \
{ \
x86gpf("Limit check", 0); \
return 1; \
} \
if (msw&1 && !(eflags&VM_FLAG) && !((chseg)->access & 0x80)) \
{ \
if ((chseg) == &_ss) \
x86ss(NULL,(chseg)->seg & 0xfffc); \
else \
x86np("Read from seg not present", (chseg)->seg & 0xfffc); \
return 1; \
}
#define CHECK_WRITE(chseg, low, high) \
if ((low < (chseg)->limit_low) || (high > (chseg)->limit_high) || !((chseg)->access & 2)) \
{ \
x86gpf("Limit check", 0); \
return 1; \
} \
if (msw&1 && !(eflags&VM_FLAG) && !((chseg)->access & 0x80)) \
{ \
if ((chseg) == &_ss) \
x86ss(NULL,(chseg)->seg & 0xfffc); \
else \
x86np("Write to seg not present", (chseg)->seg & 0xfffc); \
return 1; \
}
#define CHECK_WRITE_REP(chseg, low, high) \
if ((low < (chseg)->limit_low) || (high > (chseg)->limit_high)) \
{ \
x86gpf("Limit check", 0); \
break; \
} \
if (msw&1 && !(eflags&VM_FLAG) && !((chseg)->access & 0x80)) \
{ \
if ((chseg) == &_ss) \
x86ss(NULL,(chseg)->seg & 0xfffc); \
else \
x86np("Write (REP) to seg not present", (chseg)->seg & 0xfffc); \
break; \
}
#define NOTRM if (!(msw & 1) || (eflags & VM_FLAG))\

View File

@@ -1126,7 +1126,7 @@ int checkio(int port)
// d = readmemb386l(0, tr.base + t + (port >> 3));
d=readmemb(tr.base,t+(port>>3));
cpl_override = 0;
if (d&(1<<(port&7))) pclog("%02X %02X %08X:%04X\n",d,d&(1<<(port&7)), tr.base, t);
// if (d&(1<<(port&7))) pclog("%02X %02X %08X:%04X\n",d,d&(1<<(port&7)), tr.base, t);
if ((port & 0xfff8) == 0x1f0)
{
// if (d&(1<<(port&7))) fatal("Trying to read from IDE port %04X without permission\n", port);

View File

@@ -518,6 +518,7 @@ chdir(pcempath);
/* f=fopen("rram3.dmp","wb");
for (c=0;c<0x8000000;c++) putc(readmemb(c+0x10000000),f);
fclose(f);*/
svga_dump_vram();
f=fopen("ram.dmp","wb");
fwrite(ram,mem_size*1024,1,f);
fclose(f);

View File

@@ -412,16 +412,8 @@ CPU cpus_Pentium5V50[] =
CPU cpus_PentiumS5[] =
{
/*Intel Pentium (Socket 5)*/
{"Pentium 50 (Q0399)",CPU_PENTIUM, 5, 50000000, 1, 25000000, 0x513, 0x513, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC},
{"Pentium MMX 50", CPU_PENTIUMMMX, 5, 50000000, 1, 25000000, 0x543, 0x543, 0, CPU_SUPPORTS_DYNAREC},
{"Pentium 60", CPU_PENTIUM, 6, 60000000, 1, 30000000, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC},
{"Pentium MMX 60", CPU_PENTIUMMMX, 6, 60000000, 1, 30000000, 0x543, 0x543, 0, CPU_SUPPORTS_DYNAREC},
{"Pentium 66", CPU_PENTIUM, 6, 66666666, 1, 33333333, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC},
{"Pentium MMX 66", CPU_PENTIUMMMX, 6, 66666666, 1, 33333333, 0x543, 0x543, 0, CPU_SUPPORTS_DYNAREC},
{"Pentium 75", CPU_PENTIUM, 9, 75000000, 2, 25000000, 0x524, 0x524, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC},
{"Pentium MMX 75", CPU_PENTIUMMMX, 9, 75000000, 2, 25000000, 0x543, 0x543, 0, CPU_SUPPORTS_DYNAREC},
{"Pentium 90", CPU_PENTIUM, 12, 90000000, 2, 30000000, 0x524, 0x524, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC},
{"Pentium MMX 90", CPU_PENTIUMMMX, 12, 90000000, 2, 30000000, 0x543, 0x543, 0, CPU_SUPPORTS_DYNAREC},
{"Pentium 100/50", CPU_PENTIUM, 13, 100000000, 2, 25000000, 0x525, 0x525, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC},
{"Pentium 100/66", CPU_PENTIUM, 13, 100000000, 2, 33333333, 0x525, 0x525, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC},
{"Pentium 120", CPU_PENTIUM, 14, 120000000, 2, 30000000, 0x526, 0x526, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC},
@@ -439,16 +431,8 @@ CPU cpus_PentiumS5[] =
CPU cpus_Pentium[] =
{
/*Intel Pentium*/
{"Pentium 50 (Q0399)",CPU_PENTIUM, 5, 50000000, 1, 25000000, 0x513, 0x513, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC},
{"Pentium MMX 50", CPU_PENTIUMMMX, 5, 50000000, 1, 25000000, 0x543, 0x543, 0, CPU_SUPPORTS_DYNAREC},
{"Pentium 60", CPU_PENTIUM, 6, 60000000, 1, 30000000, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC},
{"Pentium MMX 60", CPU_PENTIUMMMX, 6, 60000000, 1, 30000000, 0x543, 0x543, 0, CPU_SUPPORTS_DYNAREC},
{"Pentium 66", CPU_PENTIUM, 6, 66666666, 1, 33333333, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC},
{"Pentium MMX 66", CPU_PENTIUMMMX, 6, 66666666, 1, 33333333, 0x543, 0x543, 0, CPU_SUPPORTS_DYNAREC},
{"Pentium 75", CPU_PENTIUM, 9, 75000000, 2, 25000000, 0x524, 0x524, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC},
{"Pentium MMX 75", CPU_PENTIUMMMX, 9, 75000000, 2, 25000000, 0x543, 0x543, 0, CPU_SUPPORTS_DYNAREC},
{"Pentium 90", CPU_PENTIUM, 12, 90000000, 2, 30000000, 0x524, 0x524, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC},
{"Pentium MMX 90", CPU_PENTIUMMMX, 12, 90000000, 2, 30000000, 0x543, 0x543, 0, CPU_SUPPORTS_DYNAREC},
{"Pentium 100/50", CPU_PENTIUM, 13, 100000000, 2, 25000000, 0x525, 0x525, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC},
{"Pentium 100/66", CPU_PENTIUM, 13, 100000000, 2, 33333333, 0x525, 0x525, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC},
{"Pentium 120", CPU_PENTIUM, 14, 120000000, 2, 30000000, 0x526, 0x526, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC},

View File

@@ -121,8 +121,8 @@ extern int cpu_hasCR4;
extern uint64_t cpu_CR4_mask;
#define CPU_SUPPORTS_DYNAREC 1
// #define CPU_REQUIRES_DYNAREC 2
#define CPU_REQUIRES_DYNAREC 0
#define CPU_REQUIRES_DYNAREC 2
// #define CPU_REQUIRES_DYNAREC 0
extern uint64_t tsc;

View File

@@ -6,14 +6,10 @@
#include "disc_img.h"
#include "fdc.h"
#include "fdd.h"
#include "pit.h"
#include "timer.h"
#include "disc_sector.h"
int disc_drivesel = 0;
int disc_poll_time = 16;
int poll_time[2] = {16, 16};
int64_t disc_poll_time = 16;
int disc_track[2];
int writeprot[2], fwriteprot[2];
@@ -37,8 +33,6 @@ int fdc_ready;
int drive_empty[2] = {1, 1};
int disc_changed[2];
int bpulses[2] = {0, 0};
int motorspin;
int motoron;
@@ -82,7 +76,6 @@ void disc_load(int drive, char *fn)
FILE *f;
// pclog("disc_load %i %s\n", drive, fn);
// setejecttext(drive, "");
fdd_stepping_motor_on[drive] = fdd_track_diff[drive] = NULL;
if (!fn) return;
p = get_extension(fn);
if (!p) return;
@@ -126,12 +119,11 @@ void disc_close(int drive)
drives[drive].readaddress = NULL;
drives[drive].format = NULL;
drives[drive].realtrack = NULL;
drives[drive].byteperiod = NULL;
drives[drive].stop = NULL;
fdd_stepping_motor_on[drive] = fdd_track_diff[drive] = 0;
}
int disc_notfound=0;
int not_found[2] = {0, 0};
static int disc_period = 32;
int disc_hole(int drive)
@@ -162,32 +154,24 @@ int disc_byteperiod(int drive)
}
}
#define ACCURATE_TIMER_USEC ((((double) cpuclock) / 1000000.0) * (double)(1 << TIMER_SHIFT))
uint32_t byte_pulses = 0;
#if 0
void disc_time_adjust()
double disc_real_period()
{
if (disc_byteperiod(disc_drivesel ^ fdd_swap) == 26)
disc_poll_time -= ((160.0 / 6.0) * ACCURATE_TIMER_USEC);
else
disc_poll_time -= 25.0 * ((double) disc_byteperiod(disc_drivesel ^ fdd_swap)) * ACCURATE_TIMER_USEC;
int64_t dbp = disc_byteperiod(disc_drivesel ^ fdd_swap);
double ddbp = (double) dbp;
if (dbp == 26) ddbp = 160.0 / 6.0;
double dusec = (double) TIMER_USEC;
return (ddbp * dusec);
}
void disc_poll()
{
// disc_poll_time += disc_period * TIMER_USEC;
if (disc_byteperiod(disc_drivesel ^ fdd_swap) == 26)
disc_poll_time += ((160.0 / 6.0) * ACCURATE_TIMER_USEC);
else
disc_poll_time += ((double) disc_byteperiod(disc_drivesel ^ fdd_swap)) * ACCURATE_TIMER_USEC;
byte_pulses++;
if ((byte_pulses > 6250) && (byte_pulses <= 6275)) pclog("Byte pulses is now %i!\n", byte_pulses);
disc_poll_time += (int64_t) disc_real_period();
if (drives[disc_drivesel].poll)
drives[disc_drivesel].poll(disc_drivesel);
drives[disc_drivesel].poll();
if (disc_notfound)
{
@@ -196,79 +180,6 @@ void disc_poll()
fdc_notfound();
}
}
#endif
// #define TIMER_SUB 441 // 736
// #define TIMER_SUB 0
#define TIMER_SUB 0
double dt[2] = {0.0, 0.0};
double dt2[2] = {0.0, 0.0};
void disc_poll_ex(int poll_drive)
{
int dp = 0;
double pm = 1.0;
int dbp = disc_byteperiod(poll_drive ^ fdd_swap);
double ddbp = (double) dbp;
double dtime = 0.0;
double dusec = (double) TIMER_USEC;
double dsub = (double) TIMER_SUB;
if (dbp == 26) ddbp = 160.0 / 6.0;
if (not_found[poll_drive])
{
not_found[poll_drive]--;
if (!not_found[poll_drive])
fdc_notfound();
}
else
{
if (drives[poll_drive].poll)
dp = drives[poll_drive].poll(poll_drive);
}
#if 0
if (dp == 2)
{
pm = 15.0 / 16.0;
pclog("SYNC byte detected\n");
}
#endif
dtime = (ddbp * pm * dusec) - dsub;
poll_time[poll_drive] += (int) dtime;
dt[poll_drive] += dtime;
if (dp) dt2[poll_drive] += dtime;
if (dp) bpulses[poll_drive]++;
// if (!dp && (byte_pulses == 10416))
if (bpulses[poll_drive] == raw_tsize[poll_drive])
{
pclog("Sent %i byte pulses for drive %c (time: %lf | %lf)\n", raw_tsize[poll_drive], 0x41 + poll_drive, dt[poll_drive], dt2[poll_drive]);
// poll_time[poll_drive] += (dbp * (2.0 / 3.0) * pm * TIMER_USEC) - TIMER_SUB;
// dt[poll_drive] = dt2[poll_drive] = bpulses[poll_drive] = motor_on[poll_drive] = 0;
// disc_stop(poll_drive ^ fdd_swap); /* Send drive to idle state after enough byte pulses have been sent. */
/* Disc state is already set to idle on finish or error anyway. */
}
}
void disc_poll_0()
{
disc_poll_ex(0);
}
void disc_poll_1()
{
disc_poll_ex(1);
}
int disc_get_bitcell_period(int rate)
{
@@ -327,11 +238,7 @@ void disc_reset()
{
curdrive = 0;
disc_period = 32;
fdd_stepping_motor_on[0] = fdd_track_diff[0] = 0;
fdd_stepping_motor_on[1] = fdd_track_diff[1] = 0;
// timer_add(disc_poll, &disc_poll_time, &motoron, NULL);
timer_add(disc_poll_0, &(poll_time[0]), &(motor_on[0]), NULL);
timer_add(disc_poll_1, &(poll_time[1]), &(motor_on[1]), NULL);
timer_add(disc_poll, &disc_poll_time, &motoron, NULL);
}
void disc_init()
@@ -360,19 +267,9 @@ void disc_readsector(int drive, int sector, int track, int side, int density, in
drive ^= fdd_swap;
if (drives[drive].readsector)
{
drives[drive].readsector(drive, sector, track, side, density, sector_size);
pclog("Byte pulses: %i\n", bpulses[drive]);
bpulses[drive] = 0;
dt[drive] = dt2[drive] = 0;
// motor_on[drive] = 1;
poll_time[drive] = 0;
}
else
not_found[drive] = 1000;
#if 0
disc_notfound = 1000;
#endif
}
void disc_writesector(int drive, int sector, int track, int side, int density, int sector_size)
@@ -380,18 +277,9 @@ void disc_writesector(int drive, int sector, int track, int side, int density, i
drive ^= fdd_swap;
if (drives[drive].writesector)
{
drives[drive].writesector(drive, sector, track, side, density, sector_size);
bpulses[drive] = 0;
dt[drive] = dt2[drive] = 0;
// motor_on[drive] = 1;
poll_time[drive] = 0;
}
else
not_found[drive] = 1000;
#if 0
disc_notfound = 1000;
#endif
}
void disc_readaddress(int drive, int track, int side, int density)
@@ -399,13 +287,7 @@ void disc_readaddress(int drive, int track, int side, int density)
drive ^= fdd_swap;
if (drives[drive].readaddress)
{
drives[drive].readaddress(drive, track, side, density);
bpulses[drive] = 0;
dt[drive] = dt2[drive] = 0;
// motor_on[drive] = 1;
poll_time[drive] = 0;
}
}
void disc_format(int drive, int track, int side, int density, uint8_t fill)
@@ -413,18 +295,9 @@ void disc_format(int drive, int track, int side, int density, uint8_t fill)
drive ^= fdd_swap;
if (drives[drive].format)
{
drives[drive].format(drive, track, side, density, fill);
bpulses[drive] = 0;
dt[drive] = dt2[drive] = 0;
// motor_on[drive] = 1;
poll_time[drive] = 0;
}
else
not_found[drive] = 1000;
#if 0
disc_notfound = 1000;
#endif
}
int disc_realtrack(int drive, int track)

View File

@@ -8,7 +8,7 @@ typedef struct
int (*hole)(int drive);
int (*byteperiod)(int drive);
void (*stop)(int drive);
int (*poll)(int drive);
void (*poll)();
int (*realtrack)(int drive, int track);
} DRIVE;
@@ -27,7 +27,6 @@ void disc_readsector(int drive, int sector, int track, int side, int density, in
void disc_writesector(int drive, int sector, int track, int side, int density, int sector_size);
void disc_readaddress(int drive, int track, int side, int density);
void disc_format(int drive, int track, int side, int density, uint8_t fill);
void disc_time_adjust();
int disc_realtrack(int drive, int track);
int disc_hole(int drive);
int disc_byteperiod(int drive);
@@ -36,11 +35,8 @@ int disc_empty(int drive);
void disc_set_rate(int drive, int drvden, int rate);
void disc_set_drivesel(int drive);
extern int disc_time;
extern int disc_poll_time;
extern int poll_time[2];
extern int64_t disc_poll_time;
extern int disc_drivesel;
extern int disc_notfound;
extern int not_found[2];
void fdc_callback();
int fdc_data(uint8_t dat);
@@ -60,8 +56,6 @@ extern int fdc_indexcount;*/
extern int motorspin;
extern int motoron;
extern int motor_on[2];
extern int swwp;
extern int disable_write;
@@ -74,10 +68,6 @@ extern int disc_changed[2];
extern int drive_empty[2];
extern int drive_type[2];
extern uint32_t byte_pulses;
extern int bpulses[2];
/*Used in the Read A Track command. Only valid for disc_readsector(). */
#define SECTOR_FIRST -2
#define SECTOR_NEXT -1

View File

@@ -19,23 +19,15 @@ static struct
} fdi[2];
static uint8_t fdi_timing[256*1024];
#if 0
static int fdi_pos;
static int fdi_revs;
static int fdi_sector, fdi_track, fdi_side, fdi_drive, fdi_density, fdi_n;
static int fdi_inread, fdi_inwrite, fdi_readpos, fdi_inreadaddr;
#endif
static int fdi_pos[2];
static int fdi_revs[2];
static int fdi_sector[2], fdi_track[2], fdi_side[2], fdi_drive[2], fdi_density[2], fdi_n[2];
static int fdi_inread[2], fdi_inwrite[2], fdi_readpos[2], fdi_inreadaddr[2];
static uint16_t CRCTable[256];
static int pollbytesleft[2]={0, 0},pollbitsleft[2]={0, 0};
static int pollbytesleft=0,pollbitsleft=0;
int fdi_realtrack(int drive, int track)
{
@@ -75,19 +67,6 @@ void fdi_init()
fdi_setupcrc(0x1021, 0xcdb4);
}
int fdi_hole(int drive)
{
switch (fdi2raw_get_bit_rate(fdi[drive].h))
{
case 1000:
return 2;
case 500:
return 1;
default:
return 0;
}
}
int fdi_byteperiod(int drive)
{
switch (fdi2raw_get_bit_rate(fdi[drive].h))
@@ -100,6 +79,19 @@ int fdi_byteperiod(int drive)
return 26;
case 250:
return 32;
default:
return 32;
}
}
int fdi_hole(int drive)
{
switch (fdi2raw_get_bit_rate(fdi[drive].h))
{
case 1000:
return 2;
case 500:
return 1;
default:
return 0;
}
@@ -173,7 +165,7 @@ void fdi_seek(int drive, int track)
else
{
memset(fdi[drive].track_data[1][density], 0, 65536);
fdi[drive].tracklen[0][density] = fdi[drive].tracklen[1][density] = 10000;
fdi[drive].tracklen[1][density] = fdi[drive].tracklen[1][density] = 10000;
}
}
}
@@ -185,97 +177,97 @@ void fdi_writeback(int drive, int track)
void fdi_readsector(int drive, int sector, int track, int side, int rate, int sector_size)
{
fdi_revs[drive] = 0;
fdi_sector[drive] = sector;
fdi_track[drive] = track;
fdi_side[drive] = side;
fdi_n[drive] = sector_size;
// fdi_drive = drive;
fdi_revs = 0;
fdi_sector = sector;
fdi_track = track;
fdi_side = side;
fdi_n = sector_size;
fdi_drive = drive;
if (rate == 2)
fdi_density[drive] = 1;
fdi_density = 1;
if (rate == 0)
fdi_density[drive] = 2;
fdi_density = 2;
if (rate == 3)
fdi_density[drive] = 3;
fdi_density = 3;
// pclog("FDI Read sector %i %i %i %i %i\n",drive,side,track,sector, fdi_density);
// if (pollbytesleft)
// pclog("In the middle of a sector!\n");
fdi_inread[drive] = 1;
fdi_inwrite[drive] = 0;
fdi_inreadaddr[drive] = 0;
fdi_readpos[drive] = 0;
fdi_inread = 1;
fdi_inwrite = 0;
fdi_inreadaddr = 0;
fdi_readpos = 0;
}
void fdi_writesector(int drive, int sector, int track, int side, int rate, int sector_size)
{
fdi_revs[drive] = 0;
fdi_sector[drive] = sector;
fdi_track[drive] = track;
fdi_side[drive] = side;
fdi_n[drive] = sector_size;
// fdi_drive = drive;
fdi_revs = 0;
fdi_sector = sector;
fdi_track = track;
fdi_side = side;
fdi_n = sector_size;
fdi_drive = drive;
if (rate == 2)
fdi_density[drive] = 1;
fdi_density = 1;
if (rate == 0)
fdi_density[drive] = 2;
fdi_density = 2;
if (rate == 3)
fdi_density[drive] = 3;
fdi_density = 3;
// pclog("Write sector %i %i %i %i\n",drive,side,track,sector);
fdi_inread[drive] = 0;
fdi_inwrite[drive] = 1;
fdi_inreadaddr[drive] = 0;
fdi_readpos[drive] = 0;
fdi_inread = 0;
fdi_inwrite = 1;
fdi_inreadaddr = 0;
fdi_readpos = 0;
}
void fdi_readaddress(int drive, int track, int side, int rate)
{
fdi_revs[drive] = 0;
fdi_track[drive] = track;
fdi_side[drive] = side;
// fdi_drive = drive;
fdi_revs = 0;
fdi_track = track;
fdi_side = side;
fdi_drive = drive;
if (rate == 2)
fdi_density[drive] = 1;
fdi_density = 1;
if (rate == 0)
fdi_density[drive] = 2;
fdi_density = 2;
if (rate == 3)
fdi_density[drive] = 3;
fdi_density = 3;
// pclog("Read address %i %i %i %i %i %p\n",drive,side,track, rate, fdi_density, &fdi_inreadaddr);
fdi_inread[drive] = 0;
fdi_inwrite[drive] = 0;
fdi_inreadaddr[drive] = 1;
fdi_readpos[drive] = 0;
fdi_inread = 0;
fdi_inwrite = 0;
fdi_inreadaddr = 1;
fdi_readpos = 0;
}
void fdi_format(int drive, int track, int side, int rate, uint8_t fill)
{
fdi_revs[drive] = 0;
fdi_track[drive] = track;
fdi_side[drive] = side;
// fdi_drive = drive;
fdi_revs = 0;
fdi_track = track;
fdi_side = side;
fdi_drive = drive;
if (rate == 2)
fdi_density[drive] = 1;
fdi_density = 1;
if (rate == 0)
fdi_density[drive] = 2;
fdi_density = 2;
if (rate == 3)
fdi_density[drive] = 3;
fdi_density = 3;
// pclog("Format %i %i %i\n",drive,side,track);
fdi_inread[drive] = 0;
fdi_inwrite[drive] = 1;
fdi_inreadaddr[drive] = 0;
fdi_readpos[drive] = 0;
fdi_inread = 0;
fdi_inwrite = 1;
fdi_inreadaddr = 0;
fdi_readpos = 0;
}
static uint16_t fdi_buffer[2];
static int readidpoll[2]={0, 0},readdatapoll[2]={0, 0},fdi_nextsector[2]={0, 0},inreadop[2]={0, 0};
static uint8_t fdi_sectordat[2][1026];
static int lastfdidat[2][2],sectorcrc[2][2];
static int sectorsize[2],fdc_sectorsize[2];
static int ddidbitsleft[2]={0, 0};
static uint16_t fdi_buffer;
static int readidpoll=0,readdatapoll=0,fdi_nextsector=0,inreadop=0;
static uint8_t fdi_sectordat[1026];
static int lastfdidat[2],sectorcrc[2];
static int sectorsize,fdc_sectorsize;
static int ddidbitsleft=0;
static uint8_t decodefm(uint16_t dat)
{
@@ -295,216 +287,216 @@ static uint8_t decodefm(uint16_t dat)
void fdi_stop(int drive)
{
// pclog("fdi_stop\n");
fdi_inread[drive] = fdi_inwrite[drive] = fdi_inreadaddr[drive] = 0;
fdi_nextsector[drive] = ddidbitsleft[drive] = pollbitsleft[drive] = 0;
fdi_inread = fdi_inwrite = fdi_inreadaddr = 0;
fdi_nextsector = ddidbitsleft = pollbitsleft = 0;
}
static uint16_t crc[2];
static uint16_t crc;
static void calccrc(int drive, uint8_t byte)
static void calccrc(uint8_t byte)
{
crc[drive] = (crc[drive] << 8) ^ CRCTable[(crc[drive] >> 8)^byte];
crc = (crc << 8) ^ CRCTable[(crc >> 8)^byte];
}
static int fdi_indextime_blank[2] = {6250 * 8, 6250 * 8};
int fdi_poll(int drive)
static int fdi_indextime_blank = 6250 * 8;
void fdi_poll()
{
int tempi, c;
int bitcount;
for (bitcount = 0; bitcount < 16; bitcount++)
{
if (fdi_pos[drive] >= fdi[drive].tracklen[fdi_side[drive]][fdi_density[drive]])
if (fdi_pos >= fdi[fdi_drive].tracklen[fdi_side][fdi_density])
{
fdi_pos[drive] = 0;
if (fdi[drive].tracklen[fdi_side[drive]][fdi_density[drive]])
fdi_pos = 0;
if (fdi[fdi_drive].tracklen[fdi_side][fdi_density])
fdc_indexpulse();
else
{
fdi_indextime_blank[drive]--;
if (!fdi_indextime_blank[drive])
fdi_indextime_blank--;
if (!fdi_indextime_blank)
{
fdi_indextime_blank[drive] = 6250 * 8;
fdi_indextime_blank = 6250 * 8;
fdc_indexpulse();
}
}
}
tempi = fdi[drive].track_data[fdi_side[drive]][fdi_density[drive]][((fdi_pos[drive] >> 3) & 0xFFFF) ^ 1] & (1 << (7 - (fdi_pos[drive] & 7)));
fdi_pos[drive]++;
fdi_buffer[drive] <<= 1;
fdi_buffer[drive] |= (tempi ? 1 : 0);
if (fdi_inwrite[drive])
tempi = fdi[fdi_drive].track_data[fdi_side][fdi_density][((fdi_pos >> 3) & 0xFFFF) ^ 1] & (1 << (7 - (fdi_pos & 7)));
fdi_pos++;
fdi_buffer <<= 1;
fdi_buffer |= (tempi ? 1 : 0);
if (fdi_inwrite)
{
fdi_inwrite[drive] = 0;
fdi_inwrite = 0;
fdc_writeprotect();
return 1;
return;
}
if (!fdi_inread[drive] && !fdi_inreadaddr[drive])
return 1;
if (fdi_pos[drive] == fdi[drive].trackindex[fdi_side[drive]][fdi_density[drive]])
if (!fdi_inread && !fdi_inreadaddr)
return;
if (fdi_pos == fdi[fdi_drive].trackindex[fdi_side][fdi_density])
{
fdi_revs[drive]++;
if (fdi_revs[drive] == 3)
fdi_revs++;
if (fdi_revs == 3)
{
// pclog("Not found!\n");
fdc_notfound();
fdi_inread[drive] = fdi_inreadaddr[drive] = 0;
return 1;
fdi_inread = fdi_inreadaddr = 0;
return;
}
if (fdi_sector[drive] == SECTOR_FIRST)
fdi_sector[drive] = SECTOR_NEXT;
if (fdi_sector == SECTOR_FIRST)
fdi_sector = SECTOR_NEXT;
}
if (pollbitsleft[drive])
if (pollbitsleft)
{
pollbitsleft[drive]--;
if (!pollbitsleft[drive])
pollbitsleft--;
if (!pollbitsleft)
{
pollbytesleft[drive]--;
if (pollbytesleft[drive]) pollbitsleft[drive] = 16; /*Set up another word if we need it*/
if (readidpoll[drive])
pollbytesleft--;
if (pollbytesleft) pollbitsleft = 16; /*Set up another word if we need it*/
if (readidpoll)
{
fdi_sectordat[drive][5 - pollbytesleft[drive]] = decodefm(fdi_buffer[drive]);
if (fdi_inreadaddr[drive] && !fdc_sectorid)// && pollbytesleft[drive] > 1)
fdi_sectordat[5 - pollbytesleft] = decodefm(fdi_buffer);
if (fdi_inreadaddr && !fdc_sectorid)// && pollbytesleft > 1)
{
// rpclog("inreadaddr - %02X\n", fdi_sectordat[drive][5 - pollbytesleft][drive]);
fdc_data(fdi_sectordat[drive][5 - pollbytesleft[drive]]);
// rpclog("inreadaddr - %02X\n", fdi_sectordat[5 - pollbytesleft]);
fdc_data(fdi_sectordat[5 - pollbytesleft]);
}
if (!pollbytesleft[drive])
if (!pollbytesleft)
{
// pclog("Header over %i,%i %i,%i\n", fdi_sectordat[drive][0], fdi_sectordat[drive][2], fdi_track[drive], fdi_sector[drive]);
if ((fdi_sectordat[drive][0] == fdi_track[drive] && (fdi_sectordat[drive][3] == fdi_n[drive]) && (fdi_sectordat[drive][2] == fdi_sector[drive] || fdi_sector[drive] == SECTOR_NEXT)) || fdi_inreadaddr[drive])
// pclog("Header over %i,%i %i,%i\n", fdi_sectordat[0], fdi_sectordat[2], fdi_track, fdi_sector);
if ((fdi_sectordat[0] == fdi_track && (fdi_sectordat[3] == fdi_n) && (fdi_sectordat[2] == fdi_sector || fdi_sector == SECTOR_NEXT)) || fdi_inreadaddr)
{
crc[drive] = (fdi_density) ? 0xcdb4 : 0xffff;
calccrc(drive, 0xFE);
crc = (fdi_density) ? 0xcdb4 : 0xffff;
calccrc(0xFE);
for (c = 0; c < 4; c++)
calccrc(drive, fdi_sectordat[drive][c]);
calccrc(fdi_sectordat[c]);
if ((crc[drive] >> 8) != fdi_sectordat[drive][4] || (crc[drive] & 0xFF) != fdi_sectordat[drive][5])
if ((crc >> 8) != fdi_sectordat[4] || (crc & 0xFF) != fdi_sectordat[5])
{
// pclog("Header CRC error : %02X %02X %02X %02X\n",crc[drive]>>8,crc[drive]&0xFF,fdi_sectordat[drive][4],fdi_sectordat[drive][5]);
// pclog("Header CRC error : %02X %02X %02X %02X\n",crc>>8,crc&0xFF,fdi_sectordat[4],fdi_sectordat[5]);
// dumpregs();
// exit(-1);
inreadop[drive] = 0;
if (fdi_inreadaddr[drive])
inreadop = 0;
if (fdi_inreadaddr)
{
// rpclog("inreadaddr - %02X\n", fdi_sector[drive]);
// fdc_data(fdi_sector[drive]);
// rpclog("inreadaddr - %02X\n", fdi_sector);
// fdc_data(fdi_sector);
if (fdc_sectorid)
fdc_sectorid(fdi_sectordat[drive][0], fdi_sectordat[drive][1], fdi_sectordat[drive][2], fdi_sectordat[drive][3], fdi_sectordat[drive][4], fdi_sectordat[drive][5]);
fdc_sectorid(fdi_sectordat[0], fdi_sectordat[1], fdi_sectordat[2], fdi_sectordat[3], fdi_sectordat[4], fdi_sectordat[5]);
else
fdc_finishread(drive);
fdc_finishread();
}
else fdc_headercrcerror();
return 1;
return;
}
// pclog("Sector %i,%i %i,%i\n", fdi_sectordat[drive][0], fdi_sectordat[drive][2], fdi_track[drive], fdi_sector[drive]);
if (fdi_sectordat[drive][0] == fdi_track[drive] && (fdi_sectordat[drive][2] == fdi_sector[drive] || fdi_sector[drive] == SECTOR_NEXT) && fdi_inread[drive] && !fdi_inreadaddr[drive])
// pclog("Sector %i,%i %i,%i\n", fdi_sectordat[0], fdi_sectordat[2], fdi_track, fdi_sector);
if (fdi_sectordat[0] == fdi_track && (fdi_sectordat[2] == fdi_sector || fdi_sector == SECTOR_NEXT) && fdi_inread && !fdi_inreadaddr)
{
fdi_nextsector[drive] = 1;
readidpoll[drive] = 0;
sectorsize[drive] = (1 << (fdi_sectordat[drive][3] + 7)) + 2;
fdc_sectorsize[drive] = fdi_sectordat[drive][3];
fdi_nextsector = 1;
readidpoll = 0;
sectorsize = (1 << (fdi_sectordat[3] + 7)) + 2;
fdc_sectorsize = fdi_sectordat[3];
}
if (fdi_inreadaddr[drive])
if (fdi_inreadaddr)
{
if (fdc_sectorid)
fdc_sectorid(fdi_sectordat[drive][0], fdi_sectordat[drive][1], fdi_sectordat[drive][2], fdi_sectordat[drive][3], fdi_sectordat[drive][4], fdi_sectordat[drive][5]);
fdc_sectorid(fdi_sectordat[0], fdi_sectordat[1], fdi_sectordat[2], fdi_sectordat[3], fdi_sectordat[4], fdi_sectordat[5]);
else
fdc_finishread(drive);
fdi_inreadaddr[drive] = 0;
fdc_finishread();
fdi_inreadaddr = 0;
}
}
}
}
if (readdatapoll[drive])
if (readdatapoll)
{
// pclog("readdatapoll %i %02x\n", pollbytesleft[drive], decodefm(fdi_buffer[drive]));
if (pollbytesleft[drive] > 1)
// pclog("readdatapoll %i %02x\n", pollbytesleft, decodefm(fdi_buffer));
if (pollbytesleft > 1)
{
calccrc(drive, decodefm(fdi_buffer[drive]));
calccrc(decodefm(fdi_buffer));
}
else
sectorcrc[drive][1 - pollbytesleft[drive]] = decodefm(fdi_buffer[drive]);
if (!pollbytesleft[drive])
sectorcrc[1 - pollbytesleft] = decodefm(fdi_buffer);
if (!pollbytesleft)
{
fdi_inread[drive] = 0;
fdi_inread = 0;
//#if 0
if ((crc[drive] >> 8) != sectorcrc[drive][0] || (crc[drive] & 0xFF) != sectorcrc[drive][1])// || (fditrack[drive]==79 && fdisect[drive]==4 && fdc_side[drive]&1))
if ((crc >> 8) != sectorcrc[0] || (crc & 0xFF) != sectorcrc[1])// || (fditrack==79 && fdisect==4 && fdc_side&1))
{
// pclog("Data CRC error : %02X %02X %02X %02X %i %04X %02X%02X\n",crc[drive]>>8,crc[drive]&0xFF,sectorcrc[0],sectorcrc[1],fdi_pos,crc,sectorcrc[0],sectorcrc[1]);
inreadop[drive] = 0;
fdc_data(decodefm(lastfdidat[drive][1]));
fdc_finishread(drive);
// pclog("Data CRC error : %02X %02X %02X %02X %i %04X %02X%02X\n",crc>>8,crc&0xFF,sectorcrc[0],sectorcrc[1],fdi_pos,crc,sectorcrc[0],sectorcrc[1]);
inreadop = 0;
fdc_data(decodefm(lastfdidat[1]));
fdc_finishread();
fdc_datacrcerror();
readdatapoll[drive] = 0;
return 1;
readdatapoll = 0;
return;
}
//#endif
// pclog("End of FDI read %02X %02X %02X %02X\n",crc[drive]>>8,crc[drive]&0xFF,sectorcrc[0],sectorcrc[1]);
fdc_data(decodefm(lastfdidat[drive][1]));
fdc_finishread(drive);
// pclog("End of FDI read %02X %02X %02X %02X\n",crc>>8,crc&0xFF,sectorcrc[0],sectorcrc[1]);
fdc_data(decodefm(lastfdidat[1]));
fdc_finishread();
}
else if (lastfdidat[drive][1] != 0)
fdc_data(decodefm(lastfdidat[drive][1]));
lastfdidat[drive][1] = lastfdidat[drive][0];
lastfdidat[drive][0] = fdi_buffer[drive];
if (!pollbytesleft[drive])
readdatapoll[drive] = 0;
else if (lastfdidat[1] != 0)
fdc_data(decodefm(lastfdidat[1]));
lastfdidat[1] = lastfdidat[0];
lastfdidat[0] = fdi_buffer;
if (!pollbytesleft)
readdatapoll = 0;
}
}
}
if (fdi_buffer[drive] == 0x4489 && fdi_density[drive])
if (fdi_buffer == 0x4489 && fdi_density)
{
// rpclog("Found sync\n");
ddidbitsleft[drive] = 17;
ddidbitsleft = 17;
}
if (fdi_buffer[drive] == 0xF57E && !fdi_density[drive])
if (fdi_buffer == 0xF57E && !fdi_density)
{
pollbytesleft[drive] = 6;
pollbitsleft[drive] = 16;
readidpoll[drive] = 1;
pollbytesleft = 6;
pollbitsleft = 16;
readidpoll = 1;
}
if ((fdi_buffer[drive] == 0xF56F || fdi_buffer[drive] == 0xF56A) && !fdi_density[drive])
if ((fdi_buffer == 0xF56F || fdi_buffer == 0xF56A) && !fdi_density)
{
if (fdi_nextsector[drive])
if (fdi_nextsector)
{
pollbytesleft[drive] = sectorsize[drive];
pollbitsleft[drive] = 16;
readdatapoll[drive] = 1;
fdi_nextsector[drive] = 0;
crc[drive] = 0xffff;
if (fdi_buffer[drive] == 0xF56A) calccrc(drive, 0xF8);
else calccrc(drive, 0xFB);
lastfdidat[drive][0] = lastfdidat[drive][1] = 0;
pollbytesleft = sectorsize;
pollbitsleft = 16;
readdatapoll = 1;
fdi_nextsector = 0;
crc = 0xffff;
if (fdi_buffer == 0xF56A) calccrc(0xF8);
else calccrc(0xFB);
lastfdidat[0] = lastfdidat[1] = 0;
}
}
if (ddidbitsleft[drive])
if (ddidbitsleft)
{
ddidbitsleft[drive]--;
if (!ddidbitsleft[drive] && !readdatapoll[drive])
ddidbitsleft--;
if (!ddidbitsleft && !readdatapoll)
{
// printf("ID bits over %04X %02X %i\n",fdibuffer[drive],decodefm(fdibuffer[drive]),fdipos[drive]);
if (decodefm(fdi_buffer[drive]) == 0xFE)
// printf("ID bits over %04X %02X %i\n",fdibuffer,decodefm(fdibuffer),fdipos);
if (decodefm(fdi_buffer) == 0xFE)
{
// printf("Sector header %i %i\n", fdi_inread[drive], fdi_inreadaddr[drive]);
pollbytesleft[drive] = 6;
pollbitsleft[drive] = 16;
readidpoll[drive] = 1;
// printf("Sector header %i %i\n", fdi_inread, fdi_inreadaddr);
pollbytesleft = 6;
pollbitsleft = 16;
readidpoll = 1;
}
else if (decodefm(fdi_buffer[drive]) == 0xFB)
else if (decodefm(fdi_buffer) == 0xFB)
{
// printf("Data header %i %i\n", fdi_inread[drive], fdi_inreadaddr[drive]);
if (fdi_nextsector[drive])
// printf("Data header %i %i\n", fdi_inread, fdi_inreadaddr);
if (fdi_nextsector)
{
pollbytesleft[drive] = sectorsize[drive];
pollbitsleft[drive] = 16;
readdatapoll[drive] = 1;
fdi_nextsector[drive] = 0;
crc[drive] = 0xcdb4;
if (fdi_buffer[drive] == 0xF56A) calccrc(drive, 0xF8);
else calccrc(drive, 0xFB);
lastfdidat[drive][0] = lastfdidat[drive][1] = 0;
pollbytesleft = sectorsize;
pollbitsleft = 16;
readdatapoll = 1;
fdi_nextsector = 0;
crc = 0xcdb4;
if (fdi_buffer == 0xF56A) calccrc(0xF8);
else calccrc(0xFB);
lastfdidat[0] = lastfdidat[1] = 0;
}
}
}

View File

@@ -8,6 +8,6 @@ void fdi_readaddress(int drive, int sector, int side, int density);
void fdi_format(int drive, int sector, int side, int density, uint8_t fill);
int fdi_hole(int drive);
int fdi_byteperiod(int drive);
void fdi_stop(int drive);
int fdi_poll(int drive);
void fdi_stop();
void fdi_poll();
int fdi_realtrack(int track, int drive);

View File

@@ -306,6 +306,52 @@ void img_load(int drive, char *fn)
else if (size <= 2000000) { img[drive].sectors = 21; img[drive].tracks = 80; bit_rate_300 = 500; raw_tsize[drive] = 12500; } /*DMF format - used by Windows 95 - changed by OBattler to 2000000, ie. the real unformatted capacity @ 500 kbps and 300 rpm */
else if (size <= 2949120) { img[drive].sectors = 36; img[drive].tracks = 80; bit_rate_300 = 1000; raw_tsize[drive] = 25000; } /*E density*/
temp_rate = 2;
bpb_bps = img[drive].sector_size;
bpt = bpb_bps * img[drive].sectors;
if (bpt <= (maximum_sectors[sector_size_code(bpb_bps)][0] * bpb_bps))
{
temp_rate = 2;
raw_tsize[drive] = 5208;
}
else if (bpt <= (maximum_sectors[sector_size_code(bpb_bps)][1] * bpb_bps))
{
temp_rate = 2;
raw_tsize[drive] = 6250;
}
else if (bpt <= (maximum_sectors[sector_size_code(bpb_bps)][2] * bpb_bps))
{
temp_rate = 1;
raw_tsize[drive] = 7500;
}
else if (bpt <= (maximum_sectors[sector_size_code(bpb_bps)][3] * bpb_bps))
{
if (bpb_bps == 512) max_spt = (bit_rate_300 == 500) ? 21 : 17;
temp_rate = (bit_rate_300 == 500) ? 0 : 4;
raw_tsize[drive] = (bit_rate_300 == 500) ? 12500 : 10416;
}
else if (bpt <= (maximum_sectors[sector_size_code(bpb_bps)][4] * bpb_bps))
{
if (bpb_bps == 512) max_spt = 21;
pclog("max_spt is %i\n", max_spt);
temp_rate = 0;
raw_tsize[drive] = 12500;
}
else if (bpt <= (maximum_sectors[sector_size_code(bpb_bps)][5] * bpb_bps))
{
if (bpb_bps == 512) max_spt = 41;
temp_rate = 3;
raw_tsize[drive] = 25000;
}
else /* Image too big, eject */
{
pclog("Image is bigger than can fit on an ED floppy, ejecting...\n");
fclose(img[drive].f);
return;
}
pclog("Temporary rate: %i (%i bytes per track)\n", temp_rate, bpt);
img[drive].xdf_type = 0;
}
else
@@ -432,7 +478,7 @@ void img_load(int drive, char *fn)
gap3_size[drive] = 40;
pclog("WARNING: Floppy image of unknown format was inserted into drive %c:!\n", drive + 0x41);
}
gap4_size[drive] = raw_tsize[drive] - (((pre_gap + gap2_size[drive] + pre_data + data_size + post_gap + gap3_size[drive]) * img[drive].sectors) + pre_track);
gap4_size[drive] = raw_tsize[drive] - (((pre_gap + gap2_size[drive] + pre_data + img[drive].sector_size + post_gap + gap3_size[drive]) * img[drive].sectors) + pre_track);
pclog("GAP4 size: %i bytes\n", gap4_size[drive]);
if (img[drive].xdf_type)
{

View File

@@ -35,12 +35,10 @@ enum
STATE_FORMAT
};
static int processed_bytes[2] = {0, 0};
static int disc_sector_state[2] = {0, 0};
static int disc_sector_track[2] = {0, 0};
static int disc_sector_side[2] = {0, 0};
// static int disc_sector_drive[2] = {0, 0};
static int disc_sector_drive;
static int disc_sector_sector[2] = {0, 0};
static int disc_sector_n[2] = {0, 0};
static int disc_intersector_delay[2] = {0, 0};
@@ -50,13 +48,7 @@ static int disc_gap4_delay[2] = {0, 0};
static uint8_t disc_sector_fill[2] = {0, 0};
static int cur_sector[2], cur_byte[2];
static int index_count[2];
int gap2 = length_gap2;
int gap3 = length_gap3;
int gap3_0 = length_gap3_0;
int gap4 = raw_track_size - (((pre_gap + length_gap2 + pre_data + data_size + post_gap + length_gap3) * no_sectors) + pre_track);
int gap4_0 = raw_track_size_0 - (((pre_gap + length_gap2 + pre_data + data_size + post_gap + length_gap3_0) * no_sectors_0) + pre_track);
int raw_tsize[2] = {6250, 6250};
int gap2_size[2] = {22, 22};
int gap3_size[2] = {0, 0};
@@ -99,8 +91,7 @@ static int get_bitcell_period(int drive)
void disc_sector_readsector(int drive, int sector, int track, int side, int rate, int sector_size)
{
pclog("disc_sector_readsector: fdc_period=%i img_period=%i rate=%i sector=%i track=%i side=%i\n", fdc_get_bitcell_period(), get_bitcell_period(drive), rate, sector, track, side);
pclog("pre_track=%i, pre_sector=%i, gap4=%i\n", pre_track, post_gap + gap3 + pre_gap + gap2 + pre_data, gap4);
// pclog("disc_sector_readsector: fdc_period=%i img_period=%i rate=%i sector=%i track=%i side=%i\n", fdc_get_bitcell_period(), get_bitcell_period(), rate, sector, track, side);
if (sector == SECTOR_FIRST)
disc_sector_state[drive] = STATE_READ_FIND_FIRST_SECTOR;
@@ -110,38 +101,35 @@ void disc_sector_readsector(int drive, int sector, int track, int side, int rate
disc_sector_state[drive] = STATE_READ_FIND_SECTOR;
disc_sector_track[drive] = track;
disc_sector_side[drive] = side;
// disc_sector_drive = drive;
disc_sector_drive = drive;
disc_sector_sector[drive] = sector;
disc_sector_n[drive] = sector_size;
if ((cur_sector[drive] == 0) && (cur_byte[drive] == 0) && !disc_track_delay[drive]) disc_track_delay[drive] = pre_track;
index_count[drive] = 0;
processed_bytes[drive] = 0;
// pclog("Disk poll time is: %i\n", disc_poll_time);
}
void disc_sector_writesector(int drive, int sector, int track, int side, int rate, int sector_size)
{
pclog("disc_sector_writesector: fdc_period=%i img_period=%i rate=%i\n", fdc_get_bitcell_period(), get_bitcell_period(drive), rate);
// pclog("disc_sector_writesector: fdc_period=%i img_period=%i rate=%i\n", fdc_get_bitcell_period(), get_bitcell_period(), rate);
disc_sector_state[drive] = STATE_WRITE_FIND_SECTOR;
disc_sector_track[drive] = track;
disc_sector_side[drive] = side;
// disc_sector_drive = drive;
disc_sector_drive = drive;
disc_sector_sector[drive] = sector;
disc_sector_n[drive] = sector_size;
if ((cur_sector[drive] == 0) && (cur_byte[drive] == 0) && !disc_track_delay[drive]) disc_track_delay[drive] = pre_track;
index_count[drive] = 0;
processed_bytes[drive] = 0;
}
void disc_sector_readaddress(int drive, int track, int side, int rate)
{
pclog("disc_sector_readaddress: fdc_period=%i img_period=%i rate=%i track=%i side=%i\n", fdc_get_bitcell_period(), get_bitcell_period(drive), rate, track, side);
// pclog("disc_sector_readaddress: fdc_period=%i img_period=%i rate=%i track=%i side=%i\n", fdc_get_bitcell_period(), get_bitcell_period(), rate, track, side);
disc_sector_state[drive] = STATE_READ_FIND_ADDRESS;
disc_sector_track[drive] = track;
disc_sector_side[drive] = side;
// disc_sector_drive = drive;
disc_sector_drive = drive;
if ((cur_sector[drive] == 0) && (cur_byte[drive] == 0) && !disc_track_delay[drive])
{
disc_track_delay[drive] = pre_track;
@@ -149,8 +137,6 @@ void disc_sector_readaddress(int drive, int track, int side, int rate)
}
else
index_count[drive] = 0;
processed_bytes[drive] = 0;
}
void disc_sector_format(int drive, int track, int side, int rate, uint8_t fill)
@@ -158,7 +144,7 @@ void disc_sector_format(int drive, int track, int side, int rate, uint8_t fill)
disc_sector_state[drive] = STATE_FORMAT_FIND;
disc_sector_track[drive] = track;
disc_sector_side[drive] = side;
// disc_sector_drive = drive;
disc_sector_drive = drive;
disc_sector_fill[drive] = fill;
index_count[drive] = 0;
}
@@ -168,49 +154,295 @@ void disc_sector_stop(int drive)
disc_sector_state[drive] = STATE_IDLE;
}
#if 0
static void advance_byte()
{
if (disc_intersector_delay)
{
disc_intersector_delay--;
return;
}
cur_byte++;
if (cur_byte >= (128 << disc_sector_data[disc_sector_drive][disc_sector_side][cur_sector].n))
{
cur_byte = 0;
cur_sector++;
if (cur_sector >= disc_sector_count[disc_sector_drive][disc_sector_side])
{
cur_sector = 0;
fdc_indexpulse();
index_count++;
}
disc_intersector_delay = 40;
}
}
void disc_sector_poll()
{
sector_t *s;
int data;
if (cur_sector >= disc_sector_count[disc_sector_drive][disc_sector_side])
cur_sector = 0;
if (cur_byte >= (128 << disc_sector_data[disc_sector_drive][disc_sector_side][cur_sector].n))
cur_byte = 0;
s = &disc_sector_data[disc_sector_drive][disc_sector_side][cur_sector];
switch (disc_sector_state)
{
case STATE_IDLE:
break;
case STATE_READ_FIND_SECTOR:
/* pclog("STATE_READ_FIND_SECTOR: cur_sector=%i cur_byte=%i sector=%i,%i side=%i,%i track=%i,%i period=%i,%i\n",
cur_sector, cur_byte,
disc_sector_sector, s->r,
disc_sector_side, s->h,
disc_sector_track, s->c,
fdc_get_bitcell_period(), get_bitcell_period());*/
if (index_count > 1)
{
// pclog("Find sector not found\n");
fdc_notfound();
disc_sector_state = STATE_IDLE;
break;
}
/* pclog("%i %i %i %i %i\n", cur_byte, disc_sector_track != s->c,
disc_sector_side != s->h,
disc_sector_sector != s->r,
fdc_get_bitcell_period() != get_bitcell_period());*/
if (cur_byte || disc_sector_track != s->c ||
disc_sector_side != s->h ||
disc_sector_sector != s->r ||
disc_sector_n != s->n ||
fdc_get_bitcell_period() != get_bitcell_period() ||
!fdd_can_read_medium(disc_sector_drive ^ fdd_swap) ||
disc_intersector_delay)
{
advance_byte();
break;
}
disc_sector_state = STATE_READ_SECTOR;
case STATE_READ_SECTOR:
// pclog("STATE_READ_SECTOR: cur_byte=%i %i\n", cur_byte, disc_intersector_delay);
if (fdc_data(s->data[cur_byte]))
{
// pclog("fdc_data failed\n");
return;
}
advance_byte();
if (!cur_byte)
{
disc_sector_state = STATE_IDLE;
fdc_finishread();
}
break;
case STATE_READ_FIND_FIRST_SECTOR:
if (!(fdd_can_read_medium(disc_sector_drive ^ fdd_swap)))
{
// pclog("Medium is of a density not supported by the drive\n");
fdc_notfound();
disc_sector_state = STATE_IDLE;
break;
}
if (cur_byte || !index_count || fdc_get_bitcell_period() != get_bitcell_period() ||
disc_intersector_delay)
{
advance_byte();
break;
}
disc_sector_state = STATE_READ_FIRST_SECTOR;
case STATE_READ_FIRST_SECTOR:
if (fdc_data(s->data[cur_byte]))
return;
advance_byte();
if (!cur_byte)
{
disc_sector_state = STATE_IDLE;
fdc_finishread();
}
break;
case STATE_READ_FIND_NEXT_SECTOR:
if (!(fdd_can_read_medium(disc_sector_drive ^ fdd_swap)))
{
// pclog("Medium is of a density not supported by the drive\n");
fdc_notfound();
disc_sector_state = STATE_IDLE;
break;
}
if (index_count)
{
// pclog("Find next sector hit end of track\n");
fdc_notfound();
disc_sector_state = STATE_IDLE;
break;
}
if (cur_byte || fdc_get_bitcell_period() != get_bitcell_period() ||
disc_intersector_delay)
{
advance_byte();
break;
}
disc_sector_state = STATE_READ_NEXT_SECTOR;
case STATE_READ_NEXT_SECTOR:
if (fdc_data(s->data[cur_byte]))
break;
advance_byte();
if (!cur_byte)
{
disc_sector_state = STATE_IDLE;
fdc_finishread();
}
break;
case STATE_WRITE_FIND_SECTOR:
if (!(fdd_can_read_medium(disc_sector_drive ^ fdd_swap)))
{
// pclog("Medium is of a density not supported by the drive\n");
fdc_notfound();
disc_sector_state = STATE_IDLE;
break;
}
if (writeprot[disc_sector_drive])
{
fdc_writeprotect();
return;
}
if (index_count > 1)
{
// pclog("Write find sector not found\n");
fdc_notfound();
disc_sector_state = STATE_IDLE;
break;
}
if (cur_byte || disc_sector_track != s->c ||
disc_sector_side != s->h ||
disc_sector_sector != s->r ||
disc_sector_n != s->n ||
fdc_get_bitcell_period() != get_bitcell_period() ||
disc_intersector_delay)
{
advance_byte();
break;
}
disc_sector_state = STATE_WRITE_SECTOR;
case STATE_WRITE_SECTOR:
data = fdc_getdata(cur_byte == ((128 << s->n) - 1));
if (data == -1)
break;
s->data[cur_byte] = data;
advance_byte();
if (!cur_byte)
{
disc_sector_state = STATE_IDLE;
disc_sector_writeback[disc_sector_drive](disc_sector_drive, disc_sector_track);
fdc_finishread();
}
break;
case STATE_READ_FIND_ADDRESS:
if (!(fdd_can_read_medium(disc_sector_drive ^ fdd_swap)))
{
// pclog("Medium is of a density not supported by the drive\n");
fdc_notfound();
disc_sector_state = STATE_IDLE;
break;
}
if (index_count)
{
// pclog("Find next sector hit end of track\n");
fdc_notfound();
disc_sector_state = STATE_IDLE;
break;
}
if (cur_byte || fdc_get_bitcell_period() != get_bitcell_period() ||
disc_intersector_delay)
{
advance_byte();
break;
}
disc_sector_state = STATE_READ_ADDRESS;
case STATE_READ_ADDRESS:
fdc_sectorid(s->c, s->h, s->r, s->n, 0, 0);
disc_sector_state = STATE_IDLE;
break;
case STATE_FORMAT_FIND:
if (writeprot[disc_sector_drive])
{
fdc_writeprotect();
return;
}
if (!index_count || fdc_get_bitcell_period() != get_bitcell_period() ||
disc_intersector_delay)
{
advance_byte();
break;
}
if (!(fdd_can_read_medium(disc_sector_drive ^ fdd_swap)))
{
// pclog("Medium is of a density not supported by the drive\n");
fdc_notfound();
disc_sector_state = STATE_IDLE;
break;
}
if (fdc_get_bitcell_period() != get_bitcell_period())
{
fdc_notfound();
disc_sector_state = STATE_IDLE;
break;
}
disc_sector_state = STATE_FORMAT;
case STATE_FORMAT:
if (!disc_intersector_delay && fdc_get_bitcell_period() == get_bitcell_period())
s->data[cur_byte] = disc_sector_fill;
advance_byte();
if (index_count == 2)
{
disc_sector_writeback[disc_sector_drive](disc_sector_drive, disc_sector_track);
fdc_finishread();
disc_sector_state = STATE_IDLE;
}
break;
}
}
#endif
static void index_pulse(int drive)
{
if (disc_sector_state[drive] != STATE_IDLE) fdc_indexpulse();
}
static int advance_byte(int drive)
static void advance_byte()
{
/* 0 = regular byte, 1 = missing clock pulse */
int type = 0;
int drive = disc_sector_drive;
processed_bytes[drive]++;
// pclog("advance_byte(%i): %i\n", drive, processed_bytes[drive]);
if (disc_postdata_delay[drive])
{
disc_postdata_delay[drive]--;
return type;
return;
}
if (disc_gap4_delay[drive])
{
disc_gap4_delay[drive]--;
return type;
return;
}
if (disc_track_delay[drive])
{
if ((disc_track_delay[drive] >= (pre_track - 92)) && (disc_track_delay[drive] <= (pre_track - 94))) type = 1;
if (disc_track_delay[drive] == pre_track)
{
// pclog("Track index pulse!\n");
index_pulse(drive);
index_count[drive]++;
}
disc_track_delay[drive]--;
if (type) pclog("advance_byte(): Track sync\n");
return type;
return;
}
if (disc_intersector_delay[drive])
{
if ((disc_intersector_delay[drive] >= (pre_gap + gap2_size[drive] + pre_data - 12)) && (disc_intersector_delay[drive] <= (pre_gap + gap2_size[drive] + pre_data - 14))) type = 1;
if ((disc_intersector_delay[drive] >= (pre_gap + gap2_size[drive] + pre_data - 56)) && (disc_intersector_delay[drive] <= (pre_gap + gap2_size[drive] + pre_data - 58))) type = 2;
disc_intersector_delay[drive]--;
if (type == 1) pclog("advance_byte(): Sector address sync\n");
if (type == 2) pclog("advance_byte(): Sector sync\n");
return type;
return;
}
cur_byte[drive]++;
if (cur_byte[drive] >= (128 << disc_sector_data[drive][disc_sector_side[drive]][cur_sector[drive]].n))
@@ -232,22 +464,14 @@ static int advance_byte(int drive)
disc_intersector_delay[drive] = pre_gap + gap2_size[drive] + pre_data;
}
}
return type;
return;
}
int head_byte(int drive, int h)
{
return (fdd_get_head(drive) << 2) | h;
}
int disc_sector_poll(int drive)
void disc_sector_poll()
{
sector_t *s;
int data;
int do_period = 0;
int sector_type = 0;
int drive = disc_sector_drive;
if (cur_sector[drive] >= disc_sector_count[drive][disc_sector_side[drive]])
cur_sector[drive] = 0;
@@ -257,70 +481,42 @@ int disc_sector_poll(int drive)
/* Note: Side to read from should be chosen from FDC head select rather than from the sector ID. */
s = &disc_sector_data[drive][disc_sector_side[drive]][cur_sector[drive]];
if (fdd_stepping_motor_on[drive])
{
/* If stepping motor is on, turn off data separator. */
sector_type = advance_byte(drive);
do_period = 1;
do_period = do_period ? ((sector_type > 0) ? 2 : 1) : 0;
return do_period;
}
switch (disc_sector_state[drive])
{
case STATE_IDLE:
sector_type = advance_byte(drive);
do_period = 1;
advance_byte();
break;
case STATE_READ_FIND_SECTOR:
/* pclog("STATE_READ_FIND_SECTOR: cur_sector=%i cur_byte=%i sector=%i,%i side=%i,%i track=%i,%i period=%i,%i\n",
cur_sector[drive], cur_byte[drive],
disc_sector_sector[drive], s->r,
disc_sector_side[drive], s->h,
disc_sector_track[drive], s->c,
fdc_get_bitcell_period(), get_bitcell_period(drive));*/
if (index_count[drive] > 1)
{
// pclog("Find sector not found\n");
pclog("READ: Sector (%i %i %i %i) not found (last: %i %i %i) (period=%i,%i)\n", s->c, s->h, s->r, s->n, disc_sector_track, disc_sector_side, disc_sector_sector, fdc_get_bitcell_period(), get_bitcell_period(drive));
fdc_notfound();
disc_sector_state[drive] = STATE_IDLE;
break;
}
/* pclog("%i %i %i %i %i\n", cur_byte[drive], disc_sector_track[drive] != s->c,
disc_sector_side[drive] != s->h,
disc_sector_sector[drive] != s->r,
fdc_get_bitcell_period() != get_bitcell_period(drive));*/
if (cur_byte[drive] || disc_sector_track[drive] != s->c ||
disc_sector_side[drive] != s->h ||
disc_sector_sector[drive] != s->r ||
disc_sector_n[drive] != s->n ||
(fdc_get_bitcell_period() != get_bitcell_period(drive)) ||
!fdd_can_read_medium(drive ^ fdd_swap) ||
disc_intersector_delay[drive] || disc_track_delay[drive])
disc_sector_side[drive] != s->h ||
disc_sector_sector[drive] != s->r ||
disc_sector_n[drive] != s->n ||
(fdc_get_bitcell_period() != get_bitcell_period(drive)) ||
!fdd_can_read_medium(drive ^ fdd_swap) ||
disc_intersector_delay[drive] || disc_track_delay[drive])
{
// pclog("Poll: Find sector advance byte!\n");
sector_type = advance_byte(drive);
do_period = 1;
advance_byte();
break;
}
disc_sector_state[drive] = STATE_READ_SECTOR;
case STATE_READ_SECTOR:
// pclog("STATE_READ_SECTOR: cur_byte=%i %i\n", cur_byte[drive], disc_intersector_delay[drive]);
if (fdc_data(s->data[cur_byte[drive]]))
{
// pclog("fdc_data failed\n");
return 0;
return;
}
sector_type = advance_byte(drive);
do_period = 1;
advance_byte();
if (!cur_byte[drive])
{
disc_sector_state[drive] = STATE_IDLE;
pclog("Processed bytes: %i, byte pulses: %i\n", processed_bytes[drive], bpulses[drive]);
// pclog("Disk poll time is: %i\n", disc_poll_time);
fdc_finishread(drive);
}
break;
@@ -328,30 +524,25 @@ int disc_sector_poll(int drive)
case STATE_READ_FIND_FIRST_SECTOR:
if (!fdd_can_read_medium(drive ^ fdd_swap))
{
pclog("Medium is of a density not supported by the drive\n");
fdc_notfound();
disc_sector_state[drive] = STATE_IDLE;
break;
}
if (cur_byte[drive] || !index_count[drive] || fdc_get_bitcell_period() != get_bitcell_period(drive) ||
disc_intersector_delay[drive] || disc_track_delay[drive])
disc_intersector_delay[drive] || disc_track_delay[drive])
{
// pclog("Poll: Find sector advance byte!\n");
sector_type = advance_byte(drive);
do_period = 1;
advance_byte();
break;
}
disc_sector_state[drive] = STATE_READ_FIRST_SECTOR;
case STATE_READ_FIRST_SECTOR:
if (fdc_data(s->data[cur_byte[drive]]))
return 0;
sector_type = advance_byte(drive);
do_period = 1;
return;
advance_byte();
if (!cur_byte[drive])
{
disc_sector_state[drive] = STATE_IDLE;
pclog("Processed bytes: %i, byte pulses: %i\n", processed_bytes[drive], bpulses[drive]);
// pclog("Disk poll time is: %i\n", disc_poll_time);
fdc_finishread(drive);
}
break;
@@ -359,14 +550,12 @@ int disc_sector_poll(int drive)
case STATE_READ_FIND_NEXT_SECTOR:
if (!fdd_can_read_medium(drive ^ fdd_swap))
{
pclog("Medium is of a density not supported by the drive\n");
fdc_notfound();
disc_sector_state[drive] = STATE_IDLE;
break;
}
if (index_count[drive] > 0)
{
pclog("Find next sector hit end of track\n");
fdc_notfound();
disc_sector_state[drive] = STATE_IDLE;
break;
@@ -374,22 +563,18 @@ int disc_sector_poll(int drive)
if (cur_byte[drive] || (fdc_get_bitcell_period() != get_bitcell_period(drive)) ||
disc_intersector_delay[drive] || disc_track_delay[drive])
{
// pclog("Poll: Find sector advance byte!\n");
sector_type = advance_byte(drive);
do_period = 1;
advance_byte();
break;
}
disc_sector_state[drive] = STATE_READ_NEXT_SECTOR;
case STATE_READ_NEXT_SECTOR:
if (fdc_data(s->data[cur_byte[drive]]))
break;
sector_type = advance_byte(drive);
do_period = 1;
advance_byte();
if (!cur_byte[drive])
{
disc_sector_state[drive] = STATE_IDLE;
pclog("Processed bytes: %i, byte pulses: %i\n", processed_bytes[drive], bpulses[drive]);
// pclog("Disk poll time is: %i\n", disc_poll_time);
fdc_finishread(drive);
}
break;
@@ -397,7 +582,6 @@ int disc_sector_poll(int drive)
case STATE_WRITE_FIND_SECTOR:
if (!fdd_can_read_medium(drive ^ fdd_swap))
{
// pclog("Medium is of a density not supported by the drive\n");
fdc_notfound();
disc_sector_state[drive] = STATE_IDLE;
break;
@@ -405,12 +589,9 @@ int disc_sector_poll(int drive)
if (writeprot[drive] || swwp)
{
fdc_writeprotect();
return 0;
}
if (index_count[drive] > 1)
{
// pclog("Write find sector not found\n");
pclog("WRITE: Sector (%i %i %i %i) not found\n", s->c, s->h, s->r, s->n);
fdc_notfound();
disc_sector_state[drive] = STATE_IDLE;
break;
@@ -422,25 +603,21 @@ int disc_sector_poll(int drive)
(fdc_get_bitcell_period() != get_bitcell_period(drive)) ||
disc_intersector_delay[drive] || disc_track_delay[drive])
{
// pclog("Poll: Find sector advance byte!\n");
sector_type = advance_byte(drive);
do_period = 1;
advance_byte();
break;
}
disc_sector_state[drive] = STATE_WRITE_SECTOR;
case STATE_WRITE_SECTOR:
data = fdc_getdata(cur_byte[drive] == ((128 << s->n) - 1));
if (data == -1)
break;
if (!disable_write) s->data[cur_byte[drive]] = data;
sector_type = advance_byte(drive);
do_period = 1;
advance_byte();
if (!cur_byte[drive])
{
disc_sector_state[drive] = STATE_IDLE;
if (!disable_write) disc_sector_writeback[drive](drive, disc_sector_track[drive]);
pclog("Processed bytes: %i, byte pulses: %i\n", processed_bytes[drive], bpulses[drive]);
// pclog("Disk poll time is: %i\n", disc_poll_time);
fdc_finishread(drive);
}
break;
@@ -448,24 +625,20 @@ int disc_sector_poll(int drive)
case STATE_READ_FIND_ADDRESS:
if (!fdd_can_read_medium(drive ^ fdd_swap))
{
pclog("Medium is of a density not supported by the drive\n");
fdc_notfound();
disc_sector_state[drive] = STATE_IDLE;
break;
}
if (index_count[drive] > 0)
{
pclog("Find next sector hit end of track\n");
fdc_notfound();
disc_sector_state[drive] = STATE_IDLE;
break;
}
if (cur_byte[drive] || (fdc_get_bitcell_period() != get_bitcell_period(drive)) ||
disc_intersector_delay[drive] || disc_track_delay[drive])
disc_intersector_delay[drive] || disc_track_delay[drive])
{
// pclog("Poll: Find sector advance byte!\n");
sector_type = advance_byte(drive);
do_period = 1;
advance_byte();
break;
}
disc_sector_state[drive] = STATE_READ_ADDRESS;
@@ -478,48 +651,37 @@ int disc_sector_poll(int drive)
if (writeprot[drive] || swwp)
{
fdc_writeprotect();
return 0;
}
if (!index_count[drive] || (fdc_get_bitcell_period() != get_bitcell_period(drive)) ||
disc_intersector_delay[drive] || disc_track_delay[drive])
disc_intersector_delay[drive] || disc_track_delay[drive])
{
sector_type = advance_byte(drive);
do_period = 1;
advance_byte();
break;
}
if (!(fdd_can_read_medium(drive ^ fdd_swap)))
{
pclog("Medium is of a density not supported by the drive\n");
fdc_notfound();
disc_sector_state[drive] = STATE_IDLE;
break;
}
if (fdc_get_bitcell_period() != get_bitcell_period(drive))
{
pclog("Bitcell period mismatch\n");
fdc_notfound();
disc_sector_state[drive] = STATE_IDLE;
break;
}
disc_sector_state[drive] = STATE_FORMAT;
case STATE_FORMAT:
if (!disc_intersector_delay[drive] && fdc_get_bitcell_period() == get_bitcell_period(drive) && !disable_write)
s->data[cur_byte[drive]] = disc_sector_fill[drive];
sector_type = advance_byte(drive);
do_period = 1;
advance_byte();
if (index_count[drive] == 2)
{
if (!disable_write) disc_sector_writeback[drive](drive, disc_sector_track[drive]);
pclog("Processed bytes: %i, byte pulses: %i\n", processed_bytes[drive], bpulses[drive]);
// pclog("Disk poll time is: %i\n", disc_poll_time);
fdc_finishread(drive);
disc_sector_state[drive] = STATE_IDLE;
}
break;
}
// if (do_period) pclog("disc_sector_poll(%i) = %i\n", drive, sector_type);
do_period = do_period ? ((sector_type > 0) ? 2 : 1) : 0;
return do_period;
}
}

View File

@@ -4,22 +4,17 @@ void disc_sector_readsector(int drive, int sector, int track, int side, int dens
void disc_sector_writesector(int drive, int sector, int track, int side, int density, int sector_size);
void disc_sector_readaddress(int drive, int sector, int side, int density);
void disc_sector_format(int drive, int sector, int side, int density, uint8_t fill);
void disc_sector_stop(int drive);
int disc_sector_poll(int drive);
void disc_sector_stop(int drive);
void disc_sector_stop();
void disc_sector_poll();
void disc_sector_stop();
extern void (*disc_sector_writeback[2])(int drive, int track);
#define length_gap0 80
#define length_gap1 50
#define length_sync 12
#define length_am 4
#define length_crc 2
#define length_gap2 22
#define length_gap3 84 // 88
#define length_gap3_0 108
#define no_sectors 15 // 8
#define no_sectors_0 18
#define raw_track_size 10416 // 6250
#define raw_track_size_0 12500
#define IBM
#define MFM
@@ -30,14 +25,11 @@ void disc_sector_stop(int drive);
#endif
#define pre_track pre_gap1 + length_gap1
#define pre_gap length_sync + length_am + 4 + length_crc // 22
#define pre_data length_sync + length_am // 16
#define data_size 512
#define pre_gap length_sync + length_am + 4 + length_crc
#define pre_data length_sync + length_am
#define post_gap length_crc
extern int raw_tsize[2];
extern int gap2_size[2];
extern int gap3_size[2];
extern int gap4_size[2];
extern void (*disc_sector_writeback[2])(int drive, int track);

298
src/fdc.c
View File

@@ -11,8 +11,6 @@
extern int motoron;
extern int motor_on[2] = {0, 0};
static int fdc_reset_stat = 0;
/*FDC*/
typedef struct FDC
@@ -38,7 +36,7 @@ typedef struct FDC
int pcjr, ps1;
int watchdog_timer;
int64_t watchdog_timer;
int watchdog_count;
int data_ready;
@@ -67,8 +65,6 @@ typedef struct FDC
int seek_params; /* Needed for relative seek. */
} FDC;
int skip_pulses[2] = {0, 0};
static FDC fdc;
void fdc_callback();
@@ -81,12 +77,6 @@ int discmodified[2];
int discrate[2];
int discint;
#define FDC_STATE_NORMAL 0
#define FDC_STATE_SEEK 1
int fdc_state = 0;
void fdc_reset()
{
fdc.stat=0x80;
@@ -95,31 +85,15 @@ void fdc_reset()
fdc.lock = 0;
fdc.head = 0;
fdc.abort = 0;
fdc_set_skip_pulses(0, 0);
fdc_set_skip_pulses(1, 0);
fdd_stepping_motor_on[0] = fdd_stepping_motor_on[1] = 0;
fdd_track_diff[0] = fdd_track_diff[1] = 0;
if (!AT)
{
fdc.rate = 2;
// fdc_update_rate();
}
fdc_state = FDC_STATE_NORMAL;
// pclog("Reset FDC\n");
}
int ins;
void fdc_set_skip_pulses(int drive, int val)
{
skip_pulses[drive] = val;
pclog("Skip pulses for drive %c: is now %i\n", 0x41 + drive, val);
}
int fdc_skip_pulses(int drive)
{
return (skip_pulses[drive] ? 1 : 0) || (discint < 0);
}
void fdc_reset_fifo_buf()
{
int i = 0;
@@ -167,7 +141,6 @@ void fdc_fifo_buf_dummy()
static void fdc_int()
{
pclog("FDC interrupt issued\n");
if (!fdc.pcjr)
picint(1 << 6);
}
@@ -289,7 +262,7 @@ void fdc_update_rate(int drive)
}
fdc.bitcell_period = 1000000 / bit_rate*2; /*Bitcell period in ns*/
pclog("fdc_update_rate: rate=%i bit_rate=%i bitcell_period=%i\n", fdc.rate, bit_rate, fdc.bitcell_period);
// pclog("fdc_update_rate: rate=%i bit_rate=%i bitcell_period=%i\n", fdc.rate, bit_rate, fdc.bitcell_period);
}
int fdc_get_bitcell_period()
@@ -345,15 +318,12 @@ static void fdc_rate(int drive)
fdc_update_rate(drive);
disc_set_rate(drive, fdc.drvrate[drive], fdc.rate);
fdd_set_densel(fdc_get_densel(drive));
// pclog("Drive %i: enh. %i, rate %i, DENSEL %i, RWC %i, drvrate %i, densel polarity %i, NSC %i, densel force %i\n", drive, fdc.enh_mode, fdc.rate, fdc_get_densel(drive), fdc_get_rwc(drive), fdc.drvrate[drive], fdc.densel_polarity, fdc.is_nsc, fdc.densel_force);
}
void fdc_seek(int drive, int params)
{
fdd_seek(drive, params);
fdc.stat |= (1 << fdc.drive);
// fdc_state = FDC_STATE_SEEK;
pclog("FDC seek issued\n");
}
void fdc_write(uint16_t addr, uint8_t val, void *priv)
@@ -361,7 +331,6 @@ void fdc_write(uint16_t addr, uint8_t val, void *priv)
// pclog("Write FDC %04X %02X %04X:%04X %i %02X %i rate=%i %i\n",addr,val,cs>>4,pc,ins,fdc.st0,ins,fdc.rate, fdc.data_ready);
int drive;
// pclog("fdc_write: %04X: %02X\n", addr, val);
switch (addr&7)
{
case 1: return;
@@ -385,9 +354,9 @@ void fdc_write(uint16_t addr, uint8_t val, void *priv)
discint=-1;
fdc_reset();
}
motor_on[0] = val & 0x01;
motoron = val & 0x01;
fdc.drive = 0;
/* if (motor_on[0])
/* if (motoron)
output = 3;
else
output = 0;*/
@@ -408,38 +377,9 @@ void fdc_write(uint16_t addr, uint8_t val, void *priv)
fdc_reset();
}
timer_process();
fdc.drive = val & 3;
val &= 0x3F;
/* if (fdc.drive > 2)
{
motor_on = 0;
} */
if (fdc.drive == 1)
{
if ((!fdc.drv2en) || (fdd_get_type(1) == 0))
{
motor_on[1] = 0;
val &= 0xDF;
}
else
{
motor_on[1] = val & 0x20;
}
}
else if (fdc.drive == 0)
{
if (fdd_get_type(0) == 0)
{
motor_on[0] = 0;
val &= 0xEF;
}
else
{
motor_on[0] = val & 0x10;
}
}
fdc_set_skip_pulses(fdc.drive, 0);
motoron = (val & 0xf0) ? 1 : 0;
timer_update_outstanding();
fdc.drive = val & 3;
}
fdc.dor=val;
// printf("DOR now %02X\n",val);
@@ -484,7 +424,7 @@ void fdc_write(uint16_t addr, uint8_t val, void *priv)
{
fdc.tc = 0;
fdc.data_ready = 0;
fdc.command=val;
// pclog("Starting FDC command %02X\n",fdc.command);
switch (fdc.command&0x1F)
@@ -559,7 +499,6 @@ void fdc_write(uint16_t addr, uint8_t val, void *priv)
fdc.pnum=0;
fdc.ptot=2;
fdc.stat=0x90;
fdc.seek_params = val & 0xC0;
break;
case 0x0e: /*Dump registers*/
fdc.lastdrive = fdc.drive;
@@ -635,14 +574,11 @@ bad_command:
switch (discint)
{
case 2: /*Read a track*/
fdc_set_skip_pulses(fdc.drive ^ fdd_swap, 1);
fdc_rate(fdc.drive);
fdc.head=fdc.params[2];
fdd_set_head(fdc.drive, (fdc.params[0] & 4) ? 1 : 0);
fdc.sector=fdc.params[3];
fdc.eot[fdc.drive] = fdc.params[5];
if (((fdc.drive ^ fdd_swap) == 1) && !fdc.drv2en)
fdc_notfound();
if (fdc.config & 0x40)
{
if (fdc.params[1] != fdc.track[fdc.drive])
@@ -651,15 +587,10 @@ bad_command:
fdc.track[fdc.drive] = fdc.params[1];
}
}
// fdc.track[fdc.drive]=fdc.params[1];
fdc.rw_track = fdc.params[1];
// pclog("Read a track track=%i head=%i sector=%i eot=%i\n", fdc.track[fdc.drive], fdc.head, fdc.sector, fdc.eot[fdc.drive]);
fdc_set_skip_pulses(fdc.drive ^ fdd_swap, 0);
if (fdc_state != FDC_STATE_SEEK)
disc_readsector(fdc.drive, SECTOR_FIRST, fdc.params[1], fdc.head, fdc.rate, fdc.params[4]);
disctime = (fdc_state == FDC_STATE_SEEK) ? (790 * TIMER_USEC) : 0;
disc_readsector(fdc.drive, SECTOR_FIRST, fdc.params[1], fdc.head, fdc.rate, fdc.params[4]);
disctime = 0;
readflash = 1;
fdc.inread = 1;
break;
@@ -672,15 +603,12 @@ bad_command:
disctime = 0;
break;
case 5: /*Write data*/
fdc_set_skip_pulses(fdc.drive ^ fdd_swap, 1);
case 5: /*Write data*/
fdc_rate(fdc.drive);
fdc.head=fdc.params[2];
fdd_set_head(fdc.drive, (fdc.params[0] & 4) ? 1 : 0);
fdc.sector=fdc.params[3];
fdc.eot[fdc.drive] = fdc.params[5];
if (((fdc.drive ^ fdd_swap) == 1) && !fdc.drv2en)
fdc_notfound();
if (fdc.config & 0x40)
{
if (fdc.params[1] != fdc.track[fdc.drive])
@@ -689,36 +617,24 @@ bad_command:
fdc.track[fdc.drive] = fdc.params[1];
}
}
// fdc.track[fdc.drive]=fdc.params[1];
fdc.rw_track = fdc.params[1];
fdc_set_skip_pulses(fdc.drive ^ fdd_swap, 0);
if (fdc_state != FDC_STATE_SEEK)
disc_writesector(fdc.drive, fdc.sector, fdc.params[1], fdc.head, fdc.rate, fdc.params[4]);
disctime = (fdc_state == FDC_STATE_SEEK) ? (790 * TIMER_USEC) : 0;
disc_writesector(fdc.drive, fdc.sector, fdc.params[1], fdc.head, fdc.rate, fdc.params[4]);
disctime = 0;
fdc.written = 0;
readflash = 1;
fdc.pos = 0;
if (fdc_state != FDC_STATE_SEEK)
{
if (fdc.pcjr)
fdc.stat = 0xb0;
}
if (fdc.pcjr)
fdc.stat = 0xb0;
// ioc_fiq(IOC_FIQ_DISC_DATA);
break;
case 6: /*Read data*/
fdc_set_skip_pulses(fdc.drive ^ fdd_swap, 1);
fdc_rate(fdc.drive);
fdc.head=fdc.params[2];
fdd_set_head(fdc.drive, (fdc.params[0] & 4) ? 1 : 0);
fdc.sector=fdc.params[3];
fdc.eot[fdc.drive] = fdc.params[5];
// pclog("FDC track is %i, requested track is %i\n", fdc.track[fdc.drive], fdc.params[1]);
if (((fdc.drive ^ fdd_swap) == 1) && !fdc.drv2en)
fdc_notfound();
if (fdc.config & 0x40)
{
if (fdc.params[1] != fdc.track[fdc.drive])
@@ -727,15 +643,10 @@ bad_command:
fdc.track[fdc.drive] = fdc.params[1];
}
}
// fdc.track[fdc.drive]=fdc.params[1];
fdc.rw_track = fdc.params[1];
fdc_set_skip_pulses(fdc.drive ^ fdd_swap, 0);
if (fdc_state != FDC_STATE_SEEK)
disc_readsector(fdc.drive, fdc.sector, fdc.params[1], fdc.head, fdc.rate, fdc.params[4]);
disctime = (fdc_state == FDC_STATE_SEEK) ? (790 * TIMER_USEC) : 0;
disc_readsector(fdc.drive, fdc.sector, fdc.params[1], fdc.head, fdc.rate, fdc.params[4]);
disctime = 0;
readflash = 1;
fdc.inread = 1;
break;
@@ -747,61 +658,48 @@ bad_command:
fdc_notfound();
else
{
// fdc_seek(fdc.drive, SEEK_RECALIBRATE);
fdc_seek(fdc.drive, -79);
}
disctime = 790 * TIMER_USEC;
break;
case 0x0d: /*Format*/
fdc_set_skip_pulses(fdc.drive ^ fdd_swap, 1);
fdc_rate(fdc.drive);
fdc.head = (fdc.params[0] & 4) ? 1 : 0;
fdc.format_state = 1;
fdc.pos = 0;
fdc.stat = 0x30;
fdc_set_skip_pulses(fdc.drive ^ fdd_swap, 0);
break;
case 0xf: /*Seek*/
fdc.stat = 1 << fdc.drive;
fdc.head = (fdc.params[0] & 4) ? 1 : 0;
disctime = 0;
if (((fdc.drive ^ fdd_swap) == 1) && !fdc.drv2en)
fdc_notfound();
else
if (fdc.seek_params & 0x80)
{
// pclog("Seeking (params=%02X, params[1]=%i)...\n", fdc.seek_params, fdc.params[1]);
if (fdc.seek_params & 0x80)
if (fdc.seek_params & 0x40)
{
if (fdc.seek_params & 0x40)
{
/* Relative seek inwards. */
fdc_seek(fdc.drive, fdc.params[1]);
}
else
{
/* Relative seek outwards. */
fdc_seek(fdc.drive, -fdc.params[1]);
}
/* Relative seek inwards. */
fdc_seek(fdc.drive, fdc.params[1]);
}
else
{
fdc_seek(fdc.drive, fdc.params[1] - fdc.track[fdc.drive]);
/* Relative seek outwards. */
fdc_seek(fdc.drive, -fdc.params[1]);
}
}
else
{
fdc_seek(fdc.drive, fdc.params[1] - fdc.track[fdc.drive]);
}
disctime = 790 * TIMER_USEC;
// pclog("Seek to %i\n", fdc.params[1]);
break;
case 10: /*Read sector ID*/
fdc_set_skip_pulses(fdc.drive ^ fdd_swap, 1);
fdc_rate(fdc.drive);
disctime = 0;
fdc.head = (fdc.params[0] & 4) ? 1 : 0;
fdd_set_head(fdc.drive, (fdc.params[0] & 4) ? 1 : 0);
// pclog("Read sector ID %i %i\n", fdc.rate, fdc.drive);
fdc_set_skip_pulses(fdc.drive ^ fdd_swap, 0);
if (((fdc.drive ^ fdd_swap) != 1) || fdc.drv2en)
disc_readaddress(fdc.drive, fdc.track[fdc.drive], fdc.head, fdc.rate);
else
@@ -812,9 +710,8 @@ bad_command:
}
return;
case 7:
// if (!AT) return;
if (!AT) return;
fdc.rate=val&3;
// pclog("Rate is now: %i\n", fdc.rate);
disc_3f7=val;
return;
@@ -844,15 +741,13 @@ uint8_t fdc_read(uint16_t addr, void *priv)
temp &= ~0x20;
break;
case 3:
drive = (fdc.dor & 1) ^ fdd_swap;
drive = (fdc.dor & 1) ^ fdd_swap;
if (fdc.ps1)
{
/*PS/1 Model 2121 seems return drive type in port 0x3f3,
despite the 82077AA FDC not implementing this. This is
presumably implemented outside the FDC on one of the
motherboard's support chips.*/
/* NOTE by OBattler: This has to be implemented for
super I/O chips too. */
if (fdd_is_525(drive))
temp = 0x20;
else if (fdd_is_ed(drive))
@@ -871,9 +766,9 @@ uint8_t fdc_read(uint16_t addr, void *priv)
temp=fdc.stat;
break;
case 5: /*Data*/
fdc.stat&=~0x80;
if ((fdc.stat & 0xf0) == 0xf0)
{
fdc.stat&=~0x80;
if (fdc.pcjr || !fdc.fifo)
temp = fdc.dat;
else
@@ -882,8 +777,7 @@ uint8_t fdc_read(uint16_t addr, void *priv)
}
break;
}
fdc.stat&=~0x80;
if (paramstogo)
if (paramstogo)
{
paramstogo--;
temp=fdc.res[10 - paramstogo];
@@ -933,7 +827,6 @@ uint8_t fdc_read(uint16_t addr, void *priv)
// exit(-1);
}
// /*if (addr!=0x3f4) */printf("%02X rate=%i %i\n",temp,fdc.rate, fdc.data_ready);
// pclog("fdc_read: %04X: %02X\n", addr, temp);
return temp;
}
@@ -944,59 +837,6 @@ void fdc_callback()
// pclog("fdc_callback %i %i\n", discint, disctime);
// if (fdc.inread)
// rpclog("c82c711_fdc_callback : while inread! %08X %i %02X %i\n", discint, fdc.drive, fdc.st0, ins);
if (fdc_state == FDC_STATE_SEEK)
{
if (!fdd_stepping_motor_on[fdc.drive ^ fdd_swap])
{
pclog("FDC has stopped seeking\n");
fdc_state = FDC_STATE_NORMAL;
fdc.stat &= ~(1 << fdc.drive);
switch (discint)
{
case 2:
disc_readsector(fdc.drive, SECTOR_FIRST, fdc.params[1], fdc.head, fdc.rate, fdc.params[4]);
disctime = 0;
readflash = 1;
fdc.inread = 1;
return;
case 5:
disc_writesector(fdc.drive, fdc.sector, fdc.params[1], fdc.head, fdc.rate, fdc.params[4]);
disctime = 0;
fdc.written = 0;
readflash = 1;
fdc.pos = 0;
if (fdc.pcjr)
fdc.stat = 0xb0;
return;
case 6:
disc_readsector(fdc.drive, fdc.sector, fdc.params[1], fdc.head, fdc.rate, fdc.params[4]);
disctime = 0;
readflash = 1;
fdc.inread = 1;
return;
case 7:
case 0xf:
break;
default:
return;
}
}
else
{
pclog("FDC is seeking\n");
return;
}
}
else
{
if (fdd_stepping_motor_on[fdc.drive ^ fdd_swap])
pclog("FDD is seeking but FDC not\n");
else
pclog("Neither the FDD nor the FDC is seeking\n");
}
switch (discint)
{
case -3: /*End of command with interrupt*/
@@ -1026,7 +866,6 @@ void fdc_callback()
fdc.inread = 0;
discint=-2;
fdc_int();
fdc_set_skip_pulses(fdc.drive, 0);
fdc.stat=0xD0;
fdc.res[4]=(fdc.head?4:0)|fdc.drive;
fdc.res[5]=fdc.res[6]=0;
@@ -1038,15 +877,7 @@ void fdc_callback()
return;
}
else
{
if (((fdc.drive ^ fdd_swap) == 1) && !fdc.drv2en)
not_found[fdc.drive ^ fdd_swap] = 1000;
#if 0
disc_notfound = 1000;
#endif
else
disc_readsector(fdc.drive, SECTOR_NEXT, fdc.rw_track, fdc.head, fdc.rate, fdc.params[4]);
}
disc_readsector(fdc.drive, SECTOR_NEXT, fdc.rw_track, fdc.head, fdc.rate, fdc.params[4]);
fdc.inread = 1;
return;
case 4: /*Sense drive status*/
@@ -1095,7 +926,6 @@ void fdc_callback()
{
discint=-2;
fdc_int();
fdc_set_skip_pulses(fdc.drive, 0);
fdc.stat=0xD0;
fdc.res[4]=(fdc.head?4:0)|fdc.drive;
fdc.res[5]=fdc.res[6]=0;
@@ -1105,20 +935,13 @@ void fdc_callback()
fdc.res[10]=fdc.params[4];
paramstogo=7;
return;
}
if (((fdc.drive ^ fdd_swap) == 1) && !fdc.drv2en)
not_found[fdc.drive ^ fdd_swap] = 1000;
#if 0
disc_notfound = 1000;
#endif
else
disc_writesector(fdc.drive, fdc.sector, fdc.rw_track, fdc.head, fdc.rate, fdc.params[4]);
}
disc_writesector(fdc.drive, fdc.sector, fdc.rw_track, fdc.head, fdc.rate, fdc.params[4]);
// ioc_fiq(IOC_FIQ_DISC_DATA);
return;
case 6: /*Read data*/
// rpclog("Read data %i\n", fdc.tc);
readflash = 1;
fdc_set_skip_pulses(fdc.drive, 1);
fdc.sector++;
if (fdc.sector > fdc.params[5])
{
@@ -1149,7 +972,6 @@ void fdc_callback()
fdc.inread = 0;
discint=-2;
fdc_int();
fdc_set_skip_pulses(fdc.drive, 0);
fdc.stat=0xD0;
fdc.res[4]=(fdc.head?4:0)|fdc.drive;
fdc.res[5]=fdc.res[6]=0;
@@ -1160,14 +982,7 @@ void fdc_callback()
paramstogo=7;
return;
}
fdc_set_skip_pulses(fdc.drive, 0);
if (((fdc.drive ^ fdd_swap) == 1) && !fdc.drv2en)
not_found[fdc.drive ^ fdd_swap] = 1000;
#if 0
disc_notfound = 1000;
#endif
else
disc_readsector(fdc.drive, fdc.sector, fdc.rw_track, fdc.head, fdc.rate, fdc.params[4]);
disc_readsector(fdc.drive, fdc.sector, fdc.rw_track, fdc.head, fdc.rate, fdc.params[4]);
fdc.inread = 1;
return;
@@ -1235,20 +1050,13 @@ void fdc_callback()
else if (fdc.format_state == 3)
{
// pclog("Format next stage track %i head %i\n", fdc.track[fdc.drive], fdc.head);
if (((fdc.drive ^ fdd_swap) == 1) && !fdc.drv2en)
not_found[fdc.drive ^ fdd_swap] = 1000;
#if 0
disc_notfound = 1000;
#endif
else
disc_format(fdc.drive, disc_realtrack(fdc.drive, fdc.track[fdc.drive]), fdc.head, fdc.rate, fdc.params[4]);
disc_format(fdc.drive, fdc.track[fdc.drive], fdc.head, fdc.rate, fdc.params[4]);
fdc.format_state = 4;
}
else
{
discint=-2;
fdc_int();
fdc_set_skip_pulses(fdc.drive, 0);
fdc.stat=0xD0;
fdc.res[4] = (fdc.head?4:0)|fdc.drive;
fdc.res[5] = fdc.res[6] = 0;
@@ -1311,7 +1119,7 @@ void fdc_callback()
fdc.pretrk = fdc.params[2];
fdc.fifo = (fdc.params[1] & 0x20) ? 0 : 1;
fdc.tfifo = (fdc.params[1] & 0xF) + 1;
// pclog("FIFO is now %02X, threshold is %02X\n", fdc.fifo, fdc.tfifo);
pclog("FIFO is now %02X, threshold is %02X\n", fdc.fifo, fdc.tfifo);
fdc.stat = 0x80;
disctime = 0;
// picint(0x40);
@@ -1365,7 +1173,6 @@ void fdc_overrun()
fdc_int();
fdc.stat=0xD0;
fdc_set_skip_pulses(fdc.drive ^ fdd_swap, 0);
fdc.res[4]=0x40|(fdc.head?4:0)|fdc.drive;
fdc.res[5]=0x10; /*Overrun*/
fdc.res[6]=0;
@@ -1433,10 +1240,9 @@ int fdc_data(uint8_t data)
return 0;
}
void fdc_finishread(int drive)
void fdc_finishread()
{
pclog("Read finished\n");
fdc_set_skip_pulses(drive, 1);
fdc.inread = 0;
disctime = 200 * TIMER_USEC;
// rpclog("fdc_finishread\n");
}
@@ -1447,7 +1253,6 @@ void fdc_notfound()
fdc_int();
fdc.stat=0xD0;
fdc_set_skip_pulses(fdc.drive ^ fdd_swap, 0);
fdc.res[4]=0x40|(fdc.head?4:0)|fdc.drive;
fdc.res[5]=5;
fdc.res[6]=0;
@@ -1465,7 +1270,6 @@ void fdc_datacrcerror()
fdc_int();
fdc.stat=0xD0;
fdc_set_skip_pulses(fdc.drive ^ fdd_swap, 0);
fdc.res[4]=0x40|(fdc.head?4:0)|fdc.drive;
fdc.res[5]=0x20; /*Data error*/
fdc.res[6]=0x20; /*Data error in data field*/
@@ -1483,7 +1287,6 @@ void fdc_headercrcerror()
fdc_int();
fdc.stat=0xD0;
fdc_set_skip_pulses(fdc.drive ^ fdd_swap, 0);
fdc.res[4]=0x40|(fdc.head?4:0)|fdc.drive;
fdc.res[5]=0x20; /*Data error*/
fdc.res[6]=0;
@@ -1501,7 +1304,6 @@ void fdc_writeprotect()
fdc_int();
fdc.stat=0xD0;
fdc_set_skip_pulses(fdc.drive ^ fdd_swap, 0);
fdc.res[4]=0x40|(fdc.head?4:0)|fdc.drive;
fdc.res[5]=0x02; /*Not writeable*/
fdc.res[6]=0;
@@ -1568,7 +1370,6 @@ void fdc_sectorid(uint8_t track, uint8_t side, uint8_t sector, uint8_t size, uin
{
// pclog("SectorID %i %i %i %i\n", track, side, sector, size);
fdc_int();
fdc_set_skip_pulses(fdc.drive ^ fdd_swap, 0);
fdc.stat=0xD0;
fdc.res[4]=(fdc.head?4:0)|fdc.drive;
fdc.res[5]=0;
@@ -1599,19 +1400,12 @@ void fdc_init()
fdc_update_densel_force(0);
fdc_update_drv2en(1);
fdc_set_skip_pulses(0, 0);
fdc_set_skip_pulses(1, 0);
fdc.fifo = fdc.tfifo = 0;
fdd_init();
swwp = 0;
disable_write = 0;
fdd_stepping_motor_on[0] = fdd_track_diff[0] = 0;
fdd_stepping_motor_on[1] = fdd_track_diff[1] = 0;
fdc_state = FDC_STATE_NORMAL;
fdc.fifo = fdc.tfifo = 0;
}
void fdc_add()
@@ -1644,11 +1438,6 @@ void fdc_remove()
io_removehandler(0x03f7, 0x0001, fdc_read, NULL, NULL, fdc_write, NULL, NULL, NULL);
}
void fdc_set_ps1()
{
fdc.ps1 = 1;
}
void fdc_discchange_clear(int drive)
{
if (drive < 2)
@@ -1664,3 +1453,8 @@ void fdc_3f1_enable(int enable)
{
fdc.enable_3f1 = enable;
}
void fdc_set_ps1()
{
fdc.ps1 = 1;
}

View File

@@ -24,4 +24,3 @@ void fdc_update_densel_polarity(int densel_polarity);
void fdc_update_densel_force(int densel_force);
void fdc_update_drvrate(int drive, int drvrate);
void fdc_update_drv2en(int drv2en);
int fdc_skip_pulses(int drive);

View File

@@ -24,7 +24,7 @@ static void write_lock(uint8_t val)
void fdc37c665_write(uint16_t port, uint8_t val, void *priv)
{
// pclog("Write SuperIO %04x %02x\n", port, val);
pclog("Write SuperIO %04x %02x\n", port, val);
if (fdc37c665_lock[0] == 0x55 && fdc37c665_lock[1] == 0x55)
{
if (port == 0x3f0)
@@ -126,7 +126,7 @@ void fdc37c665_write(uint16_t port, uint8_t val, void *priv)
uint8_t fdc37c665_read(uint16_t port, void *priv)
{
// pclog("Read SuperIO %04x %02x\n", port, fdc37c665_curreg);
pclog("Read SuperIO %04x %02x\n", port, fdc37c665_curreg);
if (fdc37c665_lock[0] == 0x55 && fdc37c665_lock[1] == 0x55)
{
if (port == 0x3f1)

127
src/fdd.c
View File

@@ -2,7 +2,6 @@
#include "disc.h"
#include "fdc.h"
#include "fdd.h"
#include "timer.h"
static struct
{
@@ -48,152 +47,37 @@ static struct
.flags = 0
},
{ /*5.25" DD*/
#ifdef MAINLINE
.max_track = 41,
#else
.max_track = 43,
#endif
.flags = FLAG_RPM_300 | FLAG_525 | FLAG_HOLE0
},
{ /*5.25" HD*/
#ifdef MAINLINE
.max_track = 82,
#else
.max_track = 86,
#endif
.flags = FLAG_RPM_360 | FLAG_525 | FLAG_HOLE0 | FLAG_HOLE1 | FLAG_DOUBLE_STEP
},
{ /*5.25" HD Dual RPM*/
#ifdef MAINLINE
.max_track = 82,
#else
.max_track = 86,
#endif
.flags = FLAG_RPM_300 | FLAG_RPM_360 | FLAG_525 | FLAG_HOLE0 | FLAG_HOLE1 | FLAG_DOUBLE_STEP
},
{ /*3.5" DD*/
#ifdef MAINLINE
.max_track = 82,
#else
.max_track = 86,
#endif
.flags = FLAG_RPM_300 | FLAG_HOLE0
},
{ /*3.5" HD*/
#ifdef MAINLINE
.max_track = 82,
#else
.max_track = 86,
#endif
.flags = FLAG_RPM_300 | FLAG_HOLE0 | FLAG_HOLE1
},
{ /*3.5" HD 3-Mode*/
#ifdef MAINLINE
.max_track = 82,
#else
.max_track = 86,
#endif
.flags = FLAG_RPM_300 | FLAG_RPM_360 | FLAG_HOLE0 | FLAG_HOLE1
},
{ /*3.5" ED*/
#ifdef MAINLINE
.max_track = 82,
#else
.max_track = 86,
#endif
.flags = FLAG_RPM_300 | FLAG_HOLE0 | FLAG_HOLE1 | FLAG_HOLE2
}
};
int fdd_swap = 0;
int fdd_stepping_motor_on[2] = {0, 0};
int fdd_track_diff[2] = {0, 0};
int fdd_track_direction[2] = {0, 0};
int fdd_old_track[2] = {0, 0};
int fdd_poll_time[2] = {0, 0};
void fdd_seek_poll(int poll_drive)
{
if (!fdd_track_diff[poll_drive])
{
fdd_stepping_motor_on[poll_drive] = 0;
return;
}
/* 80-track drive takes 6 µs per step, 40-track drive takes 10 µs. */
// fdd_poll_time[poll_drive] += (drive_types[fdd[poll_drive].type].max_track <= 43) ? (10 * TIMER_USEC) : (6 * TIMER_USEC);
fdd_poll_time[poll_drive] += (drive_types[fdd[poll_drive].type].max_track <= 43) ? (5 * TIMER_USEC) : (3 * TIMER_USEC);
if (fdd_track_direction[poll_drive])
{
fdd[poll_drive].track++;
if (fdd[poll_drive].track > drive_types[fdd[poll_drive].type].max_track)
fdd[poll_drive].track = drive_types[fdd[poll_drive].type].max_track;
}
else
{
fdd[poll_drive].track--;
if (fdd[poll_drive].track < 0)
fdd[poll_drive].track = 0;
}
fdd_track_diff[poll_drive]--;
if (!fdd_track_diff[poll_drive])
{
fdc_discchange_clear(poll_drive);
disc_seek(poll_drive, fdd[poll_drive].track);
fdd_stepping_motor_on[poll_drive] = 0;
}
}
void fdd_seek_poll_0()
{
fdd_seek_poll(0);
}
void fdd_seek_poll_1()
{
fdd_seek_poll(1);
}
#if 0
void fdd_seek(int drive, int track_diff)
{
drive ^= fdd_swap;
fdd_old_track[drive] = fdd[drive].track;
if (!track_diff)
{
/* Do not turn on motor if there are no pulses to be sent. */
fdc_discchange_clear(drive);
return;
}
fdd_stepping_motor_on[drive] = (track_diff == 0) ? 0 : 1;
if (fdd_stepping_motor_on[drive]) pclog("fdd_seek(): Stepping motor now on\n");
if (track_diff < 0)
{
fdd_track_diff[drive] = -track_diff;
fdd_track_direction[drive] = 0;
}
else
{
fdd_track_diff[drive] = track_diff;
fdd_track_direction[drive] = 1;
}
fdd_old_track[drive] = fdd[drive].track;
}
#endif
void fdd_seek(int drive, int track_diff)
{
int old_track;
@@ -210,13 +94,9 @@ 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;
// pclog("fdd_seek: drive=%i track_diff=%i old_track=%i track=%i\n", drive, track_diff, old_track, fdd[drive].track);
// if (fdd[drive].track != old_track)
// fdc_discchange_clear(drive);
fdc_discchange_clear(drive);
disc_seek(drive, fdd[drive].track);
// disctime = 5000;
disctime = 50;
disctime = 5000;
}
int fdd_track0(int drive)
@@ -317,9 +197,4 @@ int fdd_get_head(int drive)
void fdd_init()
{
fdd_stepping_motor_on[0] = fdd_stepping_motor_on[1] = 0;
fdd_track_diff[0] = fdd_track_diff[1] = 0;
timer_add(fdd_seek_poll_0, &(fdd_poll_time[0]), &(fdd_stepping_motor_on[0]), NULL);
timer_add(fdd_seek_poll_1, &(fdd_poll_time[1]), &(fdd_stepping_motor_on[1]), NULL);
}

View File

@@ -15,6 +15,4 @@ int fdd_get_type(int drive);
extern int fdd_swap;
extern int fdd_stepping_motor_on[2];
extern int fdd_track_diff[2];
void fdd_init();
void fdd_init();

View File

@@ -1,3 +1,4 @@
#include <stdint.h>
#include <stdlib.h>
#include "ibm.h"
#include "device.h"
@@ -55,7 +56,7 @@ char *joystick_get_button_name(int joystick, int id)
typedef struct gameport_axis_t
{
int count;
int64_t count;
int axis_nr;
struct gameport_t *gameport;
} gameport_axis_t;

View File

@@ -210,7 +210,7 @@ extern int cpl_override;
typedef struct PIT
{
uint32_t l[3];
int c[3];
int64_t c[3];
uint8_t m[3];
uint8_t ctrl,ctrls[3];
int wp,rm[3],wm[3];
@@ -282,7 +282,7 @@ extern int pic_intpending;
int intcount;
int disctime;
int64_t disctime;
char discfns[2][256];
int driveempty[2];
@@ -435,14 +435,14 @@ void writeega_chain4(uint32_t addr, uint8_t val);
extern uint32_t svgarbank,svgawbank;
/*Serial*/
extern int mousedelay;
extern int64_t mousedelay;
/*Sound*/
uint8_t spkstat;
float spktime;
int rtctime;
int64_t rtctime;
int soundtime,gustime,gustime2,vidtime;
int ppispeakon;
float CGACONST;
@@ -490,13 +490,13 @@ typedef struct
PcemHDC hdc[4];
/*Keyboard*/
int keybsenddelay;
int64_t keybsenddelay;
/*CD-ROM*/
extern int cdrom_drive;
extern int old_cdrom_drive;
extern int idecallback[3];
extern int64_t idecallback[3];
extern int cdrom_enabled;
#define CD_STATUS_EMPTY 0

View File

@@ -327,7 +327,7 @@ static void callnonreadcd(IDE *ide);
static void callreadcd(IDE *ide);
static void atapicommand(int ide_board);
int idecallback[3] = {0, 0, 0};
int64_t idecallback[3] = {0, 0, 0};
int cur_ide[3];

View File

@@ -51,7 +51,7 @@ void atapi_insert_cdrom();
extern int ideboard;
extern int idecallback[3];
extern int64_t idecallback[3];
extern char ide_fn[4][512];

View File

@@ -21,7 +21,7 @@ uint8_t batman_brdconfig(uint16_t port, void *p)
}
static uint16_t batman_timer_latch;
static int batman_timer = 0;
static int64_t batman_timer = 0;
static void batman_timer_over(void *p)
{
batman_timer = 0;

View File

@@ -30,13 +30,13 @@
typedef struct
{
int poll_time;
int64_t poll_time;
int poll_left;
int poll_clock;
uint64_t poll_data;
int poll_mode;
int trigger_time;
int64_t trigger_time;
int data_mode;
} sw_data;

View File

@@ -1,3 +1,4 @@
#include <stdint.h>
#include "ibm.h"
#include "io.h"
#include "mem.h"

View File

@@ -1,3 +1,5 @@
#include <stdint.h>
#include "ibm.h"
#include "io.h"
#include "mem.h"

View File

@@ -1,3 +1,5 @@
#include <stdint.h>
#include "ibm.h"
#include "io.h"
#include "mem.h"

View File

@@ -1,3 +1,5 @@
#include <stdint.h>
#include "ibm.h"
#include "device.h"
#include "io.h"

View File

@@ -1,3 +1,5 @@
#include <stdint.h>
#include "ibm.h"
#include "io.h"
#include "mem.h"

View File

@@ -500,6 +500,7 @@ void at_mb500n_init()
void at_p54tp4xe_init()
{
at_init();
memregs_init();
mouse_always_serial ? mouse_serial_init() : mouse_ps2_init();
pci_init(PCI_CONFIG_TYPE_1, 0xd, 0x10);
i430fx_init();
@@ -539,6 +540,7 @@ void at_acerv35n_init()
void at_p55t2p4_init()
{
at_init();
memregs_init();
mouse_always_serial ? mouse_serial_init() : mouse_ps2_init();
pci_init(PCI_CONFIG_TYPE_1, 0, 31);
i430hx_init();
@@ -563,6 +565,7 @@ void at_i430vx_init()
void at_p55tvp4_init()
{
at_init();
memregs_init();
mouse_always_serial ? mouse_serial_init() : mouse_ps2_init();
pci_init(PCI_CONFIG_TYPE_1, 0, 31);
i430vx_init();

View File

@@ -1,5 +1,5 @@
extern void (*mouse_poll)(int x, int y, int b);
extern int mousepos;
extern int mousedelay;
extern int64_t mousedelay;

View File

@@ -69,7 +69,7 @@ static struct
static int vlan_handlers_num;
static int vlan_poller_time = 0;
static int64_t vlan_poller_time = 0;
void vlan_handler(void (*poller)(void *p), void *p)
//void vlan_handler(int (*can_receive)(void *p), void (*receive)(void *p, const uint8_t *buf, int size), void *p)

View File

@@ -13,7 +13,8 @@ int nvraddr;
int nvr_dosave = 0;
static int nvr_onesec_time = 0, nvr_onesec_cnt = 0;
static int64_t nvr_onesec_time = 0;
static int nvr_onesec_cnt = 0;
void getnvrtime()
{
@@ -59,10 +60,46 @@ int nvr_check_alarm(int nvraddr)
return (nvrram[nvraddr + 1] == nvrram[nvraddr] || (nvrram[nvraddr + 1] & ALARM_DONTCARE) == ALARM_DONTCARE);
}
int64_t nvr_update_end_count = 0;
void nvr_update_end(void *p)
{
if (!(nvrram[RTCREGB] & RTCSET))
{
getnvrtime();
/* Clear update status. */
nvr_update_status = 0;
if (nvr_check_alarm(RTCSECONDS) && nvr_check_alarm(RTCMINUTES) && nvr_check_alarm(RTCHOURS))
{
nvrram[RTCREGC] |= RTCAF;
if (nvrram[RTCREGB] & RTCAIE)
{
nvrram[RTCREGC] |= RTCIRQF;
if (AMSTRAD) picint(2);
else picint(0x100);
}
}
/* The flag and interrupt should be issued on update ended, not started. */
nvrram[RTCREGC] |= RTCUF;
if (nvrram[RTCREGB] & RTCUIE)
{
nvrram[RTCREGC] |= RTCIRQF;
if (AMSTRAD) picint(2);
else picint(0x100);
}
}
// pclog("RTC onesec\n");
nvr_update_end_count = 0;
}
void nvr_onesec(void *p)
{
nvr_onesec_cnt++;
if (nvr_onesec_cnt >= 32768)
if (nvr_onesec_cnt >= 100)
{
nvr_onesec_cnt = 0;
@@ -71,40 +108,13 @@ void nvr_onesec(void *p)
{
nvr_update_status = RTCUIP;
if (!enable_sync) rtc_tick();
timer_clock();
nvr_update_end_count = (int)((244.0 + 1984.0) * TIMER_USEC);
timer_update_outstanding();
}
}
else if (nvr_onesec_cnt == 73) /* 73 of our cycles means 244+1984 us = update in progress time per the specification. */
{
if (!(nvrram[RTCREGB] & RTCSET))
{
getnvrtime();
/* Clear update status. */
nvr_update_status = 0;
if (nvr_check_alarm(RTCSECONDS) && nvr_check_alarm(RTCMINUTES) && nvr_check_alarm(RTCHOURS))
{
nvrram[RTCREGC] |= RTCAF;
if (nvrram[RTCREGB] & RTCAIE)
{
nvrram[RTCREGC] |= RTCIRQF;
if (AMSTRAD) picint(2);
else picint(0x100);
}
}
/* The flag and interrupt should be issued on update ended, not started. */
nvrram[RTCREGC] |= RTCUF;
if (nvrram[RTCREGB] & RTCUIE)
{
nvrram[RTCREGC] |= RTCIRQF;
if (AMSTRAD) picint(2);
else picint(0x100);
}
// pclog("RTC onesec\n");
}
}
/* This is correct! The real RTC's one second timer operates at 32768 Hz, not 100 Hz! */
nvr_onesec_time += (int)((1000000.0 / 32768.0) * TIMER_USEC);
nvr_onesec_time += (int)(10000 * TIMER_USEC);
}
void writenvr(uint16_t addr, uint8_t val, void *priv)
@@ -307,4 +317,5 @@ void nvr_init()
io_sethandler(0x0070, 0x0002, readnvr, NULL, NULL, writenvr, NULL, NULL, NULL);
timer_add(nvr_rtc, &rtctime, TIMER_ALWAYS_ENABLED, NULL);
timer_add(nvr_onesec, &nvr_onesec_time, TIMER_ALWAYS_ENABLED, NULL);
timer_add(nvr_update_end, &nvr_update_end_count, &nvr_update_end_count, NULL);
}

View File

@@ -465,7 +465,7 @@ void runpc()
framecount++;
if (framecountx>=100)
{
pclog("onesec\n");
// pclog("onesec\n");
framecountx=0;
mips=(float)insc/1000000.0f;
insc=0;

View File

@@ -88,7 +88,7 @@ static void pit_set_out(int t, int out)
static void pit_load(int t)
{
int l = pit.l[t] ? pit.l[t] : 0x10000;
int64_t l = pit.l[t] ? pit.l[t] : 0x10000;
timer_process();
pit.newcount[t] = 0;
pit.disabled[t] = 0;
@@ -97,7 +97,7 @@ static void pit_load(int t)
{
case 0: /*Interrupt on terminal count*/
pit.count[t] = l;
pit.c[t] = (int)((l << TIMER_SHIFT) * PITCONST);
pit.c[t] = (int64_t)((l << TIMER_SHIFT) * PITCONST);
pit_set_out(t, 0);
pit.thit[t] = 0;
pit.enabled[t] = pit.gate[t];
@@ -109,7 +109,7 @@ static void pit_load(int t)
if (pit.initial[t])
{
pit.count[t] = l - 1;
pit.c[t] = (int)(((l - 1) << TIMER_SHIFT) * PITCONST);
pit.c[t] = (int64_t)(((l - 1) << TIMER_SHIFT) * PITCONST);
pit_set_out(t, 1);
pit.thit[t] = 0;
}
@@ -119,7 +119,7 @@ static void pit_load(int t)
if (pit.initial[t])
{
pit.count[t] = l;
pit.c[t] = (int)((((l + 1) >> 1) << TIMER_SHIFT) * PITCONST);
pit.c[t] = (int64_t)((((l + 1) >> 1) << TIMER_SHIFT) * PITCONST);
pit_set_out(t, 1);
pit.thit[t] = 0;
}
@@ -132,7 +132,7 @@ static void pit_load(int t)
else
{
pit.count[t] = l;
pit.c[t] = (int)((l << TIMER_SHIFT) * PITCONST);
pit.c[t] = (int64_t)((l << TIMER_SHIFT) * PITCONST);
pit_set_out(t, 0);
pit.thit[t] = 0;
}
@@ -150,7 +150,7 @@ static void pit_load(int t)
void pit_set_gate(int t, int gate)
{
int l = pit.l[t] ? pit.l[t] : 0x10000;
int64_t l = pit.l[t] ? pit.l[t] : 0x10000;
if (pit.disabled[t])
{
@@ -170,7 +170,7 @@ void pit_set_gate(int t, int gate)
if (gate && !pit.gate[t])
{
pit.count[t] = l;
pit.c[t] = (int)((l << TIMER_SHIFT) * PITCONST);
pit.c[t] = (int64_t)((l << TIMER_SHIFT) * PITCONST);
pit_set_out(t, 0);
pit.thit[t] = 0;
pit.enabled[t] = 1;
@@ -180,7 +180,7 @@ void pit_set_gate(int t, int gate)
if (gate && !pit.gate[t])
{
pit.count[t] = l - 1;
pit.c[t] = (int)(((l - 1) << TIMER_SHIFT) * PITCONST);
pit.c[t] = (int64_t)(((l - 1) << TIMER_SHIFT) * PITCONST);
pit_set_out(t, 1);
pit.thit[t] = 0;
}
@@ -190,7 +190,7 @@ void pit_set_gate(int t, int gate)
if (gate && !pit.gate[t])
{
pit.count[t] = l;
pit.c[t] = (int)((((l + 1) >> 1) << TIMER_SHIFT) * PITCONST);
pit.c[t] = (int64_t)((((l + 1) >> 1) << TIMER_SHIFT) * PITCONST);
pit_set_out(t, 1);
pit.thit[t] = 0;
}
@@ -205,7 +205,7 @@ void pit_set_gate(int t, int gate)
static void pit_over(int t)
{
int l = pit.l[t] ? pit.l[t] : 0x10000;
int64_t l = pit.l[t] ? pit.l[t] : 0x10000;
if (pit.disabled[t])
{
pit.count[t] += 0xffff;
@@ -222,7 +222,7 @@ static void pit_over(int t)
pit_set_out(t, 1);
pit.thit[t] = 1;
pit.count[t] += 0xffff;
pit.c[t] += (int)((0xffff << TIMER_SHIFT) * PITCONST);
pit.c[t] += (int64_t)((0xffff << TIMER_SHIFT) * PITCONST);
break;
case 2: /*Rate generator*/
pit.count[t] += l;
@@ -235,13 +235,13 @@ static void pit_over(int t)
{
pit_set_out(t, 0);
pit.count[t] += (l >> 1);
pit.c[t] += (int)(((l >> 1) << TIMER_SHIFT) * PITCONST);
pit.c[t] += (int64_t)(((l >> 1) << TIMER_SHIFT) * PITCONST);
}
else
{
pit_set_out(t, 1);
pit.count[t] += ((l + 1) >> 1);
pit.c[t] = (int)((((l + 1) >> 1) << TIMER_SHIFT) * PITCONST);
pit.c[t] = (int64_t)((((l + 1) >> 1) << TIMER_SHIFT) * PITCONST);
}
// if (!t) pclog("pit_over: square wave mode c=%x %lli %f\n", pit.c[t], tsc, PITCONST);
break;
@@ -255,13 +255,13 @@ static void pit_over(int t)
{
pit.newcount[t] = 0;
pit.count[t] += l;
pit.c[t] += (int)((l << TIMER_SHIFT) * PITCONST);
pit.c[t] += (int64_t)((l << TIMER_SHIFT) * PITCONST);
}
else
{
pit.thit[t] = 1;
pit.count[t] += 0xffff;
pit.c[t] += (int)((0xffff << TIMER_SHIFT) * PITCONST);
pit.c[t] += (int64_t)((0xffff << TIMER_SHIFT) * PITCONST);
}
break;
case 5: /*Hardware triggered strove*/
@@ -272,7 +272,7 @@ static void pit_over(int t)
}
pit.thit[t] = 1;
pit.count[t] += 0xffff;
pit.c[t] += (int)((0xffff << TIMER_SHIFT) * PITCONST);
pit.c[t] += (int64_t)((0xffff << TIMER_SHIFT) * PITCONST);
break;
}
pit.running[t] = pit.enabled[t] && pit.using_timer[t] && !pit.disabled[t];
@@ -280,7 +280,7 @@ static void pit_over(int t)
int pit_get_timer_0()
{
int read = (int)((pit.c[0] + ((1 << TIMER_SHIFT) - 1)) / PITCONST) >> TIMER_SHIFT;
int read = (int)((int64_t)((pit.c[0] + ((1 << TIMER_SHIFT) - 1)) / PITCONST) >> TIMER_SHIFT);
//pclog("pit_get_timer_0: t=%i using_timer=%i m=%i\n", 0, pit.using_timer[0], pit.m[0]);
if (pit.m[0] == 2)
read++;
@@ -299,7 +299,7 @@ static int pit_read_timer(int t)
// pclog("pit_read_timer: t=%i using_timer=%i m=%i\n", t, pit.using_timer[t], pit.m[t]);
if (pit.using_timer[t])
{
int read = (int)((pit.c[t] + ((1 << TIMER_SHIFT) - 1)) / PITCONST) >> TIMER_SHIFT;
int read = (int)((int64_t)((pit.c[t] + ((1 << TIMER_SHIFT) - 1)) / PITCONST) >> TIMER_SHIFT);
if (pit.m[t] == 2)
read++;
if (read < 0)
@@ -330,11 +330,11 @@ void pit_write(uint16_t addr, uint8_t val, void *priv)
if (!(val&0x20))
{
if (val & 2)
pit.rl[0] = pit.using_timer[0] ? ((int)(pit.c[0] / PITCONST) >> TIMER_SHIFT) : pit.count[0];
pit.rl[0] = pit.using_timer[0] ? (int)(((int64_t) (pit.c[0] / PITCONST)) >> TIMER_SHIFT) : pit.count[0];
if (val & 4)
pit.rl[1] = pit.using_timer[1] ? ((int)(pit.c[1] / PITCONST) >> TIMER_SHIFT) : pit.count[1];
pit.rl[1] = pit.using_timer[1] ? (int)(((int64_t) (pit.c[1] / PITCONST)) >> TIMER_SHIFT) : pit.count[1];
if (val & 8)
pit.rl[2] = pit.using_timer[2] ? ((int)(pit.c[2] / PITCONST) >> TIMER_SHIFT) : pit.count[2];
pit.rl[2] = pit.using_timer[2] ? (int)(((int64_t) (pit.c[2] / PITCONST)) >> TIMER_SHIFT) : pit.count[2];
}
if (!(val & 0x10))
{
@@ -410,7 +410,7 @@ void pit_write(uint16_t addr, uint8_t val, void *priv)
pit.l[t]=val;
// pit.thit[t]=0;
pit_load(t);
// pit.c[t]=pit.l[t]*PITCONST;
// pit.c[t]=((int64_t)pit.l[t])*PITCONST;
// if (!t)
// picintc(1);
break;
@@ -549,7 +549,7 @@ void pit_set_using_timer(int t, int using_timer)
if (pit.using_timer[t] && !using_timer)
pit.count[t] = pit_read_timer(t);
if (!pit.using_timer[t] && using_timer)
pit.c[t] = (int)((pit.count[t] << TIMER_SHIFT) * PITCONST);
pit.c[t] = (int64_t)((((int64_t) pit.count[t]) << TIMER_SHIFT) * PITCONST);
pit.using_timer[t] = using_timer;
pit.running[t] = pit.enabled[t] && pit.using_timer[t] && !pit.disabled[t];
timer_update_outstanding();

View File

@@ -16,7 +16,7 @@ enum
SERIAL serial1, serial2;
int mousepos=-1;
int mousedelay;
int64_t mousedelay;
void serial_reset()
{

View File

@@ -22,7 +22,7 @@ typedef struct
uint8_t fifo[256];
int fifo_read, fifo_write;
int recieve_delay;
int64_t recieve_delay;
} SERIAL;
extern SERIAL serial1, serial2;

View File

@@ -84,7 +84,7 @@ static struct
static int sound_handlers_num;
static int sound_poll_time = 0, sound_get_buffer_time = 0, sound_poll_latch;
static int64_t sound_poll_time = 0, sound_get_buffer_time = 0, sound_poll_latch;
int sound_pos_global = 0;
int soundon = 1;

View File

@@ -1,3 +1,4 @@
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include "ibm.h"
@@ -35,7 +36,7 @@ typedef struct adgold_t
int16_t adgold_mma_out[2];
int adgold_mma_intpos[2];
int adgold_mma_timer_count;
int64_t adgold_mma_timer_count;
struct
{

View File

@@ -1,3 +1,4 @@
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -42,13 +43,13 @@ typedef struct gus_t
int16_t buffer[2][SOUNDBUFLEN];
int pos;
int samp_timer, samp_latch;
int64_t samp_timer, samp_latch;
uint8_t *ram;
int irqnext;
int timer_1, timer_2;
int64_t timer_1, timer_2;
int irq, dma, irq_midi;
int latch_enable;

View File

@@ -2,7 +2,7 @@ typedef struct opl_t
{
int chip_nr[2];
int timers[2][2];
int64_t timers[2][2];
int timers_enable[2][2];
int16_t filtbuf[2];

View File

@@ -1,3 +1,4 @@
#include <stdint.h>
#include <stdlib.h>
#include "ibm.h"
@@ -118,7 +119,7 @@ typedef struct pas16_t
struct
{
uint32_t l[3];
int c[3];
int64_t c[3];
uint8_t m[3];
uint8_t ctrl, ctrls[2];
int wp, rm[3], wm[3];

View File

@@ -1,3 +1,4 @@
#include <stdint.h>
#include <stdlib.h>
#include "ibm.h"
#include "device.h"
@@ -12,7 +13,7 @@ typedef struct ps1_audio_t
uint8_t status, ctrl;
int timer_latch, timer_count, timer_enable;
int64_t timer_latch, timer_count, timer_enable;
uint8_t fifo[2048];
int fifo_read_idx, fifo_write_idx;

View File

@@ -1,3 +1,4 @@
#include <stdint.h>
#include <stdlib.h>
#include "ibm.h"
#include "device.h"
@@ -21,7 +22,7 @@ typedef struct pssj_t
int amplitude;
int irq;
int timer_count;
int64_t timer_count;
int enable;
int wave_pos;

View File

@@ -45,7 +45,7 @@ typedef struct sb_dsp_t
int sbenable, sb_enable_i;
int sbcount, sb_count_i;
int64_t sbcount, sb_count_i;
int sblatcho, sblatchi;
@@ -55,7 +55,7 @@ typedef struct sb_dsp_t
int asp_data_len;
int wb_time, wb_full;
int64_t wb_time, wb_full;
int16_t buffer[SOUNDBUFLEN * 2];
int pos;

View File

@@ -18,14 +18,14 @@ static struct
void (*callback)(void *priv);
void *priv;
int *enable;
int *count;
int64_t *count;
} timers[TIMERS_MAX];
int timers_present = 0;
int timer_one = 1;
int timer_count = 0, timer_latch = 0;
int timer_start = 0;
int64_t timer_count = 0, timer_latch = 0;
int64_t timer_start = 0;
void timer_process()
{
@@ -33,7 +33,7 @@ void timer_process()
int retry;
int process = 0;
/*Get actual elapsed time*/
int diff = timer_latch - timer_count;
int64_t diff = timer_latch - timer_count;
int enable[TIMERS_MAX];
timer_latch = 0;
@@ -79,7 +79,7 @@ void timer_process()
void timer_update_outstanding()
{
int c;
timer_latch = 0x7fffffff;
timer_latch = 0x7fffffffffffffff;
for (c = 0; c < timers_present; c++)
{
if (*timers[c].enable && *timers[c].count < timer_latch)
@@ -96,7 +96,7 @@ void timer_reset()
// timer_process();
}
int timer_add(void (*callback)(void *priv), int *count, int *enable, void *priv)
int timer_add(void (*callback)(void *priv), int64_t *count, int *enable, void *priv)
{
if (timers_present < TIMERS_MAX)
{

View File

@@ -3,7 +3,7 @@
#include "cpu.h"
extern int timer_start;
extern int64_t timer_start;
#define timer_start_period(cycles) \
timer_start = cycles;
@@ -11,7 +11,7 @@ extern int timer_start;
#define timer_end_period(cycles) \
do \
{ \
int diff = timer_start - (cycles); \
int64_t diff = timer_start - ((uint64_t) cycles); \
timer_count -= diff; \
timer_start = cycles; \
if (timer_count <= 0) \
@@ -24,16 +24,16 @@ extern int timer_start;
#define timer_clock() \
do \
{ \
int diff; \
int64_t diff; \
if (AT) \
{ \
diff = timer_start - (cycles << TIMER_SHIFT); \
timer_start = cycles << TIMER_SHIFT; \
diff = timer_start - (((uint64_t) cycles) << TIMER_SHIFT); \
timer_start = ((uint64_t) cycles) << TIMER_SHIFT; \
} \
else \
{ \
diff = timer_start - (cycles * xt_cpu_multi); \
timer_start = cycles * xt_cpu_multi; \
diff = timer_start - (((uint64_t) cycles) * xt_cpu_multi); \
timer_start = ((uint64_t) cycles) * xt_cpu_multi; \
} \
timer_count -= diff; \
timer_process(); \
@@ -43,17 +43,15 @@ extern int timer_start;
void timer_process();
void timer_update_outstanding();
void timer_reset();
int timer_add(void (*callback)(void *priv), int *count, int *enable, void *priv);
int timer_add(void (*callback)(void *priv), int64_t *count, int *enable, void *priv);
void timer_set_callback(int timer, void (*callback)(void *priv));
#define TIMER_ALWAYS_ENABLED &timer_one
extern int timer_count;
extern int64_t timer_count;
extern int timer_one;
// #define TIMER_SHIFT 6
/* Reduced by 4 in order to alleviate problems at higher CPU speed. Will be put back if a better solution is ever implemented. */
#define TIMER_SHIFT 4
#define TIMER_SHIFT 6
extern int TIMER_USEC;

View File

@@ -18,7 +18,7 @@ typedef struct cga_t
int oddeven;
int dispontime, dispofftime;
int vidtime;
int64_t vidtime;
int firstline, lastline;

View File

@@ -353,11 +353,11 @@ void gd5429_write_linear(uint32_t addr, uint8_t val, void *p)
else if (svga->chain2_write)
{
/* Redone because the original code caused problems when using Windows 3.1 EGA driver on (S)VGA card. */
plane = (svga->readplane & 2) | (addr & 1);
plane = (addr & 1) | (svga->oddeven_page ? 2 : 0);
mask = (1 << plane);
if (svga->seqregs[2] & mask)
{
addr = ((addr & ~1) << 2) | plane | (svga->oddeven_page ? 0x10000 : 0);
addr = (((addr & ~1) | svga->oddeven_chain) << 2) | plane;
addr &= 0x7fffff;
if ((!svga->extvram) && (addr >= 0x10000)) return;
if (addr >= svga->vram_limit) return;

View File

@@ -314,7 +314,6 @@ void ega_poll(void *p)
int offset;
uint8_t edat[4];
int drawcursor = 0;
uint32_t addr_ex = 0;
int y_add = enable_overscan ? 14 : 0;
int x_add = enable_overscan ? 8 : 0;
int y_add_ex = enable_overscan ? 28 : 0;
@@ -363,9 +362,8 @@ void ega_poll(void *p)
for (x = 0; x < ega->hdisp; x++)
{
drawcursor = ((ega->ma == ega->ca) && ega->con && ega->cursoron);
addr_ex = (ega->oddeven_page ? 0x10000 : 0);
chr = ega->vram[(ega->ma << 1) | addr_ex];
attr = ega->vram[((ega->ma << 1) + 1) | addr_ex];
chr = ega->vram[ega->ma << 1];
attr = ega->vram[(ega->ma << 1) + 1];
if (attr & 8) charaddr = ega->charsetb + (chr * 128);
else charaddr = ega->charseta + (chr * 128);
@@ -726,11 +724,11 @@ void ega_write(uint32_t addr, uint8_t val, void *p)
if (ega->chain2_write)
{
plane = (ega->readplane & 2) | (addr & 1);
plane = (addr & 1) | (ega->oddeven_page ? 2 : 0);
mask = (1 << plane);
if (ega->seqregs[2] & mask)
{
addr = ((addr & ~1) << 2) | plane | (ega->oddeven_page ? 0x10000 : 0);
addr = (((addr & ~1) | ega->oddeven_chain) << 2) | plane;
if ((!ega->extvram) && (addr >= 0x10000)) return;
if (addr >= 0x40000) return;
if ((raddr <= 0xA0000) || (raddr >= 0xBFFFF)) return;
@@ -867,8 +865,8 @@ uint8_t ega_read(uint32_t addr, void *p)
if (ega->chain2_read)
{
plane = (ega->readplane & 2) | (addr & 1);
addr = ((addr & ~1) << 2) | plane | (ega->oddeven_page ? 0x10000 : 0);
plane = (addr & 1) | (ega->oddeven_page ? 2 : 0);
addr = (((addr & ~1) | ega->oddeven_chain) << 2) | plane;
if ((!ega->extvram) && (addr >= 0x10000)) return 0xff;
if (addr >= 0x40000) return 0xff;
return ega->vram[addr];

View File

@@ -25,7 +25,7 @@ typedef struct ega_t
uint8_t colourcompare, colournocare;
int readmode, writemode, readplane;
int chain4, chain2_read, chain2_write;
int oddeven_page;
int oddeven_page, oddeven_chain;
int enablevram, extvram;
uint8_t writemask;
uint32_t charseta, charsetb;
@@ -43,7 +43,7 @@ typedef struct ega_t
int vres;
int dispontime, dispofftime;
int vidtime;
int64_t vidtime;
uint8_t scrblank;

View File

@@ -17,7 +17,7 @@ typedef struct hercules_t
uint8_t ctrl, ctrl2, stat;
int dispontime, dispofftime;
int vidtime;
int64_t vidtime;
int firstline, lastline;

View File

@@ -148,7 +148,7 @@ typedef struct incolor_t
uint8_t ctrl, ctrl2, stat;
int dispontime, dispofftime;
int vidtime;
int64_t vidtime;
int firstline, lastline;

View File

@@ -18,7 +18,7 @@ typedef struct mda_t
uint8_t ctrl, stat;
int dispontime, dispofftime;
int vidtime;
int64_t vidtime;
int firstline, lastline;

View File

@@ -33,7 +33,8 @@ typedef struct m24_t
uint16_t ma, maback;
int dispon;
int dispontime, dispofftime, vidtime;
int dispontime, dispofftime;
int64_t vidtime;
int firstline, lastline;
} m24_t;

View File

@@ -35,7 +35,8 @@ typedef struct pc1512_t
int dispon;
int blink;
int dispontime, dispofftime, vidtime;
int dispontime, dispofftime;
int64_t vidtime;
int firstline, lastline;
uint8_t *vram;

View File

@@ -23,7 +23,8 @@ typedef struct pc1640_t
rom_t bios_rom;
int cga_enabled;
int dispontime, dispofftime, vidtime;
int dispontime, dispofftime;
int64_t vidtime;
} pc1640_t;
void pc1640_out(uint16_t addr, uint8_t val, void *p)

View File

@@ -33,7 +33,8 @@ typedef struct pcjr_t
int vsynctime, vadj;
uint16_t ma, maback;
int dispontime, dispofftime, vidtime;
int dispontime, dispofftime;
int64_t vidtime;
int firstline, lastline;
} pcjr_t;

View File

@@ -1,5 +1,6 @@
/*Generic SVGA handling*/
/*This is intended to be used by another SVGA driver, and not as a card in it's own right*/
#include <stdio.h>
#include <stdlib.h>
#include "ibm.h"
#include "mem.h"
@@ -29,6 +30,8 @@ static int old_overscan_color = 0;
static int sense_switches = 0xE;
svga_t *svga_pointer;
svga_t *svga_get_pri()
{
return svga_pri;
@@ -204,6 +207,7 @@ void svga_out(uint16_t addr, uint8_t val, void *p)
break;
case 6:
// pclog("svga_out recalcmapping %p\n", svga);
svga->oddeven_chain = (val & 2) ? 1 : 0;
if ((svga->gdcreg[6] & 0xc) != (val & 0xc))
{
// pclog("Write mapping %02X\n", val);
@@ -781,6 +785,8 @@ int svga_init(svga_t *svga, void *p, int memsize,
svga_pri = svga;
svga->ramdac_type = RAMDAC_6BIT;
svga_pointer = svga;
return 0;
}
@@ -826,11 +832,17 @@ void svga_write(uint32_t addr, uint8_t val, void *p)
else if (svga->chain2_write)
{
/* Redone because the original code caused problems when using Windows 3.1 EGA driver on (S)VGA card. */
plane = (svga->readplane & 2) | (addr & 1);
if (svga->oddeven_chain)
plane = (addr & 1) | (svga->oddeven_page ? 2 : 0);
else
plane = (svga->oddeven_page ? 2 : 0);
mask = (1 << plane);
if (svga->seqregs[2] & mask)
{
addr = ((addr & ~1) << 2) | plane | (svga->oddeven_page ? 0x10000 : 0);
if (svga->oddeven_chain)
addr = ((addr & ~1) << 2) | plane;
else
addr = (addr << 2) | plane;
if ((!svga->extvram) && (addr >= 0x10000)) return;
if (addr >= svga->vram_limit) return;
if ((raddr <= 0xA0000) || (raddr >= 0xBFFFF)) return;
@@ -1030,8 +1042,17 @@ uint8_t svga_read(uint32_t addr, void *p)
else if (svga->chain2_read)
{
/* Redone because the original code caused problems when using Windows 3.1 EGA driver on (S)VGA card. */
plane = (svga->readplane & 2) | (addr & 1);
addr = ((addr & ~1) << 2) | plane | (svga->oddeven_page ? 0x10000 : 0);
if (svga->oddeven_chain)
{
plane = (addr & 1) | (svga->oddeven_page ? 2 : 0);
addr = ((addr & ~1) << 2) | plane;
}
else
{
plane = (svga->oddeven_page ? 2 : 0);
addr = (addr << 2) | plane;
}
latch_addr = (addr << 2) & 0x7fffff;
if ((!svga->extvram) && (addr >= 0x10000)) return 0xff;
if (addr >= svga->vram_limit) return 0xff;
@@ -1085,6 +1106,8 @@ void svga_write_linear(uint32_t addr, uint8_t val, void *p)
uint32_t raddr = addr;
int plane, mask;
return;
if (!svga->enablevram) return;
cycles -= video_timing_b;
@@ -1103,11 +1126,17 @@ void svga_write_linear(uint32_t addr, uint8_t val, void *p)
else if (svga->chain2_write)
{
/* Redone because the original code caused problems when using Windows 3.1 EGA driver on (S)VGA card. */
plane = (svga->readplane & 2) | (addr & 1);
if (svga->oddeven_chain)
plane = (addr & 1) | (svga->oddeven_page ? 2 : 0);
else
plane = (svga->oddeven_page ? 2 : 0);
mask = (1 << plane);
if (svga->seqregs[2] & mask)
{
addr = ((addr & ~1) << 2) | plane | (svga->oddeven_page ? 0x10000 : 0);
if (svga->oddeven_chain)
addr = ((addr & ~1) << 2) | plane;
else
addr = (addr << 2) | plane;
addr &= 0x7fffff;
if ((!svga->extvram) && (addr >= 0x10000)) return;
if (addr >= svga->vram_limit) return;
@@ -1280,6 +1309,8 @@ uint8_t svga_read_linear(uint32_t addr, void *p)
int readplane = svga->readplane;
int plane;
return 0xff;
if (!svga->enablevram) return 0xff;
cycles -= video_timing_b;
@@ -1297,8 +1328,17 @@ uint8_t svga_read_linear(uint32_t addr, void *p)
else if (svga->chain2_read)
{
/* Redone because the original code caused problems when using Windows 3.1 EGA driver on (S)VGA card. */
plane = (svga->readplane & 2) | (addr & 1);
addr = ((addr & ~1) << 2) | plane | (svga->oddeven_page ? 0x10000 : 0);
if (svga->oddeven_chain)
{
plane = (addr & 1) | (svga->oddeven_page ? 2 : 0);
addr = ((addr & ~1) << 2) | plane;
}
else
{
plane = (svga->oddeven_page ? 2 : 0);
addr = (addr << 2) | plane;
}
addr &= 0x7fffff;
if ((!svga->extvram) && (addr >= 0x10000)) return 0xff;
if (addr >= svga->vram_limit) return 0xff;
@@ -1513,6 +1553,28 @@ uint32_t svga_readl(uint32_t addr, void *p)
return *(uint32_t *)&svga->vram[addr];
}
#if 0
void svga_write_linear(uint32_t addr, uint8_t val, void *p)
{
svga_t *svga = (svga_t *)p;
if (!svga->enablevram) return;
egawrites += 2;
cycles -= video_timing_w;
cycles_lost += video_timing_w;
if (svga_output) pclog("Write LFBw %08X %04X\n", addr, val);
addr &= 0x7FFFFF;
if ((!svga->extvram) && (addr >= 0x10000)) return;
if (addr >= svga->vram_limit)
return;
svga->changedvram[addr >> 12] = changeframecount;
*(uint8_t *)&svga->vram[addr] = val;
}
#endif
void svga_writew_linear(uint32_t addr, uint16_t val, void *p)
{
svga_t *svga = (svga_t *)p;
@@ -1569,6 +1631,26 @@ void svga_writel_linear(uint32_t addr, uint32_t val, void *p)
*(uint32_t *)&svga->vram[addr] = val;
}
#if 0
uint8_t svga_read_linear(uint32_t addr, void *p)
{
svga_t *svga = (svga_t *)p;
if (!svga->enablevram) return 0xff;
egareads += 2;
cycles -= video_timing_w;
cycles_lost += video_timing_w;
addr &= 0x7FFFFF;
if ((!svga->extvram) && (addr >= 0x10000)) return 0xff;
if (addr >= svga->vram_limit) return 0xff;
return *(uint8_t *)&svga->vram[addr];
}
#endif
uint16_t svga_readw_linear(uint32_t addr, void *p)
{
svga_t *svga = (svga_t *)p;
@@ -1618,6 +1700,7 @@ void svga_add_status_info(char *s, int max_len, void *p)
char temps[128];
if (svga->chain4) strcpy(temps, "SVGA chained (possibly mode 13h)\n");
else if ((svga->chain2_read) || (svga->chain2_write)) sprintf(temps, "SVGA chained odd/even (r: %s, w: %s)\n", svga->chain2_read ? "ON" : "OFF", svga->chain2_write ? "ON" : "OFF");
else strcpy(temps, "SVGA unchained (possibly mode-X)\n");
strncat(s, temps, max_len);
@@ -1628,7 +1711,21 @@ void svga_add_status_info(char *s, int max_len, void *p)
sprintf(temps, "SVGA resolution : %i x %i\n", svga->video_res_x, svga->video_res_y);
strncat(s, temps, max_len);
sprintf(temps, "SVGA refresh rate : %i Hz\n\n", svga->frames);
sprintf(temps, "SVGA refresh rate : %i Hz (%s)\n\n", svga->frames, svga->interlace ? "i" : "p");
svga->frames = 0;
strncat(s, temps, max_len);
sprintf(temps, "SVGA DAC in %i-bit mode\n", (svga->attrregs[0x10] & 0x80) ? 8 : 6);
strncat(s, temps, max_len);
}
void svga_dump_vram()
{
FILE *f;
f = fopen("svga_ram.dmp", "wb");
fwrite(svga_pointer->vram, svga_pointer->vrammask + 1, 1, f);
fclose(f);
f = fopen("svga_pal.dmp", "wb");
fwrite(svga_pointer->pallook, 256, 1, f);
fclose(f);
}

View File

@@ -33,7 +33,7 @@ typedef struct svga_t
uint8_t colourcompare, colournocare;
int readmode, writemode, readplane;
int chain4, chain2_write, chain2_read;
int oddeven_page;
int oddeven_page, oddeven_chain;
int enablevram, extvram;
uint8_t writemask;
uint32_t charseta, charsetb;
@@ -53,7 +53,7 @@ typedef struct svga_t
int bpp;
int dispontime, dispofftime;
int vidtime;
int64_t vidtime;
uint8_t scrblank;

View File

@@ -37,7 +37,6 @@ void svga_render_blank(svga_t *svga)
void svga_render_text_40(svga_t *svga)
{
uint32_t addr_ex = 0;
int y_add = (enable_overscan) ? 16 : 0;
int x_add = y_add >> 1;
@@ -58,9 +57,8 @@ void svga_render_text_40(svga_t *svga)
for (x = 0; x < svga->hdisp; x += xinc)
{
drawcursor = ((svga->ma == svga->ca) && svga->con && svga->cursoron);
if (svga->oddeven_page) addr_ex |= 0x10000;
chr = svga->vram[(svga->ma << 1) | addr_ex];
attr = svga->vram[((svga->ma << 1) + 1) | addr_ex];
chr = svga->vram[svga->ma << 1];
attr = svga->vram[(svga->ma << 1) + 1];
if (attr & 8) charaddr = svga->charsetb + (chr * 128);
else charaddr = svga->charseta + (chr * 128);
@@ -105,7 +103,6 @@ void svga_render_text_40(svga_t *svga)
void svga_render_text_80(svga_t *svga)
{
uint32_t addr_ex = 0;
FILE *f;
int y_add = (enable_overscan) ? 16 : 0;
int x_add = y_add >> 1;
@@ -127,9 +124,8 @@ void svga_render_text_80(svga_t *svga)
for (x = 0; x < svga->hdisp; x += xinc)
{
drawcursor = ((svga->ma == svga->ca) && svga->con && svga->cursoron);
if (svga->oddeven_page) addr_ex |= 0x10000;
chr = svga->vram[(svga->ma << 1) | addr_ex];
attr = svga->vram[((svga->ma << 1) + 1) | addr_ex];
chr = svga->vram[svga->ma << 1];
attr = svga->vram[(svga->ma << 1) + 1];
if (attr & 8) charaddr = svga->charsetb + (chr * 128);
else charaddr = svga->charseta + (chr * 128);

View File

@@ -35,7 +35,8 @@ typedef struct tandy_t
int vsynctime, vadj;
uint16_t ma, maback;
int dispontime, dispofftime, vidtime;
int dispontime, dispofftime;
int64_t vidtime;
int firstline, lastline;
} tandy_t;

View File

@@ -35,7 +35,8 @@ typedef struct tandysl_t
int vsynctime, vadj;
uint16_t ma, maback;
int dispontime, dispofftime, vidtime;
int dispontime, dispofftime;
int64_t vidtime;
int firstline, lastline;
} tandysl_t;

View File

@@ -198,7 +198,7 @@ typedef struct voodoo_t
int swap_count;
int disp_buffer;
int timer_count;
int64_t timer_count;
int line;
svga_t *svga;

View File

@@ -92,7 +92,7 @@ static BOOL CALLBACK config_dlgproc(HWND hdlg, UINT message, WPARAM wParam, LPAR
h = GetDlgItem(hdlg, IDC_COMBOCPUM);
c = 0;
while (models[romstomodel[romset]].cpu[c].cpus != NULL && c < 3)
while (models[romstomodel[romset]].cpu[c].cpus != NULL && c < 4)
{
SendMessage(h, CB_ADDSTRING, 0, (LPARAM)(LPCSTR)models[romstomodel[romset]].cpu[c].name);
c++;