Rewritten parts of the 86F handler to minimize false CRC errors and misidentification of sectors;
Replaced IMG handler with one that now proxies to the 86F handler; Applies the remaining Mainline PCem speedup commit; Fixed the National Semiconductors PC87306 Super I/O Chip's serial port IRQ assignment; DMF images are now loaded with the correct sector interleave, improving read/write speed; XDF images are now loaded in a way that emulates the real order of the sectors on the track, improving read/write speed; Added 16-bit physical memory read/write routines (mem_phys_readw, mem_phys_writew) and modified the 16-bit DMA code to use them instead of two 8-bit reads/writes.
This commit is contained in:
parent
0ae428b5f5
commit
6318e2bb17
@ -5,7 +5,7 @@ WINDRES = windres.exe
|
||||
CFLAGS = -O3 -march=native -mtune=native -fbranch-probabilities -fvpt -funroll-loops -fpeel-loops -ftracer -fomit-frame-pointer -ffast-math -msse -msse2 -msse3 -mssse3 -mfpmath=sse -mstackrealign
|
||||
OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o acerm3a.o ali1429.o amstrad.o cdrom-ioctl.o cdrom-iso.o \
|
||||
cdrom-null.o codegen.o codegen_ops.o codegen_timing_486.o codegen_timing_686.o codegen_timing_pentium.o codegen_timing_winchip.o codegen_x86.o compaq.o config.o cpu.o dac.o \
|
||||
device.o disc.o disc_86f.o disc_fdi.o disc_img.o disc_random.o disc_sector_86box.o dma.o fdc.o fdc37c665.o fdc37c932fr.o fdd.o fdi2raw.o gameport.o headland.o i430hx.o i430lx.o i430fx.o \
|
||||
device.o disc.o disc_86f.o disc_fdi.o disc_img_86box.o disc_random.o dma.o fdc.o fdc37c665.o fdc37c932fr.o fdd.o fdi2raw.o gameport.o headland.o i430hx.o i430lx.o i430fx.o \
|
||||
i430nx.o i430vx.o i440fx.o ide.o intel.o intel_flash.o io.o jim.o joystick_ch_flightstick_pro.o joystick_standard.o joystick_sw_pad.o joystick_tm_fcs.o keyboard.o keyboard_amstrad.o keyboard_at.o \
|
||||
keyboard_olim24.o keyboard_pcjr.o keyboard_xt.o lpt.o mcr.o mem.o memregs.o model.o mouse.o mouse_ps2.o \
|
||||
mouse_serial.o ne2000.o neat.o nethandler.o nmi.o nvr.o olivetti_m24.o opti.o pc.o pc87306.o pci.o pic.o piix.o pit.o ppi.o ps1.o rom.o rtc.o \
|
||||
|
@ -5,7 +5,7 @@ WINDRES = windres.exe
|
||||
CFLAGS = -O3 -march=native -mtune=native -fbranch-probabilities -fvpt -funroll-loops -fpeel-loops -ftracer -fomit-frame-pointer -ffast-math -msse -msse2 -msse3 -mssse3 -mfpmath=sse -mstackrealign
|
||||
OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o acerm3a.o ali1429.o amstrad.o cdrom-ioctl.o cdrom-iso.o \
|
||||
cdrom-null.o codegen.o codegen_ops.o codegen_timing_486.o codegen_timing_686.o codegen_timing_pentium.o codegen_timing_winchip.o codegen_x86-64.o compaq.o config.o cpu.o dac.o \
|
||||
device.o disc.o disc_86f.o disc_fdi.o disc_img.o disc_random.o disc_sector_86box.o dma.o fdc.o fdc37c665.o fdc37c932fr.o fdd.o fdi2raw.o gameport.o headland.o i430hx.o i430lx.o i430fx.o \
|
||||
device.o disc.o disc_86f.o disc_fdi.o disc_img_86box.o disc_random.o dma.o fdc.o fdc37c665.o fdc37c932fr.o fdd.o fdi2raw.o gameport.o headland.o i430hx.o i430lx.o i430fx.o \
|
||||
i430nx.o i430vx.o i440fx.o ide.o intel.o intel_flash.o io.o jim.o joystick_ch_flightstick_pro.o joystick_standard.o joystick_sw_pad.o joystick_tm_fcs.o keyboard.o keyboard_amstrad.o keyboard_at.o \
|
||||
keyboard_olim24.o keyboard_pcjr.o keyboard_xt.o lpt.o mcr.o mem.o memregs.o model.o mouse.o mouse_ps2.o \
|
||||
mouse_serial.o ne2000.o neat.o nethandler.o nmi.o nvr.o olivetti_m24.o opti.o pc.o pc87306.o pci.o pic.o piix.o pit.o ppi.o ps1.o rom.o rtc.o \
|
||||
|
@ -580,6 +580,7 @@ static uint32_t ropFLDCW(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint
|
||||
|
||||
MEM_LOAD_ADDR_EA_W(target_seg);
|
||||
STORE_HOST_REG_ADDR_W((uintptr_t)&cpu_state.npxc, 0);
|
||||
UPDATE_NPXC(0);
|
||||
|
||||
return op_pc + 1;
|
||||
}
|
||||
|
@ -4556,6 +4556,10 @@ static void FP_COMPARE_IL()
|
||||
FP_COMPARE_MEM();
|
||||
}
|
||||
|
||||
static void UPDATE_NPXC(int reg)
|
||||
{
|
||||
}
|
||||
|
||||
static void SET_BITS(uintptr_t addr, uint32_t val)
|
||||
{
|
||||
if (IS_32_ADDR(addr))
|
||||
|
@ -2173,82 +2173,6 @@ static void FP_LOAD_REG_D(int reg, int *host_reg1, int *host_reg2)
|
||||
*host_reg2 = REG_ECX;
|
||||
}
|
||||
|
||||
|
||||
static double _fp_half = 0.5;
|
||||
|
||||
static void FP_LOAD_ROUNDING()
|
||||
{
|
||||
pclog("cpu_state.npxc %04x\n", cpu_state.npxc);
|
||||
addbyte(0x8b); /*MOV EDX, npxc*/
|
||||
addbyte(0x15);
|
||||
addlong((uintptr_t)&cpu_state.npxc);
|
||||
addbyte(0xd9); /*FSTCW [ESP+8]*/
|
||||
addbyte(0x7c);
|
||||
addbyte(0x24);
|
||||
addbyte(0x08);
|
||||
addbyte(0x89); /*MOV [ESP+12],EDX*/
|
||||
addbyte(0x54);
|
||||
addbyte(0x24);
|
||||
addbyte(0x0c);
|
||||
addbyte(0xd9); /*FLDCW [ESP+12]*/
|
||||
addbyte(0x6c);
|
||||
addbyte(0x24);
|
||||
addbyte(0x0c);
|
||||
}
|
||||
static void FP_RESTORE_ROUNDING()
|
||||
{
|
||||
addbyte(0xd9); /*FLDCW [ESP+8]*/
|
||||
addbyte(0x6c);
|
||||
addbyte(0x24);
|
||||
addbyte(0x08);
|
||||
}
|
||||
|
||||
static int32_t x87_fround32(double b)
|
||||
{
|
||||
int64_t a, c;
|
||||
|
||||
switch ((cpu_state.npxc >> 10) & 3)
|
||||
{
|
||||
case 0: /*Nearest*/
|
||||
a = (int64_t)floor(b);
|
||||
c = (int64_t)floor(b + 1.0);
|
||||
if ((b - a) < (c - b))
|
||||
return a;
|
||||
else if ((b - a) > (c - b))
|
||||
return c;
|
||||
else
|
||||
return (a & 1) ? c : a;
|
||||
case 1: /*Down*/
|
||||
return (int32_t)floor(b);
|
||||
case 2: /*Up*/
|
||||
return (int32_t)ceil(b);
|
||||
case 3: /*Chop*/
|
||||
return (int32_t)b;
|
||||
}
|
||||
}
|
||||
static int64_t x87_fround64(double b)
|
||||
{
|
||||
int64_t a, c;
|
||||
|
||||
switch ((cpu_state.npxc >> 10) & 3)
|
||||
{
|
||||
case 0: /*Nearest*/
|
||||
a = (int64_t)floor(b);
|
||||
c = (int64_t)floor(b + 1.0);
|
||||
if ((b - a) < (c - b))
|
||||
return a;
|
||||
else if ((b - a) > (c - b))
|
||||
return c;
|
||||
else
|
||||
return (a & 1) ? c : a;
|
||||
case 1: /*Down*/
|
||||
return (int64_t)floor(b);
|
||||
case 2: /*Up*/
|
||||
return (int64_t)ceil(b);
|
||||
case 3: /*Chop*/
|
||||
return (int64_t)b;
|
||||
}
|
||||
}
|
||||
static int FP_LOAD_REG_INT_W(int reg)
|
||||
{
|
||||
addbyte(0x8b); /*MOV EBX, TOP*/
|
||||
@ -2268,25 +2192,19 @@ static int FP_LOAD_REG_INT_W(int reg)
|
||||
addbyte(0xdd);
|
||||
addbyte(cpu_state_offset(ST));
|
||||
|
||||
addbyte(0x89); /*MOV [ESP+8], EAX*/
|
||||
addbyte(0x44);
|
||||
addbyte(0xd9); /*FLDCW cpu_state.new_npxc*/
|
||||
addbyte(0x6d);
|
||||
addbyte(cpu_state_offset(new_npxc));
|
||||
addbyte(0xdb); /*FISTP [ESP]*/
|
||||
addbyte(0x1c);
|
||||
addbyte(0x24);
|
||||
addbyte(0x08);
|
||||
|
||||
addbyte(0xdd); /*FSTP [ESP]*/
|
||||
addbyte(0xd9); /*FLDCW cpu_state.old_npxc*/
|
||||
addbyte(0x6d);
|
||||
addbyte(cpu_state_offset(old_npxc));
|
||||
addbyte(0x8b); /*MOV EBX, [ESP]*/
|
||||
addbyte(0x1c);
|
||||
addbyte(0x24);
|
||||
|
||||
CALL_FUNC(x87_fround32);
|
||||
|
||||
addbyte(0x89); /*MOV EBX, EAX*/
|
||||
addbyte(0xc3);
|
||||
|
||||
addbyte(0x8b); /*MOV EAX, [ESP+8]*/
|
||||
addbyte(0x44);
|
||||
addbyte(0x24);
|
||||
addbyte(0x08);
|
||||
|
||||
return REG_EBX;
|
||||
}
|
||||
static int FP_LOAD_REG_INT(int reg)
|
||||
@ -2308,25 +2226,19 @@ static int FP_LOAD_REG_INT(int reg)
|
||||
addbyte(0xdd);
|
||||
addbyte(cpu_state_offset(ST));
|
||||
|
||||
addbyte(0x89); /*MOV [ESP+8], EAX*/
|
||||
addbyte(0x44);
|
||||
addbyte(0xd9); /*FLDCW cpu_state.new_npxc*/
|
||||
addbyte(0x6d);
|
||||
addbyte(cpu_state_offset(new_npxc));
|
||||
addbyte(0xdb); /*FISTP [ESP]*/
|
||||
addbyte(0x1c);
|
||||
addbyte(0x24);
|
||||
addbyte(0x08);
|
||||
|
||||
addbyte(0xdd); /*FSTP [ESP]*/
|
||||
addbyte(0xd9); /*FLDCW cpu_state.old_npxc*/
|
||||
addbyte(0x6d);
|
||||
addbyte(cpu_state_offset(old_npxc));
|
||||
addbyte(0x8b); /*MOV EBX, [ESP]*/
|
||||
addbyte(0x1c);
|
||||
addbyte(0x24);
|
||||
|
||||
CALL_FUNC(x87_fround32);
|
||||
|
||||
addbyte(0x89); /*MOV EBX, EAX*/
|
||||
addbyte(0xc3);
|
||||
|
||||
addbyte(0x8b); /*MOV EAX, [ESP+8]*/
|
||||
addbyte(0x44);
|
||||
addbyte(0x24);
|
||||
addbyte(0x08);
|
||||
|
||||
return REG_EBX;
|
||||
}
|
||||
static void FP_LOAD_REG_INT_Q(int reg, int *host_reg1, int *host_reg2)
|
||||
@ -2378,34 +2290,29 @@ static void FP_LOAD_REG_INT_Q(int reg, int *host_reg1, int *host_reg2)
|
||||
addbyte(cpu_state_offset(MM));
|
||||
|
||||
addbyte(0xeb); /*JMP done*/
|
||||
addbyte(4+4+3+5+2+2+4);
|
||||
addbyte(4+3+3+3+3+4);
|
||||
|
||||
addbyte(0xdd); /*FLD ST[EBX*8]*/
|
||||
addbyte(0x44);
|
||||
addbyte(0xdd);
|
||||
addbyte(cpu_state_offset(ST));
|
||||
|
||||
addbyte(0x89); /*MOV [ESP+8], EAX*/
|
||||
addbyte(0x44);
|
||||
addbyte(0xd9); /*FLDCW cpu_state.new_npxc*/
|
||||
addbyte(0x6d);
|
||||
addbyte(cpu_state_offset(new_npxc));
|
||||
addbyte(0xdf); /*FISTPQ [ESP]*/
|
||||
addbyte(0x3c);
|
||||
addbyte(0x24);
|
||||
addbyte(0x08);
|
||||
|
||||
addbyte(0xdd); /*FSTP [ESP]*/
|
||||
addbyte(0xd9); /*FLDCW cpu_state.old_npxc*/
|
||||
addbyte(0x6d);
|
||||
addbyte(cpu_state_offset(old_npxc));
|
||||
addbyte(0x8b); /*MOV EBX, [ESP]*/
|
||||
addbyte(0x1c);
|
||||
addbyte(0x24);
|
||||
|
||||
CALL_FUNC(x87_fround64);
|
||||
|
||||
addbyte(0x89); /*MOV EBX, EAX*/
|
||||
addbyte(0xc3);
|
||||
|
||||
addbyte(0x89); /*MOV ECX, EDX*/
|
||||
addbyte(0xd1);
|
||||
|
||||
addbyte(0x8b); /*MOV EAX, [ESP+8]*/
|
||||
addbyte(0x44);
|
||||
addbyte(0x8b); /*MOV ECX, 4[ESP]*/
|
||||
addbyte(0x4c);
|
||||
addbyte(0x24);
|
||||
addbyte(0x08);
|
||||
addbyte(4);
|
||||
|
||||
*host_reg1 = REG_EBX;
|
||||
*host_reg2 = REG_ECX;
|
||||
@ -2511,31 +2418,9 @@ static void FP_OP_D(int op)
|
||||
addbyte(0x04);
|
||||
if (((cpu_state.npxc >> 10) & 3) && op == FPU_ADD)
|
||||
{
|
||||
addbyte(0x9b); /*FSTCW [ESP+8]*/
|
||||
addbyte(0xd9);
|
||||
addbyte(0x7c);
|
||||
addbyte(0x24);
|
||||
addbyte(0x08);
|
||||
addbyte(0x66); /*MOV AX, [ESP+8]*/
|
||||
addbyte(0x8b);
|
||||
addbyte(0x44);
|
||||
addbyte(0x24);
|
||||
addbyte(0x08);
|
||||
addbyte(0x66); /*AND AX, ~(3 << 10)*/
|
||||
addbyte(0x25);
|
||||
addword(~(3 << 10));
|
||||
addbyte(0x66); /*OR AX, npxc & (3 << 10)*/
|
||||
addbyte(0x0d);
|
||||
addword(cpu_state.npxc & (3 << 10));
|
||||
addbyte(0x66); /*MOV [ESP+12], AX*/
|
||||
addbyte(0x89);
|
||||
addbyte(0x44);
|
||||
addbyte(0x24);
|
||||
addbyte(0x0c);
|
||||
addbyte(0xd9); /*FLDCW [ESP+12]*/
|
||||
addbyte(0x6c);
|
||||
addbyte(0x24);
|
||||
addbyte(0x0c);
|
||||
addbyte(0xd9); /*FLDCW cpu_state.new_npxc*/
|
||||
addbyte(0x6d);
|
||||
addbyte(cpu_state_offset(new_npxc));
|
||||
}
|
||||
addbyte(0xdd); /*FLD ST[dst][EBP]*/
|
||||
addbyte(0x45);
|
||||
@ -2552,10 +2437,9 @@ static void FP_OP_D(int op)
|
||||
addbyte(cpu_state_offset(ST[cpu_state.TOP]));
|
||||
if (((cpu_state.npxc >> 10) & 3) && op == FPU_ADD)
|
||||
{
|
||||
addbyte(0xd9); /*FLDCW [ESP+8]*/
|
||||
addbyte(0x6c);
|
||||
addbyte(0x24);
|
||||
addbyte(0x08);
|
||||
addbyte(0xd9); /*FLDCW cpu_state.old_npxc*/
|
||||
addbyte(0x6d);
|
||||
addbyte(cpu_state_offset(old_npxc));
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -2568,31 +2452,9 @@ static void FP_OP_D(int op)
|
||||
addbyte(0x24);
|
||||
if (((cpu_state.npxc >> 10) & 3) && op == FPU_ADD)
|
||||
{
|
||||
addbyte(0x9b); /*FSTCW [ESP+8]*/
|
||||
addbyte(0xd9);
|
||||
addbyte(0x7c);
|
||||
addbyte(0x24);
|
||||
addbyte(0x08);
|
||||
addbyte(0x66); /*MOV AX, [ESP+8]*/
|
||||
addbyte(0x8b);
|
||||
addbyte(0x44);
|
||||
addbyte(0x24);
|
||||
addbyte(0x08);
|
||||
addbyte(0x66); /*AND AX, ~(3 << 10)*/
|
||||
addbyte(0x25);
|
||||
addword(~(3 << 10));
|
||||
addbyte(0x66); /*OR AX, npxc & (3 << 10)*/
|
||||
addbyte(0x0d);
|
||||
addword(cpu_state.npxc & (3 << 10));
|
||||
addbyte(0x66); /*MOV [ESP+12], AX*/
|
||||
addbyte(0x89);
|
||||
addbyte(0x44);
|
||||
addbyte(0x24);
|
||||
addbyte(0x0c);
|
||||
addbyte(0xd9); /*FLDCW [ESP+12]*/
|
||||
addbyte(0x6c);
|
||||
addbyte(0x24);
|
||||
addbyte(0x0c);
|
||||
addbyte(0xd9); /*FLDCW cpu_state.new_npxc*/
|
||||
addbyte(0x6d);
|
||||
addbyte(cpu_state_offset(new_npxc));
|
||||
}
|
||||
addbyte(0x89); /*MOV [ESP+4], EDX*/
|
||||
addbyte(0x54);
|
||||
@ -2616,10 +2478,9 @@ static void FP_OP_D(int op)
|
||||
addbyte(cpu_state_offset(ST));
|
||||
if (((cpu_state.npxc >> 10) & 3) && op == FPU_ADD)
|
||||
{
|
||||
addbyte(0xd9); /*FLDCW [ESP+8]*/
|
||||
addbyte(0x6c);
|
||||
addbyte(0x24);
|
||||
addbyte(0x08);
|
||||
addbyte(0xd9); /*FLDCW cpu_state.old_npxc*/
|
||||
addbyte(0x6d);
|
||||
addbyte(cpu_state_offset(old_npxc));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -3226,6 +3087,32 @@ static void FP_COMPARE_REG(int dst, int src)
|
||||
}
|
||||
}
|
||||
|
||||
static void UPDATE_NPXC(int reg)
|
||||
{
|
||||
addbyte(0x66); /*AND cpu_state.new_npxc, ~0xc00*/
|
||||
addbyte(0x81);
|
||||
addbyte(0x65);
|
||||
addbyte(cpu_state_offset(new_npxc));
|
||||
addword(~0xc00);
|
||||
if (reg)
|
||||
{
|
||||
addbyte(0x66); /*AND reg, 0xc00*/
|
||||
addbyte(0x81);
|
||||
addbyte(0xe0 | reg);
|
||||
addword(0xc00);
|
||||
}
|
||||
else
|
||||
{
|
||||
addbyte(0x66); /*AND AX, 0xc00*/
|
||||
addbyte(0x25);
|
||||
addword(0xc00);
|
||||
}
|
||||
addbyte(0x66); /*OR cpu_state.new_npxc, reg*/
|
||||
addbyte(0x09);
|
||||
addbyte(0x45 | (reg << 3));
|
||||
addbyte(cpu_state_offset(new_npxc));
|
||||
}
|
||||
|
||||
static int ZERO_EXTEND_W_B(int reg)
|
||||
{
|
||||
addbyte(0x0f); /*MOVZX regl, regb*/
|
||||
|
@ -563,6 +563,11 @@ void codegen_init()
|
||||
mem_store_addr_ea_b = gen_MEM_STORE_ADDR_EA_B();
|
||||
block_pos = 1024;
|
||||
mem_store_addr_ea_q = gen_MEM_STORE_ADDR_EA_Q();
|
||||
|
||||
asm(
|
||||
"fstcw %0\n"
|
||||
: "=m" (cpu_state.old_npxc)
|
||||
);
|
||||
}
|
||||
|
||||
void codegen_reset()
|
||||
|
@ -91,7 +91,7 @@ void disc_load(int drive, char *fn)
|
||||
p = get_extension(fn);
|
||||
if (!p) return;
|
||||
// setejecttext(drive, fn);
|
||||
pclog("Loading :%i %s %s\n", drive, fn,p);
|
||||
// pclog("Loading :%i %s %s\n", drive, fn,p);
|
||||
f = fopen(fn, "rb");
|
||||
if (!f) return;
|
||||
fseek(f, -1, SEEK_END);
|
||||
@ -101,7 +101,7 @@ void disc_load(int drive, char *fn)
|
||||
{
|
||||
if (!strcasecmp(p, loaders[c].ext) && (size == loaders[c].size || loaders[c].size == -1))
|
||||
{
|
||||
pclog("Loading as %s\n", p);
|
||||
// pclog("Loading as %s (UI write protected = %s)\n", p, ui_writeprot[drive] ? "yes" : "no");
|
||||
driveloaders[drive] = c;
|
||||
loaders[c].load(drive, fn);
|
||||
drive_empty[drive] = 0;
|
||||
|
31
src/disc.h
31
src/disc.h
@ -108,3 +108,34 @@ extern int drive_type[2];
|
||||
#define BYTE_TYPE_AM 0x03
|
||||
#define BYTE_TYPE_DATA 0x04
|
||||
#define BYTE_TYPE_CRC 0x05
|
||||
|
||||
typedef union {
|
||||
uint16_t word;
|
||||
uint8_t bytes[2];
|
||||
} crc_t;
|
||||
|
||||
void disc_calccrc(int drive, uint8_t byte, crc_t *crc_var);
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint8_t (*disk_flags)(int drive);
|
||||
uint8_t (*side_flags)(int drive);
|
||||
void (*writeback)(int drive);
|
||||
void (*set_sector)(int drive, int side, uint8_t c, uint8_t h, uint8_t r, uint8_t n);
|
||||
uint8_t (*read_data)(int drive, int side, uint16_t pos);
|
||||
void (*write_data)(int drive, int side, uint16_t pos, uint8_t data);
|
||||
int (*format_conditions)(int drive);
|
||||
uint8_t check_crc;
|
||||
} d86f_handler_t;
|
||||
|
||||
d86f_handler_t d86f_handler[2];
|
||||
|
||||
void d86f_common_handlers(int drive);
|
||||
|
||||
int d86f_is_40_track(int drive);
|
||||
|
||||
uint8_t* d86f_track_data(int drive, int side);
|
||||
uint8_t* d86f_track_layout(int drive, int side);
|
||||
|
||||
uint16_t d86f_prepare_pretrack(int drive, int side, int iso, int write_data);
|
||||
uint16_t d86f_prepare_sector(int drive, int side, int pos, uint8_t *id_buf, uint8_t *data_buf, int data_len, int write_data, int gap2, int gap3);
|
||||
|
990
src/disc_86f.c
990
src/disc_86f.c
File diff suppressed because it is too large
Load Diff
109
src/disc_img.c
109
src/disc_img.c
@ -23,7 +23,7 @@ static struct
|
||||
} img[2];
|
||||
|
||||
static uint8_t xdf_track0[3][3];
|
||||
static uint8_t xdf_spt[3];
|
||||
static uint8_t xdf_spt[3] = { 6, 8, 8 };
|
||||
static uint8_t xdf_map[3][24][3];
|
||||
static uint16_t xdf_track0_layout[3][92] = { { 0x8100, 0x8200, 0x8300, 0x8400, 0x8500, 0x8600, 0x8700, 0x8800,
|
||||
0x8101, 0x8201, 0x0100, 0x0200, 0x0300, 0x0400, 0x0500, 0x0600,
|
||||
@ -49,6 +49,7 @@ static uint16_t xdf_track0_layout[3][92] = { { 0x8100, 0x8200, 0x8300, 0x8400, 0
|
||||
0x9901, 0x9A01, 0x9B01, 0x9C01, 0x9D01, 0x9E01, 0x9F01, 0xA001,
|
||||
0xA101, 0xA201, 0xA301, 0xA401 },
|
||||
};
|
||||
static uint16_t xdf_sector_pos[256];
|
||||
|
||||
/* First dimension is possible sector sizes (0 = 128, 7 = 16384), second is possible bit rates (250/360, 250, 300, 500/360, 500, 1000). */
|
||||
/* Disks formatted at 250 kbps @ 360 RPM can be read with a 360 RPM single-RPM 5.25" drive by setting the rate to 250 kbps.
|
||||
@ -152,46 +153,9 @@ static void add_to_map(uint8_t *arr, uint8_t p1, uint8_t p2, uint8_t p3)
|
||||
|
||||
static int xdf_maps_initialized = 0;
|
||||
|
||||
static void initialize_xdf_maps()
|
||||
{
|
||||
// XDF 5.25" 2HD
|
||||
/* Adds, in this order: sectors per FAT, sectors per each side of track 0, difference between that and virtual sector number specified in BPB. */
|
||||
add_to_map(xdf_track0[0], 9, 17, 2);
|
||||
xdf_spt[0] = 3;
|
||||
/* Adds, in this order: side, sequential order (not used in PCem), sector size. */
|
||||
add_to_map(xdf_map[0][0], 0, 0, 3);
|
||||
add_to_map(xdf_map[0][1], 0, 2, 6);
|
||||
add_to_map(xdf_map[0][2], 1, 0, 2);
|
||||
add_to_map(xdf_map[0][3], 0, 1, 2);
|
||||
add_to_map(xdf_map[0][4], 1, 2, 6);
|
||||
add_to_map(xdf_map[0][5], 1, 1, 3);
|
||||
|
||||
// XDF 3.5" 2HD
|
||||
add_to_map(xdf_track0[1], 11, 19, 4);
|
||||
xdf_spt[1] = 4;
|
||||
add_to_map(xdf_map[1][0], 0, 0, 3);
|
||||
add_to_map(xdf_map[1][1], 0, 2, 4);
|
||||
add_to_map(xdf_map[1][2], 1, 3, 6);
|
||||
add_to_map(xdf_map[1][3], 0, 1, 2);
|
||||
add_to_map(xdf_map[1][4], 1, 1, 2);
|
||||
add_to_map(xdf_map[1][5], 0, 3, 6);
|
||||
add_to_map(xdf_map[1][6], 1, 0, 4);
|
||||
add_to_map(xdf_map[1][7], 1, 2, 3);
|
||||
|
||||
// XDF 3.5" 2ED
|
||||
add_to_map(xdf_track0[2], 22, 37, 9);
|
||||
xdf_spt[2] = 4;
|
||||
add_to_map(xdf_map[2][0], 0, 0, 3);
|
||||
add_to_map(xdf_map[2][1], 0, 1, 4);
|
||||
add_to_map(xdf_map[2][2], 0, 2, 5);
|
||||
add_to_map(xdf_map[2][3], 0, 3, 7);
|
||||
add_to_map(xdf_map[2][4], 1, 0, 3);
|
||||
add_to_map(xdf_map[2][5], 1, 1, 4);
|
||||
add_to_map(xdf_map[2][6], 1, 2, 5);
|
||||
add_to_map(xdf_map[2][7], 1, 3, 7);
|
||||
|
||||
xdf_maps_initialized = 1;
|
||||
}
|
||||
static uint16_t xdf_trackx_layout[3][8] = { { 0x8300, 0x8600, 0x8201, 0x8200, 0x8601, 0x8301},
|
||||
{ 0x8300, 0x8400, 0x8601, 0x8200, 0x8201, 0x8600, 0x8401, 0x8301},
|
||||
{ 0x8300, 0x8400, 0x8500, 0x8700, 0x8301, 0x8401, 0x8501, 0x8701} };
|
||||
|
||||
void img_load(int drive, char *fn)
|
||||
{
|
||||
@ -208,8 +172,6 @@ void img_load(int drive, char *fn)
|
||||
char ext[4];
|
||||
int fdi;
|
||||
|
||||
if (!xdf_maps_initialized) initialize_xdf_maps(); /* Initialize XDF maps, will need them to properly register sectors in tracks. */
|
||||
|
||||
ext[0] = fn[strlen(fn) - 3] | 0x60;
|
||||
ext[1] = fn[strlen(fn) - 2] | 0x60;
|
||||
ext[2] = fn[strlen(fn) - 1] | 0x60;
|
||||
@ -224,6 +186,10 @@ void img_load(int drive, char *fn)
|
||||
return;
|
||||
writeprot[drive] = 1;
|
||||
}
|
||||
if (ui_writeprot[drive])
|
||||
{
|
||||
writeprot[drive] = 1;
|
||||
}
|
||||
fwriteprot[drive] = writeprot[drive];
|
||||
|
||||
if (strcmp(ext, "fdi") == 0)
|
||||
@ -432,7 +398,6 @@ void img_load(int drive, char *fn)
|
||||
{
|
||||
case 19: /* High density XDF @ 360 rpm */
|
||||
img[drive].xdf_type = 1;
|
||||
raw_tsize[drive] = 10521; /* Rotate at 356.4 RPM in order to fit the data. */
|
||||
break;
|
||||
case 23: /* High density XDF @ 300 rpm */
|
||||
img[drive].xdf_type = 2;
|
||||
@ -495,12 +460,6 @@ void img_load(int drive, char *fn)
|
||||
img[drive].byte_period = 16;
|
||||
}
|
||||
|
||||
if (img[drive].xdf_type) /* In case of XDF-formatted image, write-protect */
|
||||
{
|
||||
writeprot[drive] = 1;
|
||||
fwriteprot[drive] = writeprot[drive];
|
||||
}
|
||||
|
||||
drives[drive].seek = img_seek;
|
||||
drives[drive].readsector = disc_sector_readsector;
|
||||
drives[drive].writesector = disc_sector_writesector;
|
||||
@ -546,9 +505,7 @@ void img_seek(int drive, int track)
|
||||
int side;
|
||||
int current_xdft = img[drive].xdf_type - 1;
|
||||
|
||||
uint8_t sectors_fat, effective_sectors, sector_gap; /* Needed for XDF */
|
||||
|
||||
int sector, current_pos, sh, sr, sside, total;
|
||||
int sector, current_pos, sh, sr, sn, sside, total, max_pos;
|
||||
|
||||
if (!img[drive].f)
|
||||
return;
|
||||
@ -579,14 +536,11 @@ void img_seek(int drive, int track)
|
||||
|
||||
if (img[drive].xdf_type)
|
||||
{
|
||||
sectors_fat = xdf_track0[current_xdft][0];
|
||||
effective_sectors = xdf_track0[current_xdft][1];
|
||||
sector_gap = xdf_track0[current_xdft][2];
|
||||
total = img[drive].sectors;
|
||||
|
||||
max_pos = (img[drive].sectors * 512);
|
||||
if (!track)
|
||||
{
|
||||
/* Track 0, register sectors according to track 0 layout. */
|
||||
total = img[drive].sectors;
|
||||
current_pos = 0;
|
||||
for (sector = 0; sector < (total << 1); sector++)
|
||||
{
|
||||
@ -596,6 +550,7 @@ void img_seek(int drive, int track)
|
||||
{
|
||||
sh = xdf_track0_layout[current_xdft][sector] & 0xFF;
|
||||
sr = xdf_track0_layout[current_xdft][sector] >> 8;
|
||||
xdf_sector_pos[(sh << 8) | sr] = current_pos;
|
||||
disc_sector_add(drive, sh, track, sh, sr, 2,
|
||||
img[drive].bitcell_period_300rpm,
|
||||
&img[drive].track_data[sside][current_pos]);
|
||||
@ -605,25 +560,19 @@ void img_seek(int drive, int track)
|
||||
else
|
||||
{
|
||||
/* Non-zero track, this will have sectors of various sizes. */
|
||||
/* First, the "Side 0" buffer. */
|
||||
total = xdf_spt[current_xdft] >> 1;
|
||||
current_pos = 0;
|
||||
for (sector = 0; sector < xdf_spt[current_xdft]; sector++)
|
||||
for (sector = 0; sector < xdf_spt[current_xdft]; sector++)
|
||||
{
|
||||
disc_sector_add(drive, xdf_map[current_xdft][sector][0], track, xdf_map[current_xdft][sector][0],
|
||||
xdf_map[current_xdft][sector][2] + 0x80, xdf_map[current_xdft][sector][2],
|
||||
img[drive].bitcell_period_300rpm,
|
||||
&img[drive].track_data[0][current_pos]);
|
||||
current_pos += (128 << xdf_map[current_xdft][sector][2]);
|
||||
}
|
||||
/* Then, the "Side 1" buffer. */
|
||||
current_pos = 0;
|
||||
for (sector = xdf_spt[current_xdft]; sector < (xdf_spt[current_xdft] << 1); sector++)
|
||||
{
|
||||
disc_sector_add(drive, xdf_map[current_xdft][sector][0], track, xdf_map[current_xdft][sector][0],
|
||||
xdf_map[current_xdft][sector][2] + 0x80, xdf_map[current_xdft][sector][2],
|
||||
img[drive].bitcell_period_300rpm,
|
||||
&img[drive].track_data[1][current_pos]);
|
||||
current_pos += (128 << xdf_map[current_xdft][sector][2]);
|
||||
sside = (sector >= total) ? 1 : 0;
|
||||
sh = xdf_trackx_layout[current_xdft][sector] & 0xFF;
|
||||
sr = xdf_trackx_layout[current_xdft][sector] >> 8;
|
||||
sn = sr & 7;
|
||||
disc_sector_add(drive, sh, track, sh, sr, sn,
|
||||
img[drive].bitcell_period_300rpm,
|
||||
&img[drive].track_data[sside][current_pos]);
|
||||
current_pos += (128 << sn);
|
||||
current_pos %= max_pos;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -648,19 +597,19 @@ void img_writeback(int drive)
|
||||
if (!img[drive].f)
|
||||
return;
|
||||
|
||||
if (img[drive].xdf_type)
|
||||
return; /*Should never happen*/
|
||||
// if (img[drive].xdf_type)
|
||||
// return; /*Should never happen*/
|
||||
|
||||
if (img[drive].sides == 2)
|
||||
{
|
||||
fseek(img[drive].f, img[drive].base + (disc_track[drive] * img[drive].sectors * img[drive].sector_size * 2), SEEK_SET);
|
||||
fseek(img[drive].f, img[drive].base + (disc_track[drive] * img[drive].sectors * img[drive].sector_size * 2), SEEK_SET);
|
||||
fwrite(img[drive].track_data[0], img[drive].sectors * img[drive].sector_size, 1, img[drive].f);
|
||||
fwrite(img[drive].track_data[1], img[drive].sectors * img[drive].sector_size, 1, img[drive].f);
|
||||
}
|
||||
else
|
||||
{
|
||||
{
|
||||
fseek(img[drive].f, img[drive].base + (disc_track[drive] * img[drive].sectors * img[drive].sector_size), SEEK_SET);
|
||||
fwrite(img[drive].track_data[0], img[drive].sectors * img[drive].sector_size, 1, img[drive].f);
|
||||
fwrite(img[drive].track_data[0], img[drive].sectors * img[drive].sector_size, 1, img[drive].f);
|
||||
}
|
||||
}
|
||||
|
||||
|
598
src/disc_img_86box.c
Normal file
598
src/disc_img_86box.c
Normal file
@ -0,0 +1,598 @@
|
||||
/* Copyright holders: Sarah Walker, Tenshi
|
||||
see COPYING for more details
|
||||
*/
|
||||
#include "ibm.h"
|
||||
#include "fdc.h"
|
||||
#include "fdd.h"
|
||||
#include "disc.h"
|
||||
#include "disc_img.h"
|
||||
#include "disc_sector.h"
|
||||
|
||||
static struct
|
||||
{
|
||||
FILE *f;
|
||||
uint8_t track_data[2][50000];
|
||||
int sectors, tracks, sides;
|
||||
uint8_t sector_size;
|
||||
int rate;
|
||||
int xdf_type; /* 0 = not XDF, 1-5 = one of the five XDF types */
|
||||
int dmf;
|
||||
int hole;
|
||||
int track;
|
||||
uint32_t base;
|
||||
uint8_t gap2_size;
|
||||
uint8_t gap3_size;
|
||||
uint8_t disk_flags;
|
||||
uint8_t track_flags;
|
||||
uint8_t sector_pos_side[2][256];
|
||||
uint16_t sector_pos[2][256];
|
||||
uint8_t current_sector_pos_side;
|
||||
uint16_t current_sector_pos;
|
||||
} img[2];
|
||||
|
||||
static uint8_t dmf_r[21] = { 12, 2, 13, 3, 14, 4, 15, 5, 16, 6, 17, 7, 18, 8, 19, 9, 20, 10, 21, 11, 1 };
|
||||
static uint8_t xdf_spt[2] = { 6, 8 };
|
||||
static uint8_t xdf_logical_sectors[2][2] = { { 38, 6 }, { 46, 8 } };
|
||||
static uint8_t xdf_physical_sectors[2][2] = { { 16, 3 }, { 19, 4 } };
|
||||
static uint8_t xdf_gap3_sizes[2][2] = { { 60, 69 }, { 60, 50 } };
|
||||
static uint16_t xdf_trackx_spos[2][8] = { { 0xA7F, 0xF02, 0x11B7, 0xB66, 0xE1B, 0x129E }, { 0x302, 0x7E2, 0xA52, 0x12DA, 0x572, 0xDFA, 0x106A, 0x154A } };
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint8_t h;
|
||||
uint8_t r;
|
||||
} xdf_id_t;
|
||||
|
||||
typedef union
|
||||
{
|
||||
uint16_t word;
|
||||
xdf_id_t id;
|
||||
} xdf_sector_t;
|
||||
|
||||
/* XDF: Layout of the sectors in the image. */
|
||||
xdf_sector_t xdf_img_layout[2][2][46] = { { { 0x8100, 0x8200, 0x8300, 0x8400, 0x8500, 0x8600, 0x8700, 0x8800,
|
||||
0x8101, 0x8201, 0x0100, 0x0200, 0x0300, 0x0400, 0x0500, 0x0600,
|
||||
0x0700, 0x0800, 0,
|
||||
0x8301, 0x8401, 0x8501, 0x8601, 0x8701, 0x8801, 0x8901, 0x8A01,
|
||||
0x8B01, 0x8C01, 0x8D01, 0x8E01, 0x8F01, 0x9001, 0, 0,
|
||||
0, 0, 0 },
|
||||
{ 0x8300, 0x8600, 0x8201, 0x8200, 0x8601, 0x8301 }
|
||||
}, /* 5.25" 2HD */
|
||||
{ { 0x8100, 0x8200, 0x8300, 0x8400, 0x8500, 0x8600, 0x8700, 0x8800,
|
||||
0x8900, 0x8A00, 0x8B00, 0x8101, 0x0100, 0x0200, 0x0300, 0x0400,
|
||||
0x0500, 0x0600, 0x0700, 0x0800, 0, 0, 0,
|
||||
0x8201, 0x8301, 0x8401, 0x8501, 0x8601, 0x8701, 0x8801, 0x8901,
|
||||
0x8A01, 0x8B01, 0x8C01, 0x8D01, 0x8E01, 0x8F01, 0, 0,
|
||||
0, 0, 0, 0x9001, 0x9101, 0x9201, 0x9301 },
|
||||
{ 0x8300, 0x8400, 0x8601, 0x8200, 0x8201, 0x8600, 0x8401, 0x8301 }
|
||||
} /* 3.5" 2HD */
|
||||
};
|
||||
|
||||
/* XDF: Layout of the sectors on the disk's track. */
|
||||
xdf_sector_t xdf_disk_layout[2][2][38] = { { { 0x0100, 0x0200, 0x8100, 0x8800, 0x8200, 0x0300, 0x8300, 0x0400,
|
||||
0x8400, 0x0500, 0x8500, 0x0600, 0x8600, 0x0700, 0x8700, 0x0800,
|
||||
0x8D01, 0x8501, 0x8E01, 0x8601, 0x8F01, 0x8701, 0x9001, 0x8801,
|
||||
0x8101, 0x8901, 0x8201, 0x8A01, 0x8301, 0x8B01, 0x8401, 0x8C01 },
|
||||
{ 0x8300, 0x8200, 0x8600, 0x8201, 0x8301, 0x8601 }
|
||||
}, /* 5.25" 2HD */
|
||||
{ { 0x0100, 0x8A00, 0x8100, 0x8B00, 0x8200, 0x0200, 0x8300, 0x0300,
|
||||
0x8400, 0x0400, 0x8500, 0x0500, 0x8600, 0x0600, 0x8700, 0x0700,
|
||||
0x8800, 0x0800, 0x8900,
|
||||
0x9001, 0x8701, 0x9101, 0x8801, 0x9201, 0x8901, 0x9301, 0x8A01,
|
||||
0x8101, 0x8B01, 0x8201, 0x8C01, 0x8301, 0x8D01, 0x8401, 0x8E01,
|
||||
0x8501, 0x8F01, 0x8601 },
|
||||
{ 0x8300, 0x8200, 0x8400, 0x8600, 0x8401, 0x8201, 0x8301, 0x8601 },
|
||||
}, /* 3.5" 2HD */
|
||||
};
|
||||
|
||||
/* First dimension is possible sector sizes (0 = 128, 7 = 16384), second is possible bit rates (250/360, 250, 300, 500/360, 500, 1000). */
|
||||
/* Disks formatted at 250 kbps @ 360 RPM can be read with a 360 RPM single-RPM 5.25" drive by setting the rate to 250 kbps.
|
||||
Disks formatted at 300 kbps @ 300 RPM can be read with any 300 RPM single-RPM drive by setting the rate rate to 300 kbps. */
|
||||
static uint8_t maximum_sectors[8][6] = { { 26, 31, 38, 53, 64, 118 }, /* 128 */
|
||||
{ 15, 19, 23, 32, 38, 73 }, /* 256 */
|
||||
{ 7, 10, 12, 17, 21, 41 }, /* 512 */
|
||||
{ 3, 5, 6, 9, 11, 22 }, /* 1024 */
|
||||
{ 2, 2, 3, 4, 5, 11 }, /* 2048 */
|
||||
{ 1, 1, 1, 2, 2, 5 }, /* 4096 */
|
||||
{ 0, 0, 0, 1, 1, 3 }, /* 8192 */
|
||||
{ 0, 0, 0, 0, 0, 1 } }; /* 16384 */
|
||||
|
||||
static uint8_t xdf_sectors[8][6] = { { 0, 0, 0, 0, 0, 0 }, /* 128 */
|
||||
{ 0, 0, 0, 0, 0, 0 }, /* 256 */
|
||||
{ 0, 0, 0, 19, 23, 0 }, /* 512 */
|
||||
{ 0, 0, 0, 0, 0, 0 }, /* 1024 */
|
||||
{ 0, 0, 0, 0, 0, 0 }, /* 2048 */
|
||||
{ 0, 0, 0, 0, 0, 0 }, /* 4096 */
|
||||
{ 0, 0, 0, 0, 0, 0 }, /* 8192 */
|
||||
{ 0, 0, 0, 0, 0, 0 } }; /* 16384 */
|
||||
|
||||
static uint8_t xdf_types[8][6] = { { 0, 0, 0, 0, 0, 0 }, /* 128 */
|
||||
{ 0, 0, 0, 0, 0, 0 }, /* 256 */
|
||||
{ 0, 0, 0, 1, 2, 0 }, /* 512 */
|
||||
{ 0, 0, 0, 0, 0, 0 }, /* 1024 */
|
||||
{ 0, 0, 0, 0, 0, 0 }, /* 2048 */
|
||||
{ 0, 0, 0, 0, 0, 0 }, /* 4096 */
|
||||
{ 0, 0, 0, 0, 0, 0 }, /* 8192 */
|
||||
{ 0, 0, 0, 0, 0, 0 } }; /* 16384 */
|
||||
|
||||
static double bit_rates_300[6] = { (250.0 * 300.0) / 360.0, 250.0, 300.0, (500.0 * 300.0) / 360.0, 500.0, 1000.0 };
|
||||
|
||||
static uint8_t rates[6] = { 2, 2, 1, 4, 0, 3 };
|
||||
|
||||
static uint8_t holes[6] = { 0, 0, 0, 1, 1, 2 };
|
||||
|
||||
static int gap3_sizes[5][8][256] = { [0][1][16] = 0x54,
|
||||
[0][2][18] = 0x6C,
|
||||
[0][2][19] = 0x48,
|
||||
[0][2][20] = 0x2A,
|
||||
// [0][2][21] = 0x0C,
|
||||
[0][2][21] = 0x08, /* Microsoft DMFWRITE.EXE uses this, 0x0C is used by FDFORMAT. */
|
||||
// [0][2][23] = 0x7A,
|
||||
[0][2][23] = 0x01,
|
||||
// [0][2][24] = 0x38,
|
||||
[2][1][10] = 0x32,
|
||||
[2][1][11] = 0x0C,
|
||||
[2][1][15] = 0x36,
|
||||
[2][1][16] = 0x32,
|
||||
[2][2][8] = 0x58,
|
||||
[2][2][9] = 0x50,
|
||||
[2][2][10] = 0x2E,
|
||||
[2][2][11] = 0x02,
|
||||
[2][2][21] = 0x1C,
|
||||
[2][3][4] = 0xF0,
|
||||
[2][3][5] = 0x74,
|
||||
[3][2][36] = 0x53,
|
||||
[3][2][39] = 0x20,
|
||||
// [3][2][46] = 0x0E,
|
||||
[3][2][46] = 0x01,
|
||||
// [3][2][48] = 0x51,
|
||||
[4][1][32] = 0x36,
|
||||
[4][2][15] = 0x54,
|
||||
[4][2][17] = 0x23,
|
||||
// [4][2][19] = 0x29,
|
||||
[4][2][19] = 0x01,
|
||||
[4][3][8] = 0x74,
|
||||
[4][3][9] = 0x74,
|
||||
[4][3][10] = 0x74
|
||||
};
|
||||
|
||||
/* Needed for formatting! */
|
||||
int img_realtrack(int drive, int track)
|
||||
{
|
||||
if ((img[drive].tracks <= 43) && fdd_doublestep_40(drive))
|
||||
track /= 2;
|
||||
|
||||
return track;
|
||||
}
|
||||
|
||||
void img_writeback(int drive);
|
||||
|
||||
static int sector_size_code(int sector_size)
|
||||
{
|
||||
switch(sector_size)
|
||||
{
|
||||
case 128:
|
||||
return 0;
|
||||
case 256:
|
||||
return 1;
|
||||
default:
|
||||
case 512:
|
||||
return 2;
|
||||
case 1024:
|
||||
return 3;
|
||||
case 2048:
|
||||
return 4;
|
||||
case 4096:
|
||||
return 5;
|
||||
case 8192:
|
||||
return 6;
|
||||
case 16384:
|
||||
return 7;
|
||||
}
|
||||
}
|
||||
|
||||
static int img_sector_size_code(int drive)
|
||||
{
|
||||
return sector_size_code(img[drive].sector_size);
|
||||
}
|
||||
|
||||
void img_init()
|
||||
{
|
||||
memset(img, 0, sizeof(img));
|
||||
// adl[0] = adl[1] = 0;
|
||||
}
|
||||
|
||||
void d86f_register_img(int drive);
|
||||
|
||||
void img_load(int drive, char *fn)
|
||||
{
|
||||
int size;
|
||||
double bit_rate_300;
|
||||
uint16_t bpb_bps;
|
||||
uint16_t bpb_total;
|
||||
uint8_t bpb_mid; /* Media type ID. */
|
||||
uint8_t bpb_sectors;
|
||||
uint8_t bpb_sides;
|
||||
uint32_t bpt;
|
||||
uint8_t max_spt; /* Used for XDF detection. */
|
||||
int temp_rate;
|
||||
char ext[4];
|
||||
int fdi;
|
||||
int i;
|
||||
|
||||
ext[0] = fn[strlen(fn) - 3] | 0x60;
|
||||
ext[1] = fn[strlen(fn) - 2] | 0x60;
|
||||
ext[2] = fn[strlen(fn) - 1] | 0x60;
|
||||
ext[3] = 0;
|
||||
|
||||
writeprot[drive] = 0;
|
||||
img[drive].f = fopen(fn, "rb+");
|
||||
if (!img[drive].f)
|
||||
{
|
||||
img[drive].f = fopen(fn, "rb");
|
||||
if (!img[drive].f)
|
||||
return;
|
||||
writeprot[drive] = 1;
|
||||
}
|
||||
if (ui_writeprot[drive])
|
||||
{
|
||||
writeprot[drive] = 1;
|
||||
}
|
||||
fwriteprot[drive] = writeprot[drive];
|
||||
|
||||
d86f_unregister(drive);
|
||||
|
||||
if (strcmp(ext, "fdi") == 0)
|
||||
{
|
||||
/* This is a Japanese FDI image, so let's read the header */
|
||||
pclog("img_load(): File is a Japanese FDI image...\n");
|
||||
fseek(img[drive].f, 0x10, SEEK_SET);
|
||||
fread(&bpb_bps, 1, 2, img[drive].f);
|
||||
fseek(img[drive].f, 0x0C, SEEK_SET);
|
||||
fread(&size, 1, 4, img[drive].f);
|
||||
bpb_total = size / bpb_bps;
|
||||
fseek(img[drive].f, 0x08, SEEK_SET);
|
||||
fread(&(img[drive].base), 1, 4, img[drive].f);
|
||||
fseek(img[drive].f, img[drive].base + 0x15, SEEK_SET);
|
||||
bpb_mid = fgetc(img[drive].f);
|
||||
if (bpb_mid < 0xF0) bpb_mid = 0xF0;
|
||||
fseek(img[drive].f, 0x14, SEEK_SET);
|
||||
bpb_sectors = fgetc(img[drive].f);
|
||||
fseek(img[drive].f, 0x18, SEEK_SET);
|
||||
bpb_sides = fgetc(img[drive].f);
|
||||
|
||||
fdi = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Read the BPB */
|
||||
pclog("img_load(): File is a raw image...\n");
|
||||
fseek(img[drive].f, 0x0B, SEEK_SET);
|
||||
fread(&bpb_bps, 1, 2, img[drive].f);
|
||||
fseek(img[drive].f, 0x13, SEEK_SET);
|
||||
fread(&bpb_total, 1, 2, img[drive].f);
|
||||
fseek(img[drive].f, 0x15, SEEK_SET);
|
||||
bpb_mid = fgetc(img[drive].f);
|
||||
fseek(img[drive].f, 0x18, SEEK_SET);
|
||||
bpb_sectors = fgetc(img[drive].f);
|
||||
fseek(img[drive].f, 0x1A, SEEK_SET);
|
||||
bpb_sides = fgetc(img[drive].f);
|
||||
|
||||
img[drive].base = 0;
|
||||
fdi = 0;
|
||||
|
||||
fseek(img[drive].f, -1, SEEK_END);
|
||||
size = ftell(img[drive].f) + 1;
|
||||
}
|
||||
|
||||
img[drive].sides = 2;
|
||||
img[drive].sector_size = 2;
|
||||
|
||||
img[drive].hole = 0;
|
||||
|
||||
pclog("BPB reports %i sides and %i bytes per sector\n", bpb_sides, bpb_bps);
|
||||
|
||||
if (((bpb_sides < 1) || (bpb_sides > 2) || (bpb_bps < 128) || (bpb_bps > 2048)) && !fdi)
|
||||
{
|
||||
/* The BPB is giving us a wacky number of sides and/or bytes per sector, therefore it is most probably
|
||||
not a BPB at all, so we have to guess the parameters from file size. */
|
||||
|
||||
if (size <= (160*1024)) { img[drive].sectors = 8; img[drive].tracks = 40; img[drive].sides = 1; }
|
||||
else if (size <= (180*1024)) { img[drive].sectors = 9; img[drive].tracks = 40; img[drive].sides = 1; }
|
||||
else if (size <= (320*1024)) { img[drive].sectors = 8; img[drive].tracks = 40; }
|
||||
else if (size <= (360*1024)) { img[drive].sectors = 9; img[drive].tracks = 40; } /*Double density*/
|
||||
else if (size <= (640*1024)) { img[drive].sectors = 8; img[drive].tracks = 80; } /*Double density 640k*/
|
||||
else if (size < (1024*1024)) { img[drive].sectors = 9; img[drive].tracks = 80; } /*Double density*/
|
||||
else if (size <= 1228800) { img[drive].sectors = 15; img[drive].tracks = 80; } /*High density 1.2MB*/
|
||||
else if (size <= 1261568) { img[drive].sectors = 8; img[drive].tracks = 77; img[drive].sector_size = 3; } /*High density 1.25MB Japanese format*/
|
||||
else if (size <= (0x1A4000-1)) { img[drive].sectors = 18; img[drive].tracks = 80; } /*High density (not supported by Tandy 1000)*/
|
||||
else if (size <= 1556480) { img[drive].sectors = 19; img[drive].tracks = 80; } /*High density (not supported by Tandy 1000)*/
|
||||
else if (size <= 1638400) { img[drive].sectors = 10; img[drive].tracks = 80; img[drive].sector_size = 3; } /*High density (not supported by Tandy 1000)*/
|
||||
else if (size == 1884160) { img[drive].sectors = 23; img[drive].tracks = 80; } /*XDF format - used by OS/2 Warp*/
|
||||
else if (size <= 2000000) { img[drive].sectors = 21; img[drive].tracks = 80; } /*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; } /*E density*/
|
||||
else if (size <= 3358720) { img[drive].sectors = 41; img[drive].tracks = 80; } /*E density, maximum possible size*/
|
||||
else
|
||||
{
|
||||
pclog("Image is bigger than can fit on an ED floppy, ejecting...\n");
|
||||
fclose(img[drive].f);
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* The BPB readings appear to be valid, so let's set the values. */
|
||||
if (fdi)
|
||||
{
|
||||
/* The image is a Japanese FDI, therefore we read the number of tracks from the header. */
|
||||
fseek(img[drive].f, 0x1C, SEEK_SET);
|
||||
fread(&(img[drive].tracks), 1, 4, img[drive].f);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Number of tracks = number of total sectors divided by sides times sectors per track. */
|
||||
img[drive].tracks = ((uint32_t) bpb_total) / (((uint32_t) bpb_sides) * ((uint32_t) bpb_sectors));
|
||||
}
|
||||
/* The rest we just set directly from the BPB. */
|
||||
img[drive].sectors = bpb_sectors;
|
||||
img[drive].sides = bpb_sides;
|
||||
/* The sector size. */
|
||||
img[drive].sector_size = sector_size_code(bpb_bps);
|
||||
|
||||
temp_rate = 0xFF;
|
||||
}
|
||||
|
||||
for (i = 0; i < 6; i++)
|
||||
{
|
||||
if ((img[drive].sectors <= maximum_sectors[img[drive].sector_size][i]) || (img[drive].sectors == xdf_sectors[img[drive].sector_size][i]))
|
||||
{
|
||||
bit_rate_300 = bit_rates_300[i];
|
||||
temp_rate = rates[i];
|
||||
img[drive].disk_flags = holes[i] << 1;
|
||||
img[drive].xdf_type = (img[drive].sectors == xdf_sectors[img[drive].sector_size][i]) ? xdf_types[img[drive].sector_size][i] : 0;
|
||||
if ((bit_rate_300 == 500.0) && (img[drive].sectors == 21) && (img[drive].sector_size == 2) && (img[drive].tracks == 80) && (img[drive].sides == 2))
|
||||
{
|
||||
/* This is a DMF floppy, set the flag so we know to interleave the sectors. */
|
||||
img[drive].dmf = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
img[drive].dmf = 0;
|
||||
}
|
||||
|
||||
pclog("Image parameters: bit rate 300: %f, temporary rate: %i, hole: %i, XDF type: %i\n", bit_rate_300, temp_rate, img[drive].disk_flags >> 1, img[drive].xdf_type);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (temp_rate == 0xFF)
|
||||
{
|
||||
pclog("Image is bigger than can fit on an ED floppy, ejecting...\n");
|
||||
fclose(img[drive].f);
|
||||
return;
|
||||
}
|
||||
|
||||
img[drive].gap2_size = (temp_rate == 3) ? 41 : 22;
|
||||
if (img[drive].dmf)
|
||||
{
|
||||
img[drive].gap3_size = 8;
|
||||
}
|
||||
else
|
||||
{
|
||||
img[drive].gap3_size = gap3_sizes[temp_rate][img[drive].sector_size][img[drive].sectors];
|
||||
}
|
||||
if (!img[drive].gap3_size)
|
||||
{
|
||||
pclog("ERROR: Floppy image of unknown format was inserted into drive %c:!\n", drive + 0x41);
|
||||
fclose(img[drive].f);
|
||||
return;
|
||||
}
|
||||
|
||||
if (img[drive].tracks > 43) img[drive].disk_flags |= 1; /* If the image has more than 43 tracks, then the tracks are thin (96 tpi). */
|
||||
if (img[drive].sides == 2) img[drive].disk_flags |= 8; /* If the has 2 sides, mark it as such. */
|
||||
|
||||
img[drive].track_flags = 0x08; /* IMG files are always assumed to be MFM-encoded. */
|
||||
img[drive].track_flags |= temp_rate & 3; /* Data rate. */
|
||||
if (temp_rate & 4) img[drive].track_flags |= 0x20; /* RPM. */
|
||||
|
||||
pclog("Disk flags: %i, track flags: %i\n", img[drive].disk_flags, img[drive].track_flags);
|
||||
|
||||
d86f_register_img(drive);
|
||||
|
||||
drives[drive].seek = img_seek;
|
||||
|
||||
d86f_common_handlers(drive);
|
||||
}
|
||||
|
||||
void img_close(int drive)
|
||||
{
|
||||
if (img[drive].f)
|
||||
fclose(img[drive].f);
|
||||
img[drive].f = NULL;
|
||||
}
|
||||
|
||||
#define xdf_img_sector xdf_img_layout[current_xdft][!is_t0][sector]
|
||||
#define xdf_disk_sector xdf_disk_layout[current_xdft][!is_t0][array_sector]
|
||||
|
||||
void img_seek(int drive, int track)
|
||||
{
|
||||
int side;
|
||||
int current_xdft = img[drive].xdf_type - 1;
|
||||
|
||||
uint8_t id[4] = { 0, 0, 0, 0 };
|
||||
|
||||
int is_t0, sector, current_pos, img_pos, sh, sr, sn, sside, total, max_pos, bytes, array_sector, buf_side, buf_pos;
|
||||
|
||||
int ssize = 128 << ((int) img[drive].sector_size);
|
||||
|
||||
if (!img[drive].f)
|
||||
return;
|
||||
|
||||
if (d86f_is_40_track(drive) && fdd_doublestep_40(drive))
|
||||
track /= 2;
|
||||
|
||||
img[drive].track = track;
|
||||
|
||||
is_t0 = (track == 0) ? 1 : 0;
|
||||
|
||||
fseek(img[drive].f, img[drive].base + (track * img[drive].sectors * ssize * img[drive].sides), SEEK_SET);
|
||||
for (side = 0; side < img[drive].sides; side++)
|
||||
{
|
||||
fread(img[drive].track_data[side], img[drive].sectors * ssize, 1, img[drive].f);
|
||||
}
|
||||
|
||||
if (!img[drive].xdf_type)
|
||||
{
|
||||
for (side = 0; side < img[drive].sides; side++)
|
||||
{
|
||||
current_pos = d86f_prepare_pretrack(drive, side, 0, 1);
|
||||
|
||||
for (sector = 0; sector < img[drive].sectors; sector++)
|
||||
{
|
||||
sr = img[drive].dmf ? (dmf_r[sector]) : (sector + 1);
|
||||
id[0] = track;
|
||||
id[1] = side;
|
||||
id[2] = sr;
|
||||
id[3] = img[drive].sector_size;
|
||||
img[drive].sector_pos_side[side][sr] = side;
|
||||
img[drive].sector_pos[side][sr] = (sr - 1) * ssize;
|
||||
// if (img[drive].dmf) pclog("DMF: %i %i %i %i | %i %04X\n", id[0], id[1], id[2], id[3], side, (sr - 1) * ssize);
|
||||
current_pos = d86f_prepare_sector(drive, side, current_pos, id, &img[drive].track_data[side][(sr - 1) * ssize], ssize, 1, img[drive].gap2_size, img[drive].gap3_size);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
total = img[drive].sectors;
|
||||
img_pos = 0;
|
||||
sside = 0;
|
||||
|
||||
/* Pass 1, get sector positions in the image. */
|
||||
for (sector = 0; sector < xdf_logical_sectors[current_xdft][!is_t0]; sector++)
|
||||
{
|
||||
if (is_t0)
|
||||
{
|
||||
img_pos = (sector % total) << 9;
|
||||
sside = (sector >= total) ? 1 : 0;
|
||||
}
|
||||
|
||||
if (xdf_img_sector.word)
|
||||
{
|
||||
img[drive].sector_pos_side[xdf_img_sector.id.h][xdf_img_sector.id.r] = sside;
|
||||
img[drive].sector_pos[xdf_img_sector.id.h][xdf_img_sector.id.r] = img_pos;
|
||||
// pclog("Side: %i, Position: %04X\n", sside, img_pos);
|
||||
}
|
||||
|
||||
if (!is_t0)
|
||||
{
|
||||
img_pos += (128 << (xdf_img_sector.id.r & 7));
|
||||
if (img_pos >= (total << 9)) sside = 1;
|
||||
img_pos %= (total << 9);
|
||||
}
|
||||
}
|
||||
|
||||
/* Pass 2, prepare the actual track. */
|
||||
for (side = 0; side < img[drive].sides; side++)
|
||||
{
|
||||
current_pos = d86f_prepare_pretrack(drive, side, 0, 1);
|
||||
|
||||
for (sector = 0; sector < xdf_physical_sectors[current_xdft][!is_t0]; sector++)
|
||||
{
|
||||
array_sector = (side * xdf_physical_sectors[current_xdft][!is_t0]) + sector;
|
||||
// pclog("Sector %i, array sector %i\n", sector, array_sector);
|
||||
|
||||
buf_side = img[drive].sector_pos_side[xdf_disk_sector.id.h][xdf_disk_sector.id.r];
|
||||
buf_pos = img[drive].sector_pos[xdf_disk_sector.id.h][xdf_disk_sector.id.r];
|
||||
|
||||
// pclog("Side: %i, Position: %04X\n", buf_side, buf_pos);
|
||||
|
||||
id[0] = track;
|
||||
id[1] = xdf_disk_sector.id.h;
|
||||
id[2] = xdf_disk_sector.id.r;
|
||||
|
||||
if (is_t0)
|
||||
{
|
||||
id[3] = 2;
|
||||
// pclog("XDF Track 0: Registering sector: %i %i %i %i\n", id[0], id[1], id[2], id[3]);
|
||||
current_pos = d86f_prepare_sector(drive, side, current_pos, id, &img[drive].track_data[buf_side][buf_pos], ssize, 1, img[drive].gap2_size, xdf_gap3_sizes[current_xdft][!is_t0]);
|
||||
}
|
||||
else
|
||||
{
|
||||
id[3] = id[2] & 7;
|
||||
// pclog("XDF Track X: Registering sector: %i %i %i %i\n", id[0], id[1], id[2], id[3]);
|
||||
ssize = (128 << id[3]);
|
||||
current_pos = d86f_prepare_sector(drive, side, xdf_trackx_spos[current_xdft][array_sector], id, &img[drive].track_data[buf_side][buf_pos], ssize, 1, img[drive].gap2_size, xdf_gap3_sizes[current_xdft][!is_t0]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// pclog("Seeked to track: %i\n", img[drive].track);
|
||||
}
|
||||
|
||||
void img_writeback(int drive)
|
||||
{
|
||||
int side;
|
||||
int ssize = 128 << ((int) img[drive].sector_size);
|
||||
|
||||
if (!img[drive].f)
|
||||
return;
|
||||
|
||||
fseek(img[drive].f, img[drive].base + (img[drive].track * img[drive].sectors * ssize * img[drive].sides), SEEK_SET);
|
||||
for (side = 0; side < img[drive].sides; side++)
|
||||
{
|
||||
fwrite(img[drive].track_data[side], img[drive].sectors * ssize, 1, img[drive].f);
|
||||
}
|
||||
}
|
||||
|
||||
int img_xdf_type(int drive)
|
||||
{
|
||||
return img[drive].xdf_type;
|
||||
}
|
||||
|
||||
uint8_t img_disk_flags(int drive)
|
||||
{
|
||||
return img[drive].disk_flags;
|
||||
}
|
||||
|
||||
uint8_t img_side_flags(int drive)
|
||||
{
|
||||
return img[drive].track_flags;
|
||||
}
|
||||
|
||||
void img_set_sector(int drive, int side, uint8_t c, uint8_t h, uint8_t r, uint8_t n)
|
||||
{
|
||||
img[drive].current_sector_pos_side = img[drive].sector_pos_side[h][r];
|
||||
img[drive].current_sector_pos = img[drive].sector_pos[h][r];
|
||||
return;
|
||||
}
|
||||
|
||||
uint8_t img_poll_read_data(int drive, int side, uint16_t pos)
|
||||
{
|
||||
return img[drive].track_data[img[drive].current_sector_pos_side][img[drive].current_sector_pos + pos];
|
||||
}
|
||||
|
||||
void img_poll_write_data(int drive, int side, uint16_t pos, uint8_t data)
|
||||
{
|
||||
img[drive].track_data[img[drive].current_sector_pos_side][img[drive].current_sector_pos + pos] = data;
|
||||
}
|
||||
|
||||
int img_format_conditions(int drive)
|
||||
{
|
||||
int temp = (fdc_get_format_sectors() == img[drive].sectors);
|
||||
temp = temp && (fdc_get_format_n() == img[drive].sector_size);
|
||||
temp = temp && (img[drive].xdf_type == 0);
|
||||
return temp;
|
||||
}
|
||||
|
||||
void d86f_register_img(int drive)
|
||||
{
|
||||
d86f_handler[drive].disk_flags = img_disk_flags;
|
||||
d86f_handler[drive].side_flags = img_side_flags;
|
||||
d86f_handler[drive].writeback = img_writeback;
|
||||
d86f_handler[drive].set_sector = img_set_sector;
|
||||
d86f_handler[drive].read_data = img_poll_read_data;
|
||||
d86f_handler[drive].write_data = img_poll_write_data;
|
||||
d86f_handler[drive].format_conditions = img_format_conditions;
|
||||
d86f_handler[drive].check_crc = 1;
|
||||
}
|
@ -101,6 +101,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("disc_sector_readsector: fdc_period=%i img_period=%i rate=%i c=%i h=%i r=%i n=%i\n", fdc_get_bitcell_period(), get_bitcell_period(drive), rate, track, side, sector, sector_size);
|
||||
|
||||
disc_sector_track[drive] = track;
|
||||
disc_sector_side[drive] = side;
|
||||
@ -120,6 +121,12 @@ void disc_sector_writesector(int drive, int sector, int track, int side, int rat
|
||||
{
|
||||
// pclog("disc_sector_writesector: fdc_period=%i img_period=%i rate=%i\n", fdc_get_bitcell_period(), get_bitcell_period(drive), rate);
|
||||
|
||||
if (writeprot[drive] || swwp)
|
||||
{
|
||||
fdc_writeprotect();
|
||||
return;
|
||||
}
|
||||
|
||||
disc_sector_track[drive] = track;
|
||||
disc_sector_side[drive] = side;
|
||||
disc_sector_drive = drive;
|
||||
@ -171,8 +178,6 @@ int media_type = 0;
|
||||
|
||||
#define GAP3_LEN_VARIABLE 0x1B
|
||||
|
||||
int gap3_sizes[3][2] = { {74, 36}, {77, 77}, {60, 60} };
|
||||
|
||||
int disc_sector_get_gap3_size(int drive, int side, int track)
|
||||
{
|
||||
if (!img_xdf_type(drive))
|
||||
@ -183,7 +188,7 @@ int disc_sector_get_gap3_size(int drive, int side, int track)
|
||||
switch (track)
|
||||
{
|
||||
case 0:
|
||||
return gap3_sizes[img_xdf_type(drive) - 1][side];
|
||||
return 60;
|
||||
default:
|
||||
return GAP3_LEN_VARIABLE;
|
||||
}
|
||||
@ -333,6 +338,7 @@ int disc_sector_can_format(int drive)
|
||||
temp = temp && !swwp;
|
||||
temp = temp && disc_sector_can_read_address(drive);
|
||||
temp = temp && (fdc_get_format_sectors() == disc_sector_count[drive][disc_sector_side[drive]]);
|
||||
temp = temp && (!img_xdf_type(drive));
|
||||
return temp;
|
||||
}
|
||||
|
||||
|
31
src/dma.c
31
src/dma.c
@ -246,12 +246,23 @@ uint8_t _dma_read(uint32_t addr)
|
||||
return mem_readb_phys(addr);
|
||||
}
|
||||
|
||||
uint16_t _dma_readw(uint32_t addr)
|
||||
{
|
||||
return mem_readw_phys(addr);
|
||||
}
|
||||
|
||||
void _dma_write(uint32_t addr, uint8_t val)
|
||||
{
|
||||
mem_writeb_phys(addr, val);
|
||||
mem_invalidate_range(addr, addr);
|
||||
}
|
||||
|
||||
void _dma_writew(uint32_t addr, uint16_t val)
|
||||
{
|
||||
mem_writew_phys(addr, val);
|
||||
mem_invalidate_range(addr, addr + 1);
|
||||
}
|
||||
|
||||
int dma_channel_read(int channel)
|
||||
{
|
||||
uint16_t temp;
|
||||
@ -300,8 +311,12 @@ int dma_channel_read(int channel)
|
||||
if ((dma16.mode[channel] & 0xC) != 8)
|
||||
return DMA_NODATA;
|
||||
|
||||
#if 0
|
||||
temp = _dma_read((dma16.ac[channel] << 1) + ((dma16.page[channel] & ~1) << 16)) |
|
||||
(_dma_read((dma16.ac[channel] << 1) + ((dma16.page[channel] & ~1) << 16) + 1) << 8);
|
||||
#endif
|
||||
|
||||
temp = _dma_readw((dma16.ac[channel] << 1) + ((dma16.page[channel] & ~1) << 16));
|
||||
|
||||
if (dma16.mode[channel] & 0x20) dma16.ac[channel]--;
|
||||
else dma16.ac[channel]++;
|
||||
@ -325,6 +340,18 @@ int dma_channel_read(int channel)
|
||||
}
|
||||
}
|
||||
|
||||
void dma_channel_dump()
|
||||
{
|
||||
int i = 0;
|
||||
FILE *f;
|
||||
f = fopen("dma.dmp", "wb");
|
||||
for (i = 0; i < (21 * 512); i++)
|
||||
{
|
||||
fputc(mem_readb_phys((dma.page[2] << 16) + dma16.ac[2] + i), f);
|
||||
}
|
||||
fclose(f);
|
||||
}
|
||||
|
||||
int dma_channel_write(int channel, uint16_t val)
|
||||
{
|
||||
if (dma.command & 0x04)
|
||||
@ -368,8 +395,12 @@ int dma_channel_write(int channel, uint16_t val)
|
||||
if ((dma16.mode[channel] & 0xC) != 4)
|
||||
return DMA_NODATA;
|
||||
|
||||
#if 0
|
||||
_dma_write((dma16.ac[channel] << 1) + ((dma16.page[channel] & ~1) << 16), val);
|
||||
_dma_write((dma16.ac[channel] << 1) + ((dma16.page[channel] & ~1) << 16) + 1, val >> 8);
|
||||
#endif
|
||||
|
||||
_dma_writew((dma16.ac[channel] << 1) + ((dma16.page[channel] & ~1) << 16), val);
|
||||
|
||||
if (dma16.mode[channel]&0x20) dma16.ac[channel]--;
|
||||
else dma16.ac[channel]++;
|
||||
|
90
src/fdc.c
90
src/fdc.c
@ -14,6 +14,8 @@
|
||||
|
||||
extern int64_t motoron;
|
||||
|
||||
int ui_writeprot[2] = {0, 0};
|
||||
|
||||
static int fdc_reset_stat = 0;
|
||||
/*FDC*/
|
||||
typedef struct FDC
|
||||
@ -66,12 +68,11 @@ typedef struct FDC
|
||||
int drv2en;
|
||||
uint8_t fifobuf[16];
|
||||
|
||||
int seek_params; /* Needed for relative seek. */
|
||||
|
||||
int gap, dtl;
|
||||
int format_sectors;
|
||||
|
||||
int max_track;
|
||||
int mfm;
|
||||
} FDC;
|
||||
|
||||
static FDC fdc;
|
||||
@ -102,13 +103,39 @@ void fdc_reset()
|
||||
// pclog("Reset FDC\n");
|
||||
}
|
||||
|
||||
int fdc_get_drive()
|
||||
{
|
||||
return fdc.drive;
|
||||
}
|
||||
|
||||
int fdc_get_bitcell_period();
|
||||
|
||||
int fdc_get_perp()
|
||||
{
|
||||
if (!AT || fdc.pcjr || fdc.ps1) return 0;
|
||||
|
||||
return fdc.perp;
|
||||
}
|
||||
|
||||
int fdc_get_bit_rate();
|
||||
|
||||
int fdc_get_gap2(int drive)
|
||||
{
|
||||
int auto_gap2 = 22;
|
||||
|
||||
if (!AT || fdc.pcjr || fdc.ps1) return 22;
|
||||
|
||||
if (fdc.perp & 3)
|
||||
{
|
||||
return ((fdc.perp & 3) == 3) ? 41 : 22;
|
||||
}
|
||||
else
|
||||
{
|
||||
auto_gap2 = (fdc_get_bit_rate() >= 3) ? 41 : 22;
|
||||
return (fdc.perp & (4 << drive)) ? auto_gap2 : 22;
|
||||
}
|
||||
}
|
||||
|
||||
int fdc_get_format_n()
|
||||
{
|
||||
return fdc.format_n;
|
||||
@ -116,7 +143,7 @@ int fdc_get_format_n()
|
||||
|
||||
int fdc_is_mfm()
|
||||
{
|
||||
return (fdc.command & 0x40) ? 1 : 0;
|
||||
return fdc.mfm ? 1 : 0;
|
||||
}
|
||||
|
||||
double fdc_get_hut()
|
||||
@ -371,7 +398,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_bit_rate()
|
||||
@ -506,15 +533,18 @@ void fdc_write(uint16_t addr, uint8_t val, void *priv)
|
||||
disctime = 128 * (1 << TIMER_SHIFT);
|
||||
timer_update_outstanding();
|
||||
discint=-1;
|
||||
fdc.perp &= 0xfc;
|
||||
fdc_reset();
|
||||
}
|
||||
timer_process();
|
||||
motoron = (val & 0xf0) ? 1 : 0;
|
||||
timer_update_outstanding();
|
||||
fdc.drive = val & 3;
|
||||
disc_drivesel = fdc.drive & 1;
|
||||
disc_set_drivesel(fdc.drive & 1);
|
||||
}
|
||||
fdc.dor=val;
|
||||
// printf("DOR now %02X\n",val);
|
||||
// printf("DOR now %02X\n",val);
|
||||
return;
|
||||
case 3:
|
||||
/* TDR */
|
||||
@ -531,6 +561,7 @@ void fdc_write(uint16_t addr, uint8_t val, void *priv)
|
||||
disctime = 128 * (1 << TIMER_SHIFT);
|
||||
timer_update_outstanding();
|
||||
discint=-1;
|
||||
fdc.perp &= 0xfc;
|
||||
fdc_reset();
|
||||
}
|
||||
return;
|
||||
@ -575,6 +606,7 @@ void fdc_write(uint16_t addr, uint8_t val, void *priv)
|
||||
fdc.ptot=8;
|
||||
fdc.stat=0x90;
|
||||
fdc.pos=0;
|
||||
fdc.mfm=(fdc.command&0x40)?1:0;
|
||||
break;
|
||||
case 3: /*Specify*/
|
||||
fdc.pnum=0;
|
||||
@ -592,6 +624,7 @@ void fdc_write(uint16_t addr, uint8_t val, void *priv)
|
||||
fdc.ptot=8;
|
||||
fdc.stat=0x90;
|
||||
fdc.pos=0;
|
||||
fdc.mfm=(fdc.command&0x40)?1:0;
|
||||
// readflash=1;
|
||||
break;
|
||||
case 6: /*Read data*/
|
||||
@ -599,6 +632,7 @@ void fdc_write(uint16_t addr, uint8_t val, void *priv)
|
||||
fdc.ptot=8;
|
||||
fdc.stat=0x90;
|
||||
fdc.pos=0;
|
||||
fdc.mfm=(fdc.command&0x40)?1:0;
|
||||
break;
|
||||
case 7: /*Recalibrate*/
|
||||
fdc.pnum=0;
|
||||
@ -619,6 +653,7 @@ void fdc_write(uint16_t addr, uint8_t val, void *priv)
|
||||
fdc.ptot=1;
|
||||
fdc.stat=0x90;
|
||||
fdc.pos=0;
|
||||
fdc.mfm=(fdc.command&0x40)?1:0;
|
||||
break;
|
||||
case 0x0d: /*Format track*/
|
||||
fdc.pnum=0;
|
||||
@ -626,6 +661,7 @@ void fdc_write(uint16_t addr, uint8_t val, void *priv)
|
||||
fdc.stat=0x90;
|
||||
fdc.pos=0;
|
||||
fdc.format_state = 0;
|
||||
fdc.mfm=(fdc.command&0x40)?1:0;
|
||||
break;
|
||||
case 15: /*Seek*/
|
||||
fdc.pnum=0;
|
||||
@ -645,6 +681,7 @@ void fdc_write(uint16_t addr, uint8_t val, void *priv)
|
||||
fdc_callback();
|
||||
break;
|
||||
case 0x12: /*Set perpendicular mode*/
|
||||
if (!AT || fdc.pcjr || fdc.ps1) goto bad_command;
|
||||
fdc.pnum=0;
|
||||
fdc.ptot=1;
|
||||
fdc.stat=0x90;
|
||||
@ -739,8 +776,16 @@ bad_command:
|
||||
|
||||
case 0x12:
|
||||
fdc.stat=0x80;
|
||||
fdc.perp = fdc.params[0];
|
||||
pclog("PERPENDICULAR: Set to: %02X\n", fdc.perp);
|
||||
if (fdc.params[0] & 0x80)
|
||||
{
|
||||
fdc.perp = fdc.params[0] & 0x3f;
|
||||
}
|
||||
else
|
||||
{
|
||||
fdc.perp &= 0xfc;
|
||||
fdc.perp |= (fdc.params[0] & 0x03);
|
||||
}
|
||||
// pclog("PERPENDICULAR: Set to: %02X\n", fdc.perp);
|
||||
disctime = 0;
|
||||
return;
|
||||
|
||||
@ -822,7 +867,7 @@ bad_command:
|
||||
fdc.gap = fdc.params[3];
|
||||
fdc.dtl = 4000000;
|
||||
fdc.format_sectors = fdc.params[2];
|
||||
pclog("Formatting with %i sectors per track\n", fdc.format_sectors);
|
||||
// pclog("Formatting with %i sectors per track\n", fdc.format_sectors);
|
||||
fdc.format_n = fdc.params[1];
|
||||
fdc.format_state = 1;
|
||||
fdc.pos = 0;
|
||||
@ -834,9 +879,9 @@ bad_command:
|
||||
fdc.head = (fdc.params[0] & 4) ? 1 : 0;
|
||||
fdd_set_head(fdc.drive, (fdc.params[0] & 4) ? 1 : 0);
|
||||
disctime = 0;
|
||||
if (fdc.seek_params & 0x80)
|
||||
if (fdc.command & 0x80)
|
||||
{
|
||||
if (fdc.seek_params & 0x40)
|
||||
if (fdc.command & 0x40)
|
||||
{
|
||||
/* Relative seek inwards. */
|
||||
fdc_seek(fdc.drive, fdc.params[1]);
|
||||
@ -846,12 +891,13 @@ bad_command:
|
||||
/* Relative seek outwards. */
|
||||
fdc_seek(fdc.drive, -fdc.params[1]);
|
||||
}
|
||||
disctime = ((int) fdc.params[1]) * 10 * TIMER_USEC;
|
||||
}
|
||||
else
|
||||
{
|
||||
fdc_seek(fdc.drive, fdc.params[1] - fdc.track[fdc.drive]);
|
||||
disctime = ((int) (fdc.params[1] - fdc.track[fdc.drive])) * 10 * TIMER_USEC;
|
||||
}
|
||||
disctime = 790 * TIMER_USEC;
|
||||
fdc.st0 &= 0x30;
|
||||
break;
|
||||
|
||||
@ -1130,7 +1176,7 @@ void fdc_callback()
|
||||
case 7: /*Recalibrate*/
|
||||
fdc.track[fdc.drive]=0;
|
||||
// if (!driveempty[fdc.dor & 1]) discchanged[fdc.dor & 1] = 0;
|
||||
if (fdc.drive <= 1)
|
||||
if (fdc.params[0] <= 1)
|
||||
fdc.st0 = 0x20 | (fdc.params[0] & 3) | (fdd_get_head(fdc.drive ^ fdd_swap)?4:0);
|
||||
else
|
||||
fdc.st0 = 0x68 | (fdc.params[0] & 3) | (fdd_get_head(fdc.drive ^ fdd_swap)?4:0);
|
||||
@ -1147,9 +1193,15 @@ void fdc_callback()
|
||||
|
||||
fdc.stat = (fdc.stat & 0xf) | 0xd0;
|
||||
if (fdc_reset_stat)
|
||||
{
|
||||
disc_stop(4 - fdc_reset_stat);
|
||||
fdc.res[9] = 0xc0 | (4 - fdc_reset_stat) | (fdd_get_head(fdc.drive ^ fdd_swap) ? 4 : 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
disc_stop(fdc.drive);
|
||||
fdc.res[9] = fdc.st0;
|
||||
}
|
||||
fdc.res[10] = fdc.track[fdc.drive];
|
||||
if (!fdc_reset_stat)
|
||||
fdc.st0 = 0x80;
|
||||
@ -1198,7 +1250,7 @@ void fdc_callback()
|
||||
fdc.track[fdc.drive]=fdc.params[1];
|
||||
// if (!driveempty[fdc.dor & 1]) discchanged[fdc.dor & 1] = 0;
|
||||
// printf("Seeked to track %i %i\n",fdc.track[fdc.drive], fdc.drive);
|
||||
if (fdc.drive <= 1)
|
||||
if (fdc.params[0] <= 1)
|
||||
fdc.st0 = 0x20 | (fdc.params[0] & 3) | (fdd_get_head(fdc.drive ^ fdd_swap)?4:0);
|
||||
else
|
||||
fdc.st0 = 0x68 | (fdc.params[0] & 3) | (fdd_get_head(fdc.drive ^ fdd_swap)?4:0);
|
||||
@ -1232,16 +1284,6 @@ void fdc_callback()
|
||||
disctime = 0;
|
||||
return;
|
||||
|
||||
#if 0
|
||||
case 0x12:
|
||||
fdc.perp = fdc.params[0];
|
||||
pclog("PERPENDICULAR: Set to: %02X\n", fdc.perp);
|
||||
fdc.stat = 0x80;
|
||||
disctime = 0;
|
||||
// picint(0x40);
|
||||
return;
|
||||
#endif
|
||||
|
||||
case 0x13: /*Configure*/
|
||||
fdc.config = fdc.params[1];
|
||||
fdc.pretrk = fdc.params[2];
|
||||
@ -1550,6 +1592,7 @@ void fdc_add()
|
||||
fdc.pcjr = 0;
|
||||
fdc.ps1 = 0;
|
||||
fdc.max_track = 79;
|
||||
fdc.perp = 0;
|
||||
}
|
||||
|
||||
void fdc_add_for_superio()
|
||||
@ -1567,6 +1610,7 @@ void fdc_add_pcjr()
|
||||
fdc.pcjr = 1;
|
||||
fdc.ps1 = 0;
|
||||
fdc.max_track = 79;
|
||||
fdc.perp = 0;
|
||||
}
|
||||
|
||||
void fdc_remove()
|
||||
|
@ -31,6 +31,7 @@ void fdc_update_densel_force(int densel_force);
|
||||
void fdc_update_drvrate(int drive, int drvrate);
|
||||
void fdc_update_drv2en(int drv2en);
|
||||
|
||||
int fdc_get_drive();
|
||||
int fdc_get_perp();
|
||||
int fdc_get_format_n();
|
||||
int fdc_is_mfm();
|
||||
@ -39,6 +40,7 @@ double fdc_get_hlt();
|
||||
void fdc_request_next_sector_id();
|
||||
void fdc_stop_id_request();
|
||||
int fdc_get_gap();
|
||||
int fdc_get_gap2(int drive);
|
||||
int fdc_get_dtl();
|
||||
int fdc_get_format_sectors();
|
||||
|
||||
|
@ -167,6 +167,8 @@ struct
|
||||
uint16_t MM_w4[8];
|
||||
|
||||
MMX_REG MM[8];
|
||||
|
||||
uint16_t old_npxc, new_npxc;
|
||||
} cpu_state;
|
||||
|
||||
#define cycles cpu_state._cycles
|
||||
@ -575,6 +577,8 @@ extern uint32_t atapi_get_cd_volume(int channel);
|
||||
|
||||
extern int ide_ter_enabled;
|
||||
|
||||
extern int ui_writeprot[2];
|
||||
|
||||
void pclog(const char *format, ...);
|
||||
extern int nmi;
|
||||
|
||||
|
18
src/mem.c
18
src/mem.c
@ -1552,6 +1552,16 @@ uint8_t mem_readb_phys(uint32_t addr)
|
||||
return 0xff;
|
||||
}
|
||||
|
||||
uint16_t mem_readw_phys(uint32_t addr)
|
||||
{
|
||||
mem_logical_addr = 0xffffffff;
|
||||
|
||||
if (_mem_read_w[addr >> 14])
|
||||
return _mem_read_w[addr >> 14](addr, _mem_priv_r[addr >> 14]);
|
||||
|
||||
return 0xff;
|
||||
}
|
||||
|
||||
void mem_writeb_phys(uint32_t addr, uint8_t val)
|
||||
{
|
||||
mem_logical_addr = 0xffffffff;
|
||||
@ -1560,6 +1570,14 @@ void mem_writeb_phys(uint32_t addr, uint8_t val)
|
||||
_mem_write_b[addr >> 14](addr, val, _mem_priv_w[addr >> 14]);
|
||||
}
|
||||
|
||||
void mem_writew_phys(uint32_t addr, uint16_t val)
|
||||
{
|
||||
mem_logical_addr = 0xffffffff;
|
||||
|
||||
if (_mem_write_w[addr >> 14])
|
||||
_mem_write_w[addr >> 14](addr, val, _mem_priv_w[addr >> 14]);
|
||||
}
|
||||
|
||||
uint8_t mem_read_ram(uint32_t addr, void *priv)
|
||||
{
|
||||
// if (addr >= 0xc0000 && addr < 0x0c8000) pclog("Read RAMb %08X\n", addr);
|
||||
|
9
src/pc.c
9
src/pc.c
@ -96,6 +96,7 @@ void fatal(const char *format, ...)
|
||||
va_end(ap);
|
||||
fflush(stdout);
|
||||
savenvr();
|
||||
saveconfig();
|
||||
dumppic();
|
||||
dumpregs();
|
||||
fflush(stdout);
|
||||
@ -360,6 +361,7 @@ void resetpc_cad()
|
||||
void resetpchard()
|
||||
{
|
||||
savenvr();
|
||||
saveconfig();
|
||||
|
||||
device_close_all();
|
||||
device_init();
|
||||
@ -618,13 +620,18 @@ void loadconfig(char *fn)
|
||||
video_speed = config_get_int(NULL, "video_speed", 3);
|
||||
sound_card_current = config_get_int(NULL, "sndcard", SB2);
|
||||
|
||||
// d86f_unregister(0);
|
||||
// d86f_unregister(1);
|
||||
|
||||
p = (char *)config_get_string(NULL, "disc_a", "");
|
||||
if (p) strcpy(discfns[0], p);
|
||||
else strcpy(discfns[0], "");
|
||||
ui_writeprot[0] = config_get_int(NULL, "disc_a_writeprot", 0);
|
||||
|
||||
p = (char *)config_get_string(NULL, "disc_b", "");
|
||||
if (p) strcpy(discfns[1], p);
|
||||
else strcpy(discfns[1], "");
|
||||
ui_writeprot[1] = config_get_int(NULL, "disc_b_writeprot", 0);
|
||||
|
||||
mem_size = config_get_int(NULL, "mem_size", 4096);
|
||||
if (mem_size < (models[model].is_at ? models[model].min_ram*1024 : models[model].min_ram))
|
||||
@ -746,7 +753,9 @@ void saveconfig()
|
||||
config_set_int(NULL, "cache", cache);
|
||||
config_set_int(NULL, "cga_composite", cga_comp);
|
||||
config_set_string(NULL, "disc_a", discfns[0]);
|
||||
config_set_int(NULL, "disc_a_writeprot", ui_writeprot[0]);
|
||||
config_set_string(NULL, "disc_b", discfns[1]);
|
||||
config_set_int(NULL, "disc_b_writeprot", ui_writeprot[1]);
|
||||
config_set_int(NULL, "mem_size", mem_size);
|
||||
config_set_int(NULL, "cdrom_drive", cdrom_drive);
|
||||
config_set_int(NULL, "cdrom_enabled", cdrom_enabled);
|
||||
|
@ -19,9 +19,11 @@ BEGIN
|
||||
POPUP "&Disc"
|
||||
BEGIN
|
||||
MENUITEM "Change drive &A:...", IDM_DISC_A
|
||||
MENUITEM "Change drive A (&Write-protected):...", IDM_DISC_A_WP
|
||||
MENUITEM "Change drive &B:...", IDM_DISC_B
|
||||
MENUITEM "Change drive B (W&rite-protected):...", IDM_DISC_B_WP
|
||||
MENUITEM "&Eject drive A:", IDM_EJECT_A
|
||||
MENUITEM "Eject drive B:", IDM_EJECT_B
|
||||
MENUITEM "E&ject drive B:", IDM_EJECT_B
|
||||
MENUITEM "&Configure hard discs...",IDM_HDCONF
|
||||
END
|
||||
POPUP "&Settings"
|
||||
|
@ -33,22 +33,24 @@ void pc87306_gpio_write(uint16_t port, uint8_t val, void *priv)
|
||||
|
||||
uint8_t uart_int1()
|
||||
{
|
||||
return ((pc87306_regs[0x1C] >> 2) & 1) ? 3 : 4;
|
||||
return ((pc87306_regs[0x1C] >> 2) & 1) ? 4 : 3;
|
||||
}
|
||||
|
||||
uint8_t uart_int2()
|
||||
{
|
||||
return ((pc87306_regs[0x1C] >> 6) & 1) ? 3 : 4;
|
||||
return ((pc87306_regs[0x1C] >> 6) & 1) ? 4 : 3;
|
||||
}
|
||||
|
||||
uint8_t uart1_int()
|
||||
{
|
||||
return (pc87306_regs[0x1C] & 1) ? uart_int1() : 4;
|
||||
temp = ((pc87306_regs[1] >> 2) & 1) ? 3 : 4; /* 0 = IRQ 4, 1 = IRQ 3 */
|
||||
return (pc87306_regs[0x1C] & 1) ? uart_int1() : temp;
|
||||
}
|
||||
|
||||
uint8_t uart2_int()
|
||||
{
|
||||
return (pc87306_regs[0x1C] & 1) ? uart_int2() : 3;
|
||||
temp = ((pc87306_regs[1] >> 4) & 1) ? 3 : 4; /* 0 = IRQ 4, 1 = IRQ 3 */
|
||||
return (pc87306_regs[0x1C] & 1) ? uart_int2() : temp;
|
||||
}
|
||||
|
||||
void serial1_handler()
|
||||
@ -178,7 +180,7 @@ process_value:
|
||||
if (val & 2)
|
||||
{
|
||||
serial1_handler();
|
||||
if (mouse_always_serial) mouse_serial_init();
|
||||
// if (mouse_always_serial) mouse_serial_init();
|
||||
}
|
||||
if (val & 4) serial2_handler();
|
||||
|
||||
@ -218,7 +220,7 @@ process_value:
|
||||
if (pc87306_regs[0] & 2)
|
||||
{
|
||||
serial1_handler();
|
||||
if (mouse_always_serial) mouse_serial_init();
|
||||
// if (mouse_always_serial) mouse_serial_init();
|
||||
}
|
||||
if (pc87306_regs[0] & 4) serial2_handler();
|
||||
break;
|
||||
@ -237,7 +239,7 @@ process_value:
|
||||
if (pc87306_regs[0] & 2)
|
||||
{
|
||||
serial1_handler();
|
||||
if (mouse_always_serial) mouse_serial_init();
|
||||
// if (mouse_always_serial) mouse_serial_init();
|
||||
}
|
||||
if (pc87306_regs[0] & 4) serial2_handler();
|
||||
}
|
||||
|
@ -519,6 +519,7 @@ void piix_init(int card)
|
||||
card_piix_ide[0x0d] = 0x00;
|
||||
card_piix_ide[0x0e] = 0x00;
|
||||
card_piix_ide[0x20] = 0x01; card_piix_ide[0x21] = card_piix_ide[0x22] = card_piix_ide[0x23] = 0x00; /*Bus master interface base address*/
|
||||
card_piix_ide[0x3C] = 14; /* Default IRQ */
|
||||
card_piix_ide[0x40] = card_piix_ide[0x41] = 0x00;
|
||||
card_piix_ide[0x42] = card_piix_ide[0x43] = 0x00;
|
||||
|
||||
|
@ -10,6 +10,8 @@
|
||||
#define IDM_EJECT_A 40012
|
||||
#define IDM_EJECT_B 40013
|
||||
#define IDM_HDCONF 40014
|
||||
#define IDM_DISC_A_WP 40015
|
||||
#define IDM_DISC_B_WP 40016
|
||||
#define IDM_CONFIG 40020
|
||||
#define IDM_CONFIG_LOAD 40021
|
||||
#define IDM_CONFIG_SAVE 40022
|
||||
|
@ -805,6 +805,7 @@ int WINAPI WinMain (HINSTANCE hThisInstance,
|
||||
// pclog("Quited? %i\n",quited);
|
||||
// pclog("Closepc\n");
|
||||
savenvr();
|
||||
saveconfig();
|
||||
if (save_window_pos && window_remember)
|
||||
saveconfig();
|
||||
closepc();
|
||||
@ -974,6 +975,7 @@ LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM
|
||||
pause=1;
|
||||
Sleep(100);
|
||||
savenvr();
|
||||
saveconfig();
|
||||
resetpc();
|
||||
pause=0;
|
||||
break;
|
||||
@ -982,6 +984,7 @@ LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM
|
||||
pause=1;
|
||||
Sleep(100);
|
||||
savenvr();
|
||||
saveconfig();
|
||||
resetpchard();
|
||||
pause=0;
|
||||
break;
|
||||
@ -989,6 +992,7 @@ LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM
|
||||
pause=1;
|
||||
Sleep(100);
|
||||
savenvr();
|
||||
saveconfig();
|
||||
resetpc_cad();
|
||||
pause=0;
|
||||
break;
|
||||
@ -996,17 +1000,21 @@ LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM
|
||||
PostQuitMessage (0); /* send a WM_QUIT to the message queue */
|
||||
break;
|
||||
case IDM_DISC_A:
|
||||
case IDM_DISC_A_WP:
|
||||
if (!getfile(hwnd,"Disc image (*.12;*.144;*.360;*.720;*.86F;*.DSK;*.IMG;*.IMA;*.FDI;*.FLP;*.XDF;*.VFD)\0*.12;*.144;*.360;*.720;*.86F;*.DSK;*.IMG;*.IMA;*.FDI;*.FLP;*.XDF;*.VFD\0All files (*.*)\0*.*\0",discfns[0]))
|
||||
{
|
||||
disc_close(0);
|
||||
ui_writeprot[0] = (LOWORD(wParam) == IDM_DISC_A_WP) ? 1 : 0;
|
||||
disc_load(0, openfilestring);
|
||||
saveconfig();
|
||||
}
|
||||
break;
|
||||
case IDM_DISC_B:
|
||||
case IDM_DISC_B_WP:
|
||||
if (!getfile(hwnd,"Disc image (*.12;*.144;*.360;*.720;*.86F;*.DSK;*.IMG;*.IMA;*.FDI;*.FLP;*.XDF;*.VFD)\0*.12;*.144;*.360;*.720;*.86F;*.DSK;*.IMG;*.IMA;*.FDI;*.FLP;*.XDF;*.VFD\0All files (*.*)\0*.*\0",discfns[1]))
|
||||
{
|
||||
disc_close(1);
|
||||
ui_writeprot[1] = (LOWORD(wParam) == IDM_DISC_B_WP) ? 1 : 0;
|
||||
disc_load(1, openfilestring);
|
||||
saveconfig();
|
||||
}
|
||||
|
@ -32,6 +32,7 @@ static int opFINIT(uint32_t fetchdat)
|
||||
FP_ENTER();
|
||||
cpu_state.pc++;
|
||||
cpu_state.npxc = 0x37F;
|
||||
cpu_state.new_npxc = (cpu_state.old_npxc & ~0xc00);
|
||||
cpu_state.npxs = 0;
|
||||
*(uint64_t *)cpu_state.tag = 0x0303030303030303ll;
|
||||
cpu_state.TOP = 0;
|
||||
@ -96,6 +97,7 @@ static int FSTOR()
|
||||
case 0x000: /*16-bit real mode*/
|
||||
case 0x001: /*16-bit protected mode*/
|
||||
cpu_state.npxc = readmemw(easeg, cpu_state.eaaddr);
|
||||
cpu_state.new_npxc = (cpu_state.old_npxc & ~0xc00) | (cpu_state.npxc & 0xc00);
|
||||
cpu_state.npxs = readmemw(easeg, cpu_state.eaaddr+2);
|
||||
x87_settag(readmemw(easeg, cpu_state.eaaddr+4));
|
||||
cpu_state.TOP = (cpu_state.npxs >> 11) & 7;
|
||||
@ -104,6 +106,7 @@ static int FSTOR()
|
||||
case 0x100: /*32-bit real mode*/
|
||||
case 0x101: /*32-bit protected mode*/
|
||||
cpu_state.npxc = readmemw(easeg, cpu_state.eaaddr);
|
||||
cpu_state.new_npxc = (cpu_state.old_npxc & ~0xc00) | (cpu_state.npxc & 0xc00);
|
||||
cpu_state.npxs = readmemw(easeg, cpu_state.eaaddr+4);
|
||||
x87_settag(readmemw(easeg, cpu_state.eaaddr+8));
|
||||
cpu_state.TOP = (cpu_state.npxs >> 11) & 7;
|
||||
@ -676,6 +679,7 @@ static int FLDENV()
|
||||
case 0x000: /*16-bit real mode*/
|
||||
case 0x001: /*16-bit protected mode*/
|
||||
cpu_state.npxc = readmemw(easeg, cpu_state.eaaddr);
|
||||
cpu_state.new_npxc = (cpu_state.old_npxc & ~0xc00) | (cpu_state.npxc & 0xc00);
|
||||
cpu_state.npxs = readmemw(easeg, cpu_state.eaaddr+2);
|
||||
x87_settag(readmemw(easeg, cpu_state.eaaddr+4));
|
||||
cpu_state.TOP = (cpu_state.npxs >> 11) & 7;
|
||||
@ -683,6 +687,7 @@ static int FLDENV()
|
||||
case 0x100: /*32-bit real mode*/
|
||||
case 0x101: /*32-bit protected mode*/
|
||||
cpu_state.npxc = readmemw(easeg, cpu_state.eaaddr);
|
||||
cpu_state.new_npxc = (cpu_state.old_npxc & ~0xc00) | (cpu_state.npxc & 0xc00);
|
||||
cpu_state.npxs = readmemw(easeg, cpu_state.eaaddr+4);
|
||||
x87_settag(readmemw(easeg, cpu_state.eaaddr+8));
|
||||
cpu_state.TOP = (cpu_state.npxs >> 11) & 7;
|
||||
@ -716,6 +721,7 @@ static int opFLDCW_a16(uint32_t fetchdat)
|
||||
tempw = geteaw();
|
||||
if (cpu_state.abrt) return 1;
|
||||
cpu_state.npxc = tempw;
|
||||
cpu_state.new_npxc = (cpu_state.old_npxc & ~0xc00) | (cpu_state.npxc & 0xc00);
|
||||
CLOCK_CYCLES(4);
|
||||
return 0;
|
||||
}
|
||||
@ -728,6 +734,7 @@ static int opFLDCW_a32(uint32_t fetchdat)
|
||||
tempw = geteaw();
|
||||
if (cpu_state.abrt) return 1;
|
||||
cpu_state.npxc = tempw;
|
||||
cpu_state.new_npxc = (cpu_state.old_npxc & ~0xc00) | (cpu_state.npxc & 0xc00);
|
||||
CLOCK_CYCLES(4);
|
||||
return 0;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user