mirror of
https://github.com/86Box/86Box.git
synced 2026-02-22 01:25:33 -07:00
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:
@@ -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))\
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
16
src/cpu.c
16
src/cpu.c
@@ -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},
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
155
src/disc.c
155
src/disc.c
@@ -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)
|
||||
|
||||
14
src/disc.h
14
src/disc.h
@@ -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
|
||||
|
||||
392
src/disc_fdi.c
392
src/disc_fdi.c
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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
298
src/fdc.c
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
127
src/fdd.c
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
@@ -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;
|
||||
|
||||
12
src/ibm.h
12
src/ibm.h
@@ -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
|
||||
|
||||
@@ -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];
|
||||
|
||||
|
||||
@@ -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];
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
#include <stdint.h>
|
||||
#include "ibm.h"
|
||||
#include "io.h"
|
||||
#include "mem.h"
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
#include <stdint.h>
|
||||
|
||||
#include "ibm.h"
|
||||
#include "io.h"
|
||||
#include "mem.h"
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
#include <stdint.h>
|
||||
|
||||
#include "ibm.h"
|
||||
#include "io.h"
|
||||
#include "mem.h"
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
#include <stdint.h>
|
||||
|
||||
#include "ibm.h"
|
||||
#include "device.h"
|
||||
#include "io.h"
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
#include <stdint.h>
|
||||
|
||||
#include "ibm.h"
|
||||
#include "io.h"
|
||||
#include "mem.h"
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
extern void (*mouse_poll)(int x, int y, int b);
|
||||
|
||||
extern int mousepos;
|
||||
extern int mousedelay;
|
||||
extern int64_t mousedelay;
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
79
src/nvr.c
79
src/nvr.c
@@ -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);
|
||||
}
|
||||
|
||||
2
src/pc.c
2
src/pc.c
@@ -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;
|
||||
|
||||
46
src/pit.c
46
src/pit.c
@@ -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();
|
||||
|
||||
@@ -16,7 +16,7 @@ enum
|
||||
SERIAL serial1, serial2;
|
||||
|
||||
int mousepos=-1;
|
||||
int mousedelay;
|
||||
int64_t mousedelay;
|
||||
|
||||
void serial_reset()
|
||||
{
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
{
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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];
|
||||
|
||||
@@ -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];
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
12
src/timer.c
12
src/timer.c
@@ -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)
|
||||
{
|
||||
|
||||
22
src/timer.h
22
src/timer.h
@@ -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;
|
||||
|
||||
|
||||
@@ -18,7 +18,7 @@ typedef struct cga_t
|
||||
int oddeven;
|
||||
|
||||
int dispontime, dispofftime;
|
||||
int vidtime;
|
||||
int64_t vidtime;
|
||||
|
||||
int firstline, lastline;
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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];
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@ typedef struct hercules_t
|
||||
uint8_t ctrl, ctrl2, stat;
|
||||
|
||||
int dispontime, dispofftime;
|
||||
int vidtime;
|
||||
int64_t vidtime;
|
||||
|
||||
int firstline, lastline;
|
||||
|
||||
|
||||
@@ -148,7 +148,7 @@ typedef struct incolor_t
|
||||
uint8_t ctrl, ctrl2, stat;
|
||||
|
||||
int dispontime, dispofftime;
|
||||
int vidtime;
|
||||
int64_t vidtime;
|
||||
|
||||
int firstline, lastline;
|
||||
|
||||
|
||||
@@ -18,7 +18,7 @@ typedef struct mda_t
|
||||
uint8_t ctrl, stat;
|
||||
|
||||
int dispontime, dispofftime;
|
||||
int vidtime;
|
||||
int64_t vidtime;
|
||||
|
||||
int firstline, lastline;
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
115
src/vid_svga.c
115
src/vid_svga.c
@@ -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);
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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++;
|
||||
|
||||
Reference in New Issue
Block a user