mirror of
https://github.com/86Box/86Box.git
synced 2026-02-22 01:25:33 -07:00
Applied all mainline PCem commits;
Added experimental NVidia Riva TNT2 emulation (patch from MoochMcGee); ASUS P/I-P54TP4XE, ASUS P/I-P55T2P4, and ASUS P/I-P55TVP4 are back; National Semiconductor PC87306 Super I/O chip now correctly reenables devices after a chip power cycle; Several FDC improvements and the behavior is now a bit closer to real hardware (based on actual tests); Added MR Intel Advanced/ATX with Microid Research BIOS with support for 4 floppy drives and up to 4 IDE controllers; Added floppy drives 3 and 4, bringing the maximum to 4; You can now connect hard disks to the tertiary IDE controller; Correct undocumented behavior of the LEA instruction with register is back on 286 and later CPU's; Pentium-rea models with Intel chipsets now have port 92 (with alternate reset and alternate A20 toggle); Overhauled DMA channel read and write routines and fixed cascading; Improved IMG detection of a bad BPB (or complete lack of a BPB); Added preliminary emulation of PS/2 1.44 MB and PC-98 1.25 MB 3-mode drives (both have an inverted DENSEL pin); Removed the incorrect Amstrad mouse patch from TheCollector1995; Fixed ATAPI CD-ROM disk change detection; Windows IOCTL CD-ROM handler now tries to use direct SCSI passthrough for more things, including obtaining CD-ROM capacity; The Diamond Stealth32 (ET4000/W32p) now also works correctly on the two Award SiS 496/497 boxes; The (S)VGA handler now converts 6-bit RAMDAC RGB channels to standard 8-bit RGB using a lookup table generated at emulator start, calculated using the correct intensity conversion method and treating intensity 64 as equivalent to 63; Moved a few options from the Configuration dialog box to the menu; SIO, PIIX, and PIIX3 now have the reset control register on port CF9 as they should; Several bugfixes.
This commit is contained in:
BIN
nvr/ami386dx_opti495.nvr
Normal file
BIN
nvr/ami386dx_opti495.nvr
Normal file
Binary file not shown.
BIN
nvr/mr386dx_opti495.nvr
Normal file
BIN
nvr/mr386dx_opti495.nvr
Normal file
Binary file not shown.
@@ -29,7 +29,6 @@ extern int cpl_override;
|
||||
|
||||
int has_fpu;
|
||||
extern int fpucount;
|
||||
int times;
|
||||
uint16_t rds;
|
||||
uint16_t ea_rseg;
|
||||
|
||||
@@ -40,7 +39,6 @@ int cgate32;
|
||||
|
||||
uint8_t romext[32768];
|
||||
uint8_t *ram,*rom;
|
||||
uint16_t biosmask;
|
||||
|
||||
uint32_t rmdat32;
|
||||
#define rmdat rmdat32
|
||||
@@ -289,6 +287,7 @@ dontprint=0;
|
||||
{
|
||||
cpu_state.abrt = 0;
|
||||
softresetx86();
|
||||
cpu_set_edx();
|
||||
pclog("Triple fault - reset\n");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -38,7 +38,6 @@ int cpl_override=0;
|
||||
|
||||
int has_fpu;
|
||||
int fpucount=0;
|
||||
int times;
|
||||
uint16_t rds;
|
||||
uint16_t ea_rseg;
|
||||
|
||||
@@ -48,7 +47,6 @@ int cgate32;
|
||||
|
||||
uint8_t romext[32768];
|
||||
uint8_t *ram,*rom;
|
||||
uint16_t biosmask;
|
||||
|
||||
uint32_t rmdat32;
|
||||
uint32_t backupregs[16];
|
||||
@@ -135,6 +133,7 @@ static inline void fetch_ea_32_long(uint32_t rmdat)
|
||||
if (writelookup2[addr >> 12] != -1)
|
||||
eal_w = (uint32_t *)(writelookup2[addr >> 12] + addr);
|
||||
}
|
||||
cpu_state.last_ea = cpu_state.eaaddr;
|
||||
}
|
||||
|
||||
static inline void fetch_ea_16_long(uint32_t rmdat)
|
||||
@@ -177,6 +176,7 @@ static inline void fetch_ea_16_long(uint32_t rmdat)
|
||||
if (writelookup2[addr >> 12] != -1)
|
||||
eal_w = (uint32_t *)(writelookup2[addr >> 12] + addr);
|
||||
}
|
||||
cpu_state.last_ea = cpu_state.eaaddr;
|
||||
}
|
||||
|
||||
#define fetch_ea_16(rmdat) cpu_state.pc++; cpu_mod=(rmdat >> 6) & 3; cpu_reg=(rmdat >> 3) & 7; cpu_rm = rmdat & 7; if (cpu_mod != 3) { fetch_ea_16_long(rmdat); if (cpu_state.abrt) return 1; }
|
||||
@@ -275,6 +275,89 @@ void x86illegal()
|
||||
x86_int(6);
|
||||
}
|
||||
|
||||
/*Prefetch emulation is a fairly simplistic model:
|
||||
- All instruction bytes must be fetched before it starts.
|
||||
- Cycles used for non-instruction memory accesses are counted and subtracted
|
||||
from the total cycles taken
|
||||
- Any remaining cycles are used to refill the prefetch queue.
|
||||
|
||||
Note that this is only used for 286 / 386 systems. It is disabled when the
|
||||
internal cache on 486+ CPUs is enabled.
|
||||
*/
|
||||
static int prefetch_bytes = 0;
|
||||
static int prefetch_prefixes = 0;
|
||||
|
||||
static void prefetch_run(int instr_cycles, int bytes, int modrm, int reads, int reads_l, int writes, int writes_l, int ea32)
|
||||
{
|
||||
int mem_cycles = reads*cpu_cycles_read + reads_l*cpu_cycles_read_l + writes*cpu_cycles_write + writes_l*cpu_cycles_write_l;
|
||||
|
||||
if (instr_cycles < mem_cycles)
|
||||
instr_cycles = mem_cycles;
|
||||
|
||||
prefetch_bytes -= prefetch_prefixes;
|
||||
prefetch_bytes -= bytes;
|
||||
if (modrm != -1)
|
||||
{
|
||||
if (ea32)
|
||||
{
|
||||
if ((modrm & 7) == 4)
|
||||
{
|
||||
if ((modrm & 0x700) == 0x500)
|
||||
prefetch_bytes -= 5;
|
||||
else if ((modrm & 0xc0) == 0x40)
|
||||
prefetch_bytes -= 2;
|
||||
else if ((modrm & 0xc0) == 0x80)
|
||||
prefetch_bytes -= 5;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((modrm & 0xc7) == 0x05)
|
||||
prefetch_bytes -= 4;
|
||||
else if ((modrm & 0xc0) == 0x40)
|
||||
prefetch_bytes--;
|
||||
else if ((modrm & 0xc0) == 0x80)
|
||||
prefetch_bytes -= 4;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((modrm & 0xc7) == 0x06)
|
||||
prefetch_bytes -= 2;
|
||||
else if ((modrm & 0xc0) != 0xc0)
|
||||
prefetch_bytes -= ((modrm & 0xc0) >> 6);
|
||||
}
|
||||
}
|
||||
|
||||
/* Fill up prefetch queue */
|
||||
while (prefetch_bytes < 0)
|
||||
{
|
||||
prefetch_bytes += cpu_prefetch_width;
|
||||
cycles -= cpu_prefetch_cycles;
|
||||
}
|
||||
|
||||
/* Subtract cycles used for memory access by instruction */
|
||||
instr_cycles -= mem_cycles;
|
||||
|
||||
while (instr_cycles >= cpu_prefetch_cycles)
|
||||
{
|
||||
prefetch_bytes += cpu_prefetch_width;
|
||||
instr_cycles -= cpu_prefetch_cycles;
|
||||
}
|
||||
|
||||
prefetch_prefixes = 0;
|
||||
}
|
||||
|
||||
static void prefetch_flush()
|
||||
{
|
||||
prefetch_bytes = 0;
|
||||
}
|
||||
|
||||
#define PREFETCH_RUN(instr_cycles, bytes, modrm, reads, reads_l, writes, writes_l, ea32) \
|
||||
do { if (cpu_prefetch_cycles) prefetch_run(instr_cycles, bytes, modrm, reads, reads_l, writes, writes_l, ea32); } while (0)
|
||||
|
||||
#define PREFETCH_PREFIX() prefetch_prefixes++
|
||||
#define PREFETCH_FLUSH() prefetch_flush()
|
||||
|
||||
|
||||
int rep386(int fv)
|
||||
{
|
||||
@@ -292,6 +375,7 @@ int rep386(int fv)
|
||||
that high frequency timers still work okay. This amount is different
|
||||
for interpreter and recompiler*/
|
||||
int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100);
|
||||
int reads = 0, reads_l = 0, writes = 0, writes_l = 0, total_cycles = 0;
|
||||
|
||||
if (trap)
|
||||
cycles_end = cycles+1; /*Force the instruction to end after only one iteration when trap flag set*/
|
||||
@@ -320,28 +404,36 @@ int rep386(int fv)
|
||||
break;
|
||||
case 0x26: case 0x126: case 0x226: case 0x326: /*ES:*/
|
||||
cpu_state.ea_seg = &_es;
|
||||
PREFETCH_PREFIX();
|
||||
goto startrep;
|
||||
break;
|
||||
case 0x2E: case 0x12E: case 0x22E: case 0x32E: /*CS:*/
|
||||
cpu_state.ea_seg = &_cs;
|
||||
PREFETCH_PREFIX();
|
||||
goto startrep;
|
||||
case 0x36: case 0x136: case 0x236: case 0x336: /*SS:*/
|
||||
cpu_state.ea_seg = &_ss;
|
||||
PREFETCH_PREFIX();
|
||||
goto startrep;
|
||||
case 0x3E: case 0x13E: case 0x23E: case 0x33E: /*DS:*/
|
||||
cpu_state.ea_seg = &_ds;
|
||||
PREFETCH_PREFIX();
|
||||
goto startrep;
|
||||
case 0x64: case 0x164: case 0x264: case 0x364: /*FS:*/
|
||||
cpu_state.ea_seg = &_fs;
|
||||
PREFETCH_PREFIX();
|
||||
goto startrep;
|
||||
case 0x65: case 0x165: case 0x265: case 0x365: /*GS:*/
|
||||
cpu_state.ea_seg = &_gs;
|
||||
PREFETCH_PREFIX();
|
||||
goto startrep;
|
||||
case 0x66: case 0x166: case 0x266: case 0x366: /*Data size prefix*/
|
||||
rep32 = (rep32 & 0x200) | ((use32 ^ 0x100) & 0x100);
|
||||
PREFETCH_PREFIX();
|
||||
goto startrep;
|
||||
case 0x67: case 0x167: case 0x267: case 0x367: /*Address size prefix*/
|
||||
rep32 = (rep32 & 0x100) | ((use32 ^ 0x200) & 0x200);
|
||||
PREFETCH_PREFIX();
|
||||
goto startrep;
|
||||
case 0x6C: case 0x16C: /*REP INSB*/
|
||||
// cpu_notreps++;
|
||||
@@ -355,6 +447,7 @@ int rep386(int fv)
|
||||
else DI++;
|
||||
c--;
|
||||
cycles-=15;
|
||||
reads++; writes++; total_cycles += 15;
|
||||
}
|
||||
if (c>0) { firstrepcycle=0; cpu_state.pc=ipc; }
|
||||
else firstrepcycle=1;
|
||||
@@ -371,6 +464,7 @@ int rep386(int fv)
|
||||
else EDI++;
|
||||
c--;
|
||||
cycles-=15;
|
||||
reads++; writes++; total_cycles += 15;
|
||||
}
|
||||
if (c>0) { firstrepcycle=0; cpu_state.pc=ipc; }
|
||||
else firstrepcycle=1;
|
||||
@@ -387,6 +481,7 @@ int rep386(int fv)
|
||||
else DI+=2;
|
||||
c--;
|
||||
cycles-=15;
|
||||
reads++; writes++; total_cycles += 15;
|
||||
}
|
||||
if (c>0) { firstrepcycle=0; cpu_state.pc=ipc; }
|
||||
else firstrepcycle=1;
|
||||
@@ -402,6 +497,7 @@ int rep386(int fv)
|
||||
else DI+=4;
|
||||
c--;
|
||||
cycles-=15;
|
||||
reads_l++; writes_l++; total_cycles += 15;
|
||||
}
|
||||
if (c>0) { firstrepcycle=0; cpu_state.pc=ipc; }
|
||||
else firstrepcycle=1;
|
||||
@@ -417,6 +513,7 @@ int rep386(int fv)
|
||||
else EDI+=2;
|
||||
c--;
|
||||
cycles-=15;
|
||||
reads++; writes++; total_cycles += 15;
|
||||
}
|
||||
if (c>0) { firstrepcycle=0; cpu_state.pc=ipc; }
|
||||
else firstrepcycle=1;
|
||||
@@ -432,6 +529,7 @@ int rep386(int fv)
|
||||
else EDI+=4;
|
||||
c--;
|
||||
cycles-=15;
|
||||
reads_l++; writes_l++; total_cycles += 15;
|
||||
}
|
||||
if (c>0) { firstrepcycle=0; cpu_state.pc=ipc; }
|
||||
else firstrepcycle=1;
|
||||
@@ -448,6 +546,7 @@ int rep386(int fv)
|
||||
else SI++;
|
||||
c--;
|
||||
cycles-=14;
|
||||
reads++; writes++; total_cycles += 14;
|
||||
}
|
||||
if (c>0) { firstrepcycle=0; cpu_state.pc=ipc; }
|
||||
else firstrepcycle=1;
|
||||
@@ -464,6 +563,7 @@ int rep386(int fv)
|
||||
else ESI++;
|
||||
c--;
|
||||
cycles-=14;
|
||||
reads++; writes++; total_cycles += 14;
|
||||
}
|
||||
if (c>0) { firstrepcycle=0; cpu_state.pc=ipc; }
|
||||
else firstrepcycle=1;
|
||||
@@ -480,6 +580,7 @@ int rep386(int fv)
|
||||
else SI+=2;
|
||||
c--;
|
||||
cycles-=14;
|
||||
reads++; writes++; total_cycles += 14;
|
||||
}
|
||||
if (c>0) { firstrepcycle=0; cpu_state.pc=ipc; }
|
||||
else firstrepcycle=1;
|
||||
@@ -495,6 +596,7 @@ int rep386(int fv)
|
||||
else SI += 4;
|
||||
c--;
|
||||
cycles -= 14;
|
||||
reads_l++; writes_l++; total_cycles += 14;
|
||||
}
|
||||
if (c > 0) { firstrepcycle = 0; cpu_state.pc = ipc; }
|
||||
else firstrepcycle = 1;
|
||||
@@ -510,6 +612,7 @@ int rep386(int fv)
|
||||
else ESI+=2;
|
||||
c--;
|
||||
cycles-=14;
|
||||
reads++; writes++; total_cycles += 14;
|
||||
}
|
||||
if (c>0) { firstrepcycle=0; cpu_state.pc=ipc; }
|
||||
else firstrepcycle=1;
|
||||
@@ -525,6 +628,7 @@ int rep386(int fv)
|
||||
else ESI += 4;
|
||||
c--;
|
||||
cycles -= 14;
|
||||
reads_l++; writes_l++; total_cycles += 14;
|
||||
}
|
||||
if (c > 0) { firstrepcycle = 0; cpu_state.pc = ipc; }
|
||||
else firstrepcycle = 1;
|
||||
@@ -545,6 +649,7 @@ int rep386(int fv)
|
||||
c--;
|
||||
cycles-=(is486)?3:4;
|
||||
ins++;
|
||||
reads++; writes++; total_cycles += is486 ? 3 : 4;
|
||||
if (cycles < cycles_end)
|
||||
break;
|
||||
}
|
||||
@@ -563,6 +668,7 @@ int rep386(int fv)
|
||||
c--;
|
||||
cycles-=(is486)?3:4;
|
||||
ins++;
|
||||
reads++; writes++; total_cycles += is486 ? 3 : 4;
|
||||
if (cycles < cycles_end)
|
||||
break;
|
||||
}
|
||||
@@ -581,6 +687,7 @@ int rep386(int fv)
|
||||
c--;
|
||||
cycles-=(is486)?3:4;
|
||||
ins++;
|
||||
reads++; writes++; total_cycles += is486 ? 3 : 4;
|
||||
if (cycles < cycles_end)
|
||||
break;
|
||||
}
|
||||
@@ -600,6 +707,7 @@ int rep386(int fv)
|
||||
c--;
|
||||
cycles-=(is486)?3:4;
|
||||
ins++;
|
||||
reads_l++; writes_l++; total_cycles += is486 ? 3 : 4;
|
||||
if (cycles < cycles_end)
|
||||
break;
|
||||
}
|
||||
@@ -619,6 +727,7 @@ int rep386(int fv)
|
||||
c--;
|
||||
cycles-=(is486)?3:4;
|
||||
ins++;
|
||||
reads++; writes++; total_cycles += is486 ? 3 : 4;
|
||||
if (cycles < cycles_end)
|
||||
break;
|
||||
}
|
||||
@@ -639,6 +748,7 @@ int rep386(int fv)
|
||||
c--;
|
||||
cycles-=(is486)?3:4;
|
||||
ins++;
|
||||
reads_l++; writes_l++; total_cycles += is486 ? 3 : 4;
|
||||
if (cycles < cycles_end)
|
||||
break;
|
||||
}
|
||||
@@ -658,6 +768,7 @@ int rep386(int fv)
|
||||
else { DI++; SI++; }
|
||||
c--;
|
||||
cycles-=(is486)?7:9;
|
||||
reads += 2; total_cycles += is486 ? 7 : 9;
|
||||
setsub8(temp,temp2);
|
||||
tempz = (ZF_SET()) ? 1 : 0;
|
||||
}
|
||||
@@ -676,6 +787,7 @@ int rep386(int fv)
|
||||
else { EDI++; ESI++; }
|
||||
c--;
|
||||
cycles-=(is486)?7:9;
|
||||
reads += 2; total_cycles += is486 ? 7 : 9;
|
||||
setsub8(temp,temp2);
|
||||
tempz = (ZF_SET()) ? 1 : 0;
|
||||
}
|
||||
@@ -697,6 +809,7 @@ int rep386(int fv)
|
||||
else { DI+=2; SI+=2; }
|
||||
c--;
|
||||
cycles-=(is486)?7:9;
|
||||
reads += 2; total_cycles += is486 ? 7 : 9;
|
||||
setsub16(tempw,tempw2);
|
||||
tempz = (ZF_SET()) ? 1 : 0;
|
||||
}
|
||||
@@ -715,6 +828,7 @@ int rep386(int fv)
|
||||
else { DI+=4; SI+=4; }
|
||||
c--;
|
||||
cycles-=(is486)?7:9;
|
||||
reads_l += 2; total_cycles += is486 ? 7 : 9;
|
||||
setsub32(templ,templ2);
|
||||
tempz = (ZF_SET()) ? 1 : 0;
|
||||
}
|
||||
@@ -733,6 +847,7 @@ int rep386(int fv)
|
||||
else { EDI+=2; ESI+=2; }
|
||||
c--;
|
||||
cycles-=(is486)?7:9;
|
||||
reads += 2; total_cycles += is486 ? 7 : 9;
|
||||
setsub16(tempw,tempw2);
|
||||
tempz = (ZF_SET()) ? 1 : 0;
|
||||
}
|
||||
@@ -751,6 +866,7 @@ int rep386(int fv)
|
||||
else { EDI+=4; ESI+=4; }
|
||||
c--;
|
||||
cycles-=(is486)?7:9;
|
||||
reads_l += 2; total_cycles += is486 ? 7 : 9;
|
||||
setsub32(templ,templ2);
|
||||
tempz = (ZF_SET()) ? 1 : 0;
|
||||
}
|
||||
@@ -768,6 +884,7 @@ int rep386(int fv)
|
||||
else DI++;
|
||||
c--;
|
||||
cycles-=(is486)?4:5;
|
||||
writes++; total_cycles += is486 ? 4 : 5;
|
||||
ins++;
|
||||
if (cycles < cycles_end)
|
||||
break;
|
||||
@@ -786,6 +903,7 @@ int rep386(int fv)
|
||||
else EDI++;
|
||||
c--;
|
||||
cycles-=(is486)?4:5;
|
||||
writes++; total_cycles += is486 ? 4 : 5;
|
||||
ins++;
|
||||
if (cycles < cycles_end)
|
||||
break;
|
||||
@@ -804,6 +922,7 @@ int rep386(int fv)
|
||||
else DI+=2;
|
||||
c--;
|
||||
cycles-=(is486)?4:5;
|
||||
writes++; total_cycles += is486 ? 4 : 5;
|
||||
ins++;
|
||||
if (cycles < cycles_end)
|
||||
break;
|
||||
@@ -822,6 +941,7 @@ int rep386(int fv)
|
||||
else EDI+=2;
|
||||
c--;
|
||||
cycles-=(is486)?4:5;
|
||||
writes++; total_cycles += is486 ? 4 : 5;
|
||||
ins++;
|
||||
if (cycles < cycles_end)
|
||||
break;
|
||||
@@ -840,6 +960,7 @@ int rep386(int fv)
|
||||
else DI+=4;
|
||||
c--;
|
||||
cycles-=(is486)?4:5;
|
||||
writes_l++; total_cycles += is486 ? 4 : 5;
|
||||
ins++;
|
||||
if (cycles < cycles_end)
|
||||
break;
|
||||
@@ -858,6 +979,7 @@ int rep386(int fv)
|
||||
else EDI+=4;
|
||||
c--;
|
||||
cycles-=(is486)?4:5;
|
||||
writes_l++; total_cycles += is486 ? 4 : 5;
|
||||
ins++;
|
||||
if (cycles < cycles_end)
|
||||
break;
|
||||
@@ -877,6 +999,7 @@ int rep386(int fv)
|
||||
else SI++;
|
||||
c--;
|
||||
cycles-=5;
|
||||
reads++; total_cycles += 5;
|
||||
}
|
||||
if (c>0) { firstrepcycle=0; cpu_state.pc=ipc; }
|
||||
else firstrepcycle=1;
|
||||
@@ -892,6 +1015,7 @@ int rep386(int fv)
|
||||
else ESI++;
|
||||
c--;
|
||||
cycles-=5;
|
||||
reads++; total_cycles += 5;
|
||||
}
|
||||
if (c>0) { firstrepcycle=0; cpu_state.pc=ipc; }
|
||||
else firstrepcycle=1;
|
||||
@@ -907,6 +1031,7 @@ int rep386(int fv)
|
||||
else SI+=2;
|
||||
c--;
|
||||
cycles-=5;
|
||||
reads++; total_cycles += 5;
|
||||
}
|
||||
if (c>0) { firstrepcycle=0; cpu_state.pc=ipc; }
|
||||
else firstrepcycle=1;
|
||||
@@ -922,6 +1047,7 @@ int rep386(int fv)
|
||||
else SI+=4;
|
||||
c--;
|
||||
cycles-=5;
|
||||
reads_l++; total_cycles += 5;
|
||||
}
|
||||
if (c>0) { firstrepcycle=0; cpu_state.pc=ipc; }
|
||||
else firstrepcycle=1;
|
||||
@@ -937,6 +1063,7 @@ int rep386(int fv)
|
||||
else ESI+=2;
|
||||
c--;
|
||||
cycles-=5;
|
||||
reads++; total_cycles += 5;
|
||||
}
|
||||
if (c>0) { firstrepcycle=0; cpu_state.pc=ipc; }
|
||||
else firstrepcycle=1;
|
||||
@@ -952,6 +1079,7 @@ int rep386(int fv)
|
||||
else ESI+=4;
|
||||
c--;
|
||||
cycles-=5;
|
||||
reads_l++; total_cycles += 5;
|
||||
}
|
||||
if (c>0) { firstrepcycle=0; cpu_state.pc=ipc; }
|
||||
else firstrepcycle=1;
|
||||
@@ -971,6 +1099,7 @@ int rep386(int fv)
|
||||
else DI++;
|
||||
c--;
|
||||
cycles-=(is486)?5:8;
|
||||
reads++; total_cycles += is486 ? 5 : 8;
|
||||
ins++;
|
||||
if (cycles < cycles_end)
|
||||
break;
|
||||
@@ -995,6 +1124,7 @@ int rep386(int fv)
|
||||
else EDI++;
|
||||
c--;
|
||||
cycles-=(is486)?5:8;
|
||||
reads++; total_cycles += is486 ? 5 : 8;
|
||||
ins++;
|
||||
if (cycles < cycles_end)
|
||||
break;
|
||||
@@ -1017,6 +1147,7 @@ int rep386(int fv)
|
||||
else DI+=2;
|
||||
c--;
|
||||
cycles-=(is486)?5:8;
|
||||
reads++; total_cycles += is486 ? 5 : 8;
|
||||
ins++;
|
||||
if (cycles < cycles_end)
|
||||
break;
|
||||
@@ -1039,6 +1170,7 @@ int rep386(int fv)
|
||||
else DI+=4;
|
||||
c--;
|
||||
cycles-=(is486)?5:8;
|
||||
reads_l++; total_cycles += is486 ? 5 : 8;
|
||||
ins++;
|
||||
if (cycles < cycles_end)
|
||||
break;
|
||||
@@ -1061,6 +1193,7 @@ int rep386(int fv)
|
||||
else EDI+=2;
|
||||
c--;
|
||||
cycles-=(is486)?5:8;
|
||||
reads++; total_cycles += is486 ? 5 : 8;
|
||||
ins++;
|
||||
if (cycles < cycles_end)
|
||||
break;
|
||||
@@ -1083,6 +1216,7 @@ int rep386(int fv)
|
||||
else EDI+=4;
|
||||
c--;
|
||||
cycles-=(is486)?5:8;
|
||||
reads_l++; total_cycles += is486 ? 5 : 8;
|
||||
ins++;
|
||||
if (cycles < cycles_end)
|
||||
break;
|
||||
@@ -1101,6 +1235,7 @@ int rep386(int fv)
|
||||
if (rep32&0x200) ECX=c;
|
||||
else CX=c;
|
||||
CPU_BLOCK_END();
|
||||
PREFETCH_RUN(total_cycles, 1, -1, reads, reads_l, writes, writes_l, 0);
|
||||
return cpu_state.abrt;
|
||||
//pclog("rep cpu_block_end=%d %p\n", cpu_block_end, (void *)&cpu_block_end);
|
||||
// if (output) pclog("%03X %03X\n",rep32,use32);
|
||||
@@ -1310,7 +1445,7 @@ void exec386_dynarec(int cycs)
|
||||
if (page->code_present_mask & mask)
|
||||
{
|
||||
/*Walk page tree to see if we find the correct block*/
|
||||
codeblock_t *new_block = codeblock_tree_find(phys_addr, cs);
|
||||
codeblock_t *new_block = codeblock_tree_find(phys_addr, cs);
|
||||
if (new_block)
|
||||
{
|
||||
valid_block = (new_block->pc == cs + cpu_state.pc) && (new_block->_cs == cs) &&
|
||||
@@ -1559,6 +1694,7 @@ inrecomp=0;
|
||||
{
|
||||
cpu_state.abrt = 0;
|
||||
softresetx86();
|
||||
cpu_set_edx();
|
||||
pclog("Triple fault - reset\n");
|
||||
}
|
||||
}
|
||||
@@ -1597,10 +1733,18 @@ inrecomp=0;
|
||||
flags_rebuild();
|
||||
if (msw&1)
|
||||
{
|
||||
/* if (temp == 0x0E)
|
||||
{
|
||||
pclog("Servicing FDC interupt (p)!\n");
|
||||
} */
|
||||
pmodeint(temp,0);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* if (temp == 0x0E)
|
||||
{
|
||||
pclog("Servicing FDC interupt (r)!\n");
|
||||
} */
|
||||
writememw(ss,(SP-2)&0xFFFF,flags);
|
||||
writememw(ss,(SP-4)&0xFFFF,CS);
|
||||
writememw(ss,(SP-6)&0xFFFF,cpu_state.pc);
|
||||
@@ -1613,6 +1757,10 @@ inrecomp=0;
|
||||
loadcs(readmemw(0,addr+2));
|
||||
}
|
||||
}
|
||||
/* else
|
||||
{
|
||||
pclog("Servicing pending interrupt 0xFF (!)!\n");
|
||||
} */
|
||||
}
|
||||
}
|
||||
timer_end_period(cycles << TIMER_SHIFT);
|
||||
|
||||
@@ -28,6 +28,7 @@ static inline void fetch_ea_32_long(uint32_t rmdat)
|
||||
if (writelookup2[addr >> 12] != -1)
|
||||
eal_w = (uint32_t *)(writelookup2[addr >> 12] + addr);
|
||||
}
|
||||
cpu_state.last_ea = cpu_state.eaaddr;
|
||||
}
|
||||
|
||||
static inline void fetch_ea_16_long(uint32_t rmdat)
|
||||
@@ -43,12 +44,16 @@ static inline void fetch_ea_16_long(uint32_t rmdat)
|
||||
if (writelookup2[addr >> 12] != -1)
|
||||
eal_w = (uint32_t *)(writelookup2[addr >> 12] + addr);
|
||||
}
|
||||
cpu_state.last_ea = cpu_state.eaaddr;
|
||||
}
|
||||
|
||||
#define fetch_ea_16(rmdat) cpu_state.pc++; if (cpu_mod != 3) fetch_ea_16_long(rmdat);
|
||||
#define fetch_ea_32(rmdat) cpu_state.pc++; if (cpu_mod != 3) fetch_ea_32_long(rmdat);
|
||||
|
||||
|
||||
#define PREFETCH_RUN(instr_cycles, bytes, modrm, reads, read_ls, writes, write_ls, ea32)
|
||||
#define PREFETCH_PREFIX()
|
||||
#define PREFETCH_FLUSH()
|
||||
|
||||
#define OP_TABLE(name) dynarec_ops_ ## name
|
||||
#define CLOCK_CYCLES(c)
|
||||
|
||||
@@ -175,6 +175,8 @@ static int op0F_w_a16(uint32_t fetchdat)
|
||||
cpu_state.pc++;
|
||||
|
||||
// pclog("A16W: 0F %02X\n", opcode);
|
||||
PREFETCH_PREFIX();
|
||||
|
||||
return x86_opcodes_0f[opcode](fetchdat >> 8);
|
||||
}
|
||||
static int op0F_l_a16(uint32_t fetchdat)
|
||||
@@ -184,6 +186,8 @@ static int op0F_l_a16(uint32_t fetchdat)
|
||||
cpu_state.pc++;
|
||||
|
||||
// pclog("A16L: 0F %02X\n", opcode);
|
||||
PREFETCH_PREFIX();
|
||||
|
||||
return x86_opcodes_0f[opcode | 0x100](fetchdat >> 8);
|
||||
}
|
||||
static int op0F_w_a32(uint32_t fetchdat)
|
||||
@@ -193,6 +197,8 @@ static int op0F_w_a32(uint32_t fetchdat)
|
||||
cpu_state.pc++;
|
||||
|
||||
// pclog("A32W: 0F %02X\n", opcode);
|
||||
PREFETCH_PREFIX();
|
||||
|
||||
return x86_opcodes_0f[opcode | 0x200](fetchdat >> 8);
|
||||
}
|
||||
static int op0F_l_a32(uint32_t fetchdat)
|
||||
@@ -202,6 +208,8 @@ static int op0F_l_a32(uint32_t fetchdat)
|
||||
cpu_state.pc++;
|
||||
|
||||
// pclog("A32L: 0F %02X\n", opcode);
|
||||
PREFETCH_PREFIX();
|
||||
|
||||
return x86_opcodes_0f[opcode | 0x300](fetchdat >> 8);
|
||||
}
|
||||
|
||||
|
||||
@@ -101,7 +101,6 @@ int oldcpl;
|
||||
|
||||
int tempc;
|
||||
uint8_t opcode;
|
||||
int times=0;
|
||||
uint16_t pc2,pc3;
|
||||
int noint=0;
|
||||
|
||||
@@ -640,6 +639,8 @@ void resetx86()
|
||||
cr0 = 1 << 30;
|
||||
else
|
||||
cr0 = 0;
|
||||
cpu_cache_int_enabled = 0;
|
||||
cpu_update_waitstates();
|
||||
cr4 = 0;
|
||||
eflags=0;
|
||||
cgate32=0;
|
||||
@@ -667,6 +668,7 @@ void resetx86()
|
||||
x86seg_reset();
|
||||
codegen_reset();
|
||||
x86_was_reset = 1;
|
||||
port_92_clear_reset();
|
||||
}
|
||||
|
||||
void softresetx86()
|
||||
@@ -689,6 +691,7 @@ void softresetx86()
|
||||
idt.base = 0;
|
||||
x86seg_reset();
|
||||
x86_was_reset = 1;
|
||||
port_92_clear_reset();
|
||||
}
|
||||
|
||||
static void setznp8(uint8_t val)
|
||||
|
||||
@@ -8,8 +8,8 @@ OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o acerm3a.o aha154x
|
||||
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_imd.o disc_img.o disc_random.o disc_td0.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_amstrad.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 \
|
||||
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 opti495.o pc.o pc87306.o pci.o pic.o piix.o pit.o ppi.o ps1.o rom.o rtc.o \
|
||||
scat.o scattergather.o scsi.o scsi_cdrom.o serial.o sis496.o sis85c471.o sio.o sound.o sound_ad1848.o sound_adlib.o sound_adlibgold.o sound_cms.o \
|
||||
sound_dbopl.o sound_emu8k.o sound_gus.o sound_mpu401_uart.o sound_opl.o sound_pas16.o sound_ps1.o sound_pssj.o sound_resid.o \
|
||||
sound_sb.o sound_sb_dsp.o sound_sn76489.o sound_speaker.o sound_ssi2001.o sound_wss.o sound_ym7128.o \
|
||||
@@ -19,7 +19,7 @@ OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o acerm3a.o aha154x
|
||||
vid_olivetti_m24.o vid_oti067.o vid_paradise.o vid_pc1512.o vid_pc1640.o vid_pc200.o \
|
||||
vid_pcjr.o vid_ps1_svga.o vid_s3.o vid_s3_virge.o vid_sdac_ramdac.o vid_stg_ramdac.o vid_svga.o \
|
||||
vid_svga_render.o vid_tandy.o vid_tandysl.o vid_tgui9440.o vid_tkd8001_ramdac.o vid_tvga.o vid_unk_ramdac.o \
|
||||
vid_vga.o vid_voodoo.o video.o wd76c10.o win.o win-config.o win-d3d.o win-d3d-fs.o win-ddraw.o \
|
||||
vid_vga.o vid_wy700.o vid_voodoo.o video.o w83877f.o wd76c10.o win.o win-config.o win-d3d.o win-d3d-fs.o win-ddraw.o \
|
||||
win-ddraw-fs.o win-ddraw-screenshot.o win-deviceconfig.o win-hdconf.o win-joystick.o win-joystickconfig.o win-keyboard.o win-midi.o win-mouse.o \
|
||||
win-status.o win-video.o x86seg.o x87.o xtide.o pc.res
|
||||
DBOBJ = dbopl.o nukedopl.o vid_cga_comp.o
|
||||
|
||||
@@ -8,8 +8,8 @@ OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o acerm3a.o aha154x
|
||||
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_imd.o disc_img.o disc_random.o disc_td0.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_amstrad.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 \
|
||||
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 opti495.o pc.o pc87306.o pci.o pic.o piix.o pit.o ppi.o ps1.o rom.o rtc.o \
|
||||
scat.o scattergather.o scsi.o scsi_cdrom.o serial.o sis496.o sis85c471.o sio.o sound.o sound_ad1848.o sound_adlib.o sound_adlibgold.o sound_cms.o \
|
||||
sound_dbopl.o sound_emu8k.o sound_gus.o sound_mpu401_uart.o sound_opl.o sound_pas16.o sound_ps1.o sound_pssj.o sound_resid.o \
|
||||
sound_sb.o sound_sb_dsp.o sound_sn76489.o sound_speaker.o sound_ssi2001.o sound_wss.o sound_ym7128.o \
|
||||
@@ -19,7 +19,7 @@ OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o acerm3a.o aha154x
|
||||
vid_olivetti_m24.o vid_oti067.o vid_paradise.o vid_pc1512.o vid_pc1640.o vid_pc200.o \
|
||||
vid_pcjr.o vid_ps1_svga.o vid_s3.o vid_s3_virge.o vid_sdac_ramdac.o vid_stg_ramdac.o vid_svga.o \
|
||||
vid_svga_render.o vid_tandy.o vid_tandysl.o vid_tgui9440.o vid_tkd8001_ramdac.o vid_tvga.o vid_unk_ramdac.o \
|
||||
vid_vga.o vid_voodoo.o video.o wd76c10.o win.o win-config.o win-d3d.o win-d3d-fs.o win-ddraw.o \
|
||||
vid_vga.o vid_wy700.o vid_voodoo.o video.o w83877f.o wd76c10.o win.o win-config.o win-d3d.o win-d3d-fs.o win-ddraw.o \
|
||||
win-ddraw-fs.o win-ddraw-screenshot.o win-deviceconfig.o win-hdconf.o win-joystick.o win-joystickconfig.o win-keyboard.o win-midi.o win-mouse.o \
|
||||
win-status.o win-video.o x86seg.o x87.o xtide.o pc.res
|
||||
DBOBJ = dbopl.o nukedopl.o vid_cga_comp.o
|
||||
|
||||
865
src/aha154x.c
865
src/aha154x.c
File diff suppressed because it is too large
Load Diff
@@ -1 +1 @@
|
||||
extern void AdaptecInit(uint8_t Id);
|
||||
extern void AdaptecInit();
|
||||
@@ -1,6 +1,3 @@
|
||||
/* Copyright holders: Sarah Walker
|
||||
see COPYING for more details
|
||||
*/
|
||||
#include "ibm.h"
|
||||
#include "io.h"
|
||||
#include "keyboard.h"
|
||||
@@ -38,10 +35,78 @@ void amstrad_write(uint16_t port, uint8_t val, void *priv)
|
||||
}
|
||||
}
|
||||
|
||||
static uint8_t mousex, mousey;
|
||||
static void amstrad_mouse_write(uint16_t addr, uint8_t val, void *p)
|
||||
{
|
||||
// pclog("Write mouse %04X %02X %04X:%04X\n", addr, val, CS, pc);
|
||||
if (addr == 0x78)
|
||||
mousex = 0;
|
||||
else
|
||||
mousey = 0;
|
||||
}
|
||||
|
||||
static uint8_t amstrad_mouse_read(uint16_t addr, void *p)
|
||||
{
|
||||
// printf("Read mouse %04X %04X:%04X %02X\n", addr, CS, pc, (addr == 0x78) ? mousex : mousey);
|
||||
if (addr == 0x78)
|
||||
return mousex;
|
||||
return mousey;
|
||||
}
|
||||
|
||||
typedef struct mouse_amstrad_t
|
||||
{
|
||||
int oldb;
|
||||
} mouse_amstrad_t;
|
||||
|
||||
static void mouse_amstrad_poll(int x, int y, int z, int b, void *p)
|
||||
{
|
||||
mouse_amstrad_t *mouse = (mouse_amstrad_t *)p;
|
||||
|
||||
mousex += x;
|
||||
mousey -= y;
|
||||
|
||||
if ((b & 1) && !(mouse->oldb & 1))
|
||||
keyboard_send(0x7e);
|
||||
if ((b & 2) && !(mouse->oldb & 2))
|
||||
keyboard_send(0x7d);
|
||||
if (!(b & 1) && (mouse->oldb & 1))
|
||||
keyboard_send(0xfe);
|
||||
if (!(b & 2) && (mouse->oldb & 2))
|
||||
keyboard_send(0xfd);
|
||||
|
||||
mouse->oldb = b;
|
||||
}
|
||||
|
||||
static void *mouse_amstrad_init()
|
||||
{
|
||||
mouse_amstrad_t *mouse = (mouse_amstrad_t *)malloc(sizeof(mouse_amstrad_t));
|
||||
memset(mouse, 0, sizeof(mouse_amstrad_t));
|
||||
|
||||
return mouse;
|
||||
}
|
||||
|
||||
static void mouse_amstrad_close(void *p)
|
||||
{
|
||||
mouse_amstrad_t *mouse = (mouse_amstrad_t *)p;
|
||||
|
||||
free(mouse);
|
||||
}
|
||||
|
||||
mouse_t mouse_amstrad =
|
||||
{
|
||||
"Amstrad mouse",
|
||||
mouse_amstrad_init,
|
||||
mouse_amstrad_close,
|
||||
mouse_amstrad_poll,
|
||||
MOUSE_TYPE_AMSTRAD
|
||||
};
|
||||
|
||||
void amstrad_init()
|
||||
{
|
||||
lpt2_remove_ams();
|
||||
|
||||
io_sethandler(0x0078, 0x0001, amstrad_mouse_read, NULL, NULL, amstrad_mouse_write, NULL, NULL, NULL);
|
||||
io_sethandler(0x007a, 0x0001, amstrad_mouse_read, NULL, NULL, amstrad_mouse_write, NULL, NULL, NULL);
|
||||
io_sethandler(0x0379, 0x0002, amstrad_read, NULL, NULL, NULL, NULL, NULL, NULL);
|
||||
io_sethandler(0xdead, 0x0001, amstrad_read, NULL, NULL, amstrad_write, NULL, NULL, NULL);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
/* Copyright holders: Sarah Walker
|
||||
see COPYING for more details
|
||||
*/
|
||||
void amstrad_init();
|
||||
|
||||
extern mouse_t mouse_amstrad;
|
||||
|
||||
@@ -420,16 +420,6 @@ static void ioctl_load(void)
|
||||
cdrom_capacity = ioctl_get_last_block(0, 0, 4096, 0);
|
||||
}
|
||||
|
||||
static void ioctl_readsector(uint8_t *b, int sector)
|
||||
{
|
||||
int cdrom = open("/dev/cdrom", O_RDONLY|O_NONBLOCK);
|
||||
if (cdrom <= 0)
|
||||
return;
|
||||
lseek(cdrom, sector*2048, SEEK_SET);
|
||||
read(cdrom, b, 2048);
|
||||
close(cdrom);
|
||||
}
|
||||
|
||||
union
|
||||
{
|
||||
struct cdrom_msf *msf;
|
||||
@@ -441,6 +431,11 @@ static int lba_to_msf(int lba)
|
||||
return (((lba / 75) / 60) << 16) + (((lba / 75) % 60) << 8) + (lba % 75);
|
||||
}
|
||||
|
||||
static int ioctl_sector_data_type(int sector, int ismsf)
|
||||
{
|
||||
return 2; /* Always Mode 1 */
|
||||
}
|
||||
|
||||
static void ioctl_readsector_raw(uint8_t *b, int sector)
|
||||
{
|
||||
int err;
|
||||
@@ -711,7 +706,10 @@ static ATAPI ioctl_atapi=
|
||||
ioctl_readtoc_session,
|
||||
ioctl_readtoc_raw,
|
||||
ioctl_getcurrentsubchannel,
|
||||
ioctl_readsector,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
ioctl_sector_data_type,
|
||||
ioctl_readsector_raw,
|
||||
ioctl_playaudio,
|
||||
ioctl_seek,
|
||||
|
||||
@@ -424,23 +424,6 @@ static void ioctl_load(void)
|
||||
cdrom_capacity = ioctl_get_last_block(0, 0, 4096, 0);
|
||||
}
|
||||
|
||||
static void ioctl_readsector(uint8_t *b, int sector)
|
||||
{
|
||||
LARGE_INTEGER pos;
|
||||
long size;
|
||||
if (!cdrom_drive) return;
|
||||
|
||||
if (ioctl_cd_state == CD_PLAYING)
|
||||
return;
|
||||
|
||||
ioctl_cd_state = CD_STOPPED;
|
||||
pos.QuadPart=sector*2048;
|
||||
ioctl_open(0);
|
||||
SetFilePointer(hIOCTL,pos.LowPart,&pos.HighPart,FILE_BEGIN);
|
||||
ReadFile(hIOCTL,b,2048,&size,NULL);
|
||||
ioctl_close();
|
||||
}
|
||||
|
||||
static int is_track_audio(uint32_t pos)
|
||||
{
|
||||
int c;
|
||||
@@ -490,137 +473,209 @@ static int ioctl_is_track_audio(uint32_t pos, int ismsf)
|
||||
return is_track_audio(pos);
|
||||
}
|
||||
|
||||
/* Direct SCSI read in MSF mode. */
|
||||
int SCSIReadMSF(uint8_t *b, int sector)
|
||||
static int SCSICommand(const UCHAR *cdb, UCHAR *buf, uint32_t len)
|
||||
{
|
||||
HANDLE fh;
|
||||
DWORD ioctl_bytes;
|
||||
DWORD out_size;
|
||||
int ioctl_rv = 0;
|
||||
UCHAR tbuf[2856];
|
||||
struct sptd_with_sense
|
||||
{
|
||||
SCSI_PASS_THROUGH_DIRECT s;
|
||||
UCHAR sense[128];
|
||||
} sptd;
|
||||
|
||||
memset(&sptd, 0, sizeof(sptd));
|
||||
sptd.s.Length = sizeof(sptd.s);
|
||||
// sptd.s.CdbLength = sizeof(cdb);
|
||||
sptd.s.CdbLength = 12;
|
||||
sptd.s.DataIn = SCSI_IOCTL_DATA_IN;
|
||||
sptd.s.TimeOutValue = 30;
|
||||
sptd.s.DataBuffer = tbuf;
|
||||
sptd.s.DataTransferLength = len;
|
||||
sptd.s.SenseInfoLength = sizeof(sptd.sense);
|
||||
sptd.s.SenseInfoOffset = offsetof(struct sptd_with_sense, sense);
|
||||
|
||||
// memcpy(sptd.s.Cdb, cdb, sizeof(cdb));
|
||||
memcpy(sptd.s.Cdb, cdb, 12);
|
||||
ioctl_rv = DeviceIoControl(hIOCTL, IOCTL_SCSI_PASS_THROUGH_DIRECT, &sptd, sizeof(sptd), &sptd, sizeof(sptd), &ioctl_bytes, NULL);
|
||||
memcpy(buf, sptd.s.DataBuffer, len);
|
||||
|
||||
return ioctl_rv;
|
||||
}
|
||||
|
||||
static void ioctl_read_capacity(uint8_t *b)
|
||||
{
|
||||
const UCHAR cdb[] = { 0x25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
|
||||
UCHAR buf[16];
|
||||
|
||||
ioctl_open(0);
|
||||
|
||||
SCSICommand(cdb, buf, 16);
|
||||
|
||||
memcpy(b, buf, 8);
|
||||
|
||||
ioctl_close();
|
||||
}
|
||||
|
||||
static void ioctl_read_header(uint8_t *in_cdb, uint8_t *b)
|
||||
{
|
||||
const UCHAR cdb[12];
|
||||
UCHAR buf[16];
|
||||
|
||||
ioctl_open(0);
|
||||
|
||||
memcpy(cdb, in_cdb, 12);
|
||||
SCSICommand(cdb, buf, 16);
|
||||
|
||||
memcpy(b, buf, 8);
|
||||
|
||||
ioctl_close();
|
||||
}
|
||||
|
||||
static void ioctl_read_disc_information(uint8_t *b)
|
||||
{
|
||||
const UCHAR cdb[] = { 0x51, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
|
||||
UCHAR buf[68];
|
||||
|
||||
ioctl_open(0);
|
||||
|
||||
SCSICommand(cdb, buf, 68);
|
||||
|
||||
memcpy(b, buf, 34);
|
||||
|
||||
ioctl_close();
|
||||
}
|
||||
|
||||
static int SCSIReadCommon(const UCHAR *cdb_0, const UCHAR *cdb_1, const UCHAR *cdb_2, const UCHAR *cdb_4, uint8_t *b, UCHAR *buf)
|
||||
{
|
||||
int ioctl_rv;
|
||||
|
||||
ioctl_open(0);
|
||||
|
||||
/* Fill the buffer with zeroes. */
|
||||
memset(b, 0, 2856);
|
||||
|
||||
ioctl_rv = SCSICommand(cdb_0, buf, 2856);
|
||||
memcpy(b, buf, 2648);
|
||||
|
||||
/* Next, try to read RAW subchannel data. */
|
||||
ioctl_rv += SCSICommand(cdb_1, buf, 2856);
|
||||
memcpy(b + 2648, buf + 2648, 96);
|
||||
|
||||
/* Next, try to read Q subchannel data. */
|
||||
ioctl_rv += SCSICommand(cdb_2, buf, 2856);
|
||||
memcpy(b + 2648 + 96, buf + 2648, 16);
|
||||
|
||||
/* Next, try to read R - W subchannel data. */
|
||||
ioctl_rv += SCSICommand(cdb_4, buf, 2856);
|
||||
memcpy(b + 2648 + 96 + 16, buf + 2648, 96);
|
||||
|
||||
ioctl_close();
|
||||
|
||||
// pclog("rv: %i\n", ioctl_rv);
|
||||
|
||||
return ioctl_rv;
|
||||
}
|
||||
|
||||
/* Direct SCSI read in MSF mode. */
|
||||
static int SCSIReadMSF(uint8_t *b, int sector)
|
||||
{
|
||||
const UCHAR cdb_0[] = { 0xB9, 0, 0, ((sector >> 16) & 0xff), ((sector >> 8) & 0xff), (sector & 0xff), ((sector >> 16) & 0xff), ((sector >> 8) & 0xff), (sector & 0xff), 0xFC, 0, 0 };
|
||||
const UCHAR cdb_1[] = { 0xB9, 0, 0, ((sector >> 16) & 0xff), ((sector >> 8) & 0xff), (sector & 0xff), ((sector >> 16) & 0xff), ((sector >> 8) & 0xff), (sector & 0xff), 0xFC, 1, 0 };
|
||||
const UCHAR cdb_2[] = { 0xB9, 0, 0, ((sector >> 16) & 0xff), ((sector >> 8) & 0xff), (sector & 0xff), ((sector >> 16) & 0xff), ((sector >> 8) & 0xff), (sector & 0xff), 0xFC, 2, 0 };
|
||||
const UCHAR cdb_4[] = { 0xB9, 0, 0, ((sector >> 16) & 0xff), ((sector >> 8) & 0xff), (sector & 0xff), ((sector >> 16) & 0xff), ((sector >> 8) & 0xff), (sector & 0xff), 0xFC, 4, 0 };
|
||||
UCHAR buf[2856];
|
||||
struct sptd_with_sense
|
||||
{
|
||||
SCSI_PASS_THROUGH_DIRECT s;
|
||||
UCHAR sense[128];
|
||||
} sptd;
|
||||
|
||||
ioctl_open(0);
|
||||
|
||||
memset(&sptd, 0, sizeof(sptd));
|
||||
sptd.s.Length = sizeof(sptd.s);
|
||||
sptd.s.CdbLength = sizeof(cdb_0); /* All 4 of our CDB's are identically sized, therefore we can take this shortcut. */
|
||||
sptd.s.DataIn = SCSI_IOCTL_DATA_IN;
|
||||
sptd.s.TimeOutValue = 30;
|
||||
sptd.s.DataBuffer = buf;
|
||||
sptd.s.DataTransferLength = 2856;
|
||||
sptd.s.SenseInfoLength = sizeof(sptd.sense);
|
||||
sptd.s.SenseInfoOffset = offsetof(struct sptd_with_sense, sense);
|
||||
|
||||
/* Fill the buffer with zeroes. */
|
||||
memset(b, 0, 2856);
|
||||
|
||||
/* First, read without subchannel data so we at least have *SOMETHING*. */
|
||||
memcpy(sptd.s.Cdb, cdb_0, sizeof(cdb_0));
|
||||
ioctl_rv = DeviceIoControl(hIOCTL, IOCTL_SCSI_PASS_THROUGH_DIRECT, &sptd, sizeof(sptd), &sptd, sizeof(sptd), &ioctl_bytes, NULL);
|
||||
// pclog("Read (%i) without subchannel data: %s\n", sector, ioctl_rv ? "SUCCESS" : "FAILURE");
|
||||
memcpy(b, sptd.s.DataBuffer, 2648);
|
||||
|
||||
/* Next, try to read RAW subchannel data. */
|
||||
memcpy(sptd.s.Cdb, cdb_1, sizeof(cdb_1));
|
||||
ioctl_rv += DeviceIoControl(hIOCTL, IOCTL_SCSI_PASS_THROUGH_DIRECT, &sptd, sizeof(sptd), &sptd, sizeof(sptd), &ioctl_bytes, NULL);
|
||||
// pclog("Read (%i) with RAW subchannel data: %s\n", sector, ioctl_rv ? "SUCCESS" : "FAILURE");
|
||||
memcpy(b + 2648, sptd.s.DataBuffer + 2648, 96);
|
||||
|
||||
/* Next, try to read Q subchannel data. */
|
||||
memcpy(sptd.s.Cdb, cdb_2, sizeof(cdb_2));
|
||||
ioctl_rv += DeviceIoControl(hIOCTL, IOCTL_SCSI_PASS_THROUGH_DIRECT, &sptd, sizeof(sptd), &sptd, sizeof(sptd), &ioctl_bytes, NULL);
|
||||
// pclog("Read (%i) with Q subchannel data: %s\n", sector, ioctl_rv ? "SUCCESS" : "FAILURE");
|
||||
memcpy(b + 2648 + 96, sptd.s.DataBuffer + 2648, 16);
|
||||
|
||||
/* Next, try to read R - W subchannel data. */
|
||||
memcpy(sptd.s.Cdb, cdb_4, sizeof(cdb_4));
|
||||
ioctl_rv += DeviceIoControl(hIOCTL, IOCTL_SCSI_PASS_THROUGH_DIRECT, &sptd, sizeof(sptd), &sptd, sizeof(sptd), &ioctl_bytes, NULL);
|
||||
// pclog("Read (%i) with R - W subchannel data: %s\n", sector, ioctl_rv ? "SUCCESS" : "FAILURE");
|
||||
memcpy(b + 2648 + 96 + 16, sptd.s.DataBuffer + 2648, 96);
|
||||
|
||||
ioctl_close();
|
||||
|
||||
return ioctl_rv;
|
||||
return SCSIReadCommon(cdb_0, cdb_1, cdb_2, cdb_4, b, buf);
|
||||
}
|
||||
|
||||
/* Direct SCSI read in LBA mode. */
|
||||
void SCSIRead(uint8_t *b, int sector)
|
||||
static void SCSIRead(uint8_t *b, int sector)
|
||||
{
|
||||
HANDLE fh;
|
||||
DWORD ioctl_bytes;
|
||||
DWORD out_size;
|
||||
BOOL ioctl_rv;
|
||||
const UCHAR cdb_0[] = { 0xBE, 0, (sector >> 24), ((sector >> 16) & 0xff), ((sector >> 8) & 0xff), (sector & 0xff), 0, 0, 1, 0xFC, 0, 0 };
|
||||
const UCHAR cdb_1[] = { 0xBE, 0, (sector >> 24), ((sector >> 16) & 0xff), ((sector >> 8) & 0xff), (sector & 0xff), 0, 0, 1, 0xFC, 1, 0 };
|
||||
const UCHAR cdb_2[] = { 0xBE, 0, (sector >> 24), ((sector >> 16) & 0xff), ((sector >> 8) & 0xff), (sector & 0xff), 0, 0, 1, 0xFC, 2, 0 };
|
||||
const UCHAR cdb_4[] = { 0xBE, 0, (sector >> 24), ((sector >> 16) & 0xff), ((sector >> 8) & 0xff), (sector & 0xff), 0, 0, 1, 0xFC, 4, 0 };
|
||||
UCHAR buf[2856];
|
||||
struct sptd_with_sense
|
||||
|
||||
SCSIReadCommon(cdb_0, cdb_1, cdb_2, cdb_4, b, buf);
|
||||
return;
|
||||
}
|
||||
|
||||
static uint32_t msf_to_lba32(int lba)
|
||||
{
|
||||
int m = (lba >> 16) & 0xff;
|
||||
int s = (lba >> 8) & 0xff;
|
||||
int f = lba & 0xff;
|
||||
return (m * 60 * 75) + (s * 75) + f;
|
||||
}
|
||||
|
||||
static int ioctl_get_type(UCHAR *cdb, UCHAR *buf)
|
||||
{
|
||||
int i = 0;
|
||||
int ioctl_rv = 0;
|
||||
|
||||
for (i = 2; i <= 5; i++)
|
||||
{
|
||||
SCSI_PASS_THROUGH_DIRECT s;
|
||||
UCHAR sense[128];
|
||||
} sptd;
|
||||
cdb[1] = i << 2;
|
||||
ioctl_rv = SCSICommand(cdb, buf, 2352);
|
||||
if (ioctl_rv)
|
||||
{
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ioctl_sector_data_type(int sector, int ismsf)
|
||||
{
|
||||
int ioctl_rv = 0;
|
||||
const UCHAR cdb_lba[] = { 0xBE, 0, (sector >> 24), ((sector >> 16) & 0xff), ((sector >> 8) & 0xff), (sector & 0xff), 0, 0, 1, 0x10, 0, 0 };
|
||||
const UCHAR cdb_msf[] = { 0xB9, 0, 0, ((sector >> 16) & 0xff), ((sector >> 8) & 0xff), (sector & 0xff), ((sector >> 16) & 0xff), ((sector >> 8) & 0xff), (sector & 0xff), 0x10, 0, 0 };
|
||||
UCHAR buf[2352];
|
||||
|
||||
ioctl_open(0);
|
||||
|
||||
memset(&sptd, 0, sizeof(sptd));
|
||||
sptd.s.Length = sizeof(sptd.s);
|
||||
sptd.s.CdbLength = sizeof(cdb_0); /* All 4 of our CDB's are identically sized, therefore we can take this shortcut. */
|
||||
sptd.s.DataIn = SCSI_IOCTL_DATA_IN;
|
||||
sptd.s.TimeOutValue = 30;
|
||||
sptd.s.DataBuffer = buf;
|
||||
sptd.s.DataTransferLength = 2856;
|
||||
sptd.s.SenseInfoLength = sizeof(sptd.sense);
|
||||
sptd.s.SenseInfoOffset = offsetof(struct sptd_with_sense, sense);
|
||||
|
||||
/* Fill the buffer with zeroes. */
|
||||
memset(b, 0, 2856);
|
||||
if (ioctl_is_track_audio(sector, ismsf))
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* First, read without subchannel data so we at least have *SOMETHING*. */
|
||||
memcpy(sptd.s.Cdb, cdb_0, sizeof(cdb_0));
|
||||
ioctl_rv = DeviceIoControl(hIOCTL, IOCTL_SCSI_PASS_THROUGH_DIRECT, &sptd, sizeof(sptd), &sptd, sizeof(sptd), &ioctl_bytes, NULL);
|
||||
// pclog("Read (%i) without subchannel data: %s\n", sector, ioctl_rv ? "SUCCESS" : "FAILURE");
|
||||
memcpy(b, sptd.s.DataBuffer, 2648);
|
||||
|
||||
/* Next, try to read RAW subchannel data. */
|
||||
memcpy(sptd.s.Cdb, cdb_1, sizeof(cdb_1));
|
||||
ioctl_rv = DeviceIoControl(hIOCTL, IOCTL_SCSI_PASS_THROUGH_DIRECT, &sptd, sizeof(sptd), &sptd, sizeof(sptd), &ioctl_bytes, NULL);
|
||||
// pclog("Read (%i) with RAW subchannel data: %s\n", sector, ioctl_rv ? "SUCCESS" : "FAILURE");
|
||||
memcpy(b + 2648, sptd.s.DataBuffer + 2648, 96);
|
||||
|
||||
/* Next, try to read Q subchannel data. */
|
||||
memcpy(sptd.s.Cdb, cdb_2, sizeof(cdb_2));
|
||||
ioctl_rv = DeviceIoControl(hIOCTL, IOCTL_SCSI_PASS_THROUGH_DIRECT, &sptd, sizeof(sptd), &sptd, sizeof(sptd), &ioctl_bytes, NULL);
|
||||
// pclog("Read (%i) with Q subchannel data: %s\n", sector, ioctl_rv ? "SUCCESS" : "FAILURE");
|
||||
memcpy(b + 2648 + 96, sptd.s.DataBuffer + 2648, 16);
|
||||
|
||||
/* Next, try to read R - W subchannel data. */
|
||||
memcpy(sptd.s.Cdb, cdb_4, sizeof(cdb_4));
|
||||
ioctl_rv = DeviceIoControl(hIOCTL, IOCTL_SCSI_PASS_THROUGH_DIRECT, &sptd, sizeof(sptd), &sptd, sizeof(sptd), &ioctl_bytes, NULL);
|
||||
// pclog("Read (%i) with R - W subchannel data: %s\n", sector, ioctl_rv ? "SUCCESS" : "FAILURE");
|
||||
memcpy(b + 2648 + 96 + 16, sptd.s.DataBuffer + 2648, 96);
|
||||
if (ismsf)
|
||||
{
|
||||
ioctl_rv = ioctl_get_type(cdb_msf, buf);
|
||||
}
|
||||
else
|
||||
{
|
||||
ioctl_rv = ioctl_get_type(cdb_lba, buf);
|
||||
}
|
||||
|
||||
if (ioctl_rv)
|
||||
{
|
||||
ioctl_close();
|
||||
return ioctl_rv;
|
||||
}
|
||||
|
||||
if (ismsf)
|
||||
{
|
||||
sector = msf_to_lba32(sector);
|
||||
if (sector < 150)
|
||||
{
|
||||
ioctl_close();
|
||||
return 0;
|
||||
}
|
||||
sector -= 150;
|
||||
ioctl_rv = ioctl_get_type(cdb_lba, buf);
|
||||
}
|
||||
|
||||
ioctl_close();
|
||||
|
||||
return;
|
||||
return ioctl_rv;
|
||||
}
|
||||
|
||||
static void ioctl_readsector_raw(uint8_t *b, int sector, int ismsf)
|
||||
{
|
||||
RAW_READ_INFO in;
|
||||
LARGE_INTEGER pos;
|
||||
DWORD count = 0;
|
||||
long size;
|
||||
uint32_t temp;
|
||||
if (!cdrom_drive) return;
|
||||
if (ioctl_cd_state == CD_PLAYING)
|
||||
return;
|
||||
@@ -629,16 +684,13 @@ static void ioctl_readsector_raw(uint8_t *b, int sector, int ismsf)
|
||||
{
|
||||
if (!SCSIReadMSF(b, sector))
|
||||
{
|
||||
int m = (sector >> 16) & 0xff;
|
||||
int s = (sector >> 8) & 0xff;
|
||||
int f = sector & 0xff;
|
||||
sector = (m * 60 * 75) + (s * 75) + f;
|
||||
sector = msf_to_lba32(sector);
|
||||
if (sector < 150)
|
||||
{
|
||||
memset(b, 0, 2856);
|
||||
return;
|
||||
}
|
||||
sector += 150;
|
||||
sector -= 150;
|
||||
SCSIRead(b, sector);
|
||||
}
|
||||
}
|
||||
@@ -805,7 +857,15 @@ static int ioctl_readtoc_raw(unsigned char *b, int maxlen)
|
||||
|
||||
static uint32_t ioctl_size()
|
||||
{
|
||||
return cdrom_capacity;
|
||||
uint8_t capacity_buffer[8];
|
||||
uint32_t capacity = 0;
|
||||
ioctl_read_capacity(capacity_buffer);
|
||||
capacity = ((uint32_t) capacity_buffer[0]) << 24;
|
||||
capacity |= ((uint32_t) capacity_buffer[1]) << 16;
|
||||
capacity |= ((uint32_t) capacity_buffer[2]) << 8;
|
||||
capacity |= (uint32_t) capacity_buffer[3];
|
||||
return capacity + 1;
|
||||
// return cdrom_capacity;
|
||||
}
|
||||
|
||||
static int ioctl_status()
|
||||
@@ -891,13 +951,16 @@ static void ioctl_exit(void)
|
||||
static CDROM ioctl_cdrom=
|
||||
{
|
||||
ioctl_ready,
|
||||
ioctl_medium_changed,
|
||||
ioctl_medium_changed,
|
||||
ioctl_readtoc,
|
||||
ioctl_readtoc_session,
|
||||
ioctl_readtoc_raw,
|
||||
ioctl_readtoc_raw,
|
||||
ioctl_getcurrentsubchannel,
|
||||
ioctl_readsector,
|
||||
ioctl_readsector_raw,
|
||||
ioctl_read_capacity,
|
||||
ioctl_read_header,
|
||||
ioctl_read_disc_information,
|
||||
ioctl_sector_data_type,
|
||||
ioctl_readsector_raw,
|
||||
ioctl_playaudio,
|
||||
ioctl_seek,
|
||||
ioctl_load,
|
||||
@@ -905,8 +968,8 @@ static CDROM ioctl_cdrom=
|
||||
ioctl_pause,
|
||||
ioctl_resume,
|
||||
ioctl_size,
|
||||
ioctl_status,
|
||||
ioctl_is_track_audio,
|
||||
ioctl_status,
|
||||
ioctl_is_track_audio,
|
||||
ioctl_stop,
|
||||
ioctl_exit
|
||||
};
|
||||
|
||||
@@ -126,40 +126,18 @@ static void iso_load(void)
|
||||
// pclog("iso_load stub\n");
|
||||
}
|
||||
|
||||
static void iso_readsector(uint8_t *b, int sector)
|
||||
{
|
||||
if (!cdrom_drive) return;
|
||||
iso_image = fopen(iso_path, "rb");
|
||||
fseek(iso_image,sector*2048,SEEK_SET);
|
||||
fread(b,2048,1,iso_image);
|
||||
fclose(iso_image);
|
||||
}
|
||||
|
||||
static void lba_to_msf(uint8_t *buf, int lba)
|
||||
{
|
||||
#if 0
|
||||
double dlba = (double) lba + 150;
|
||||
buf[2] = (uint8_t) (((uint32_t) dlba) % 75);
|
||||
dlba /= 75;
|
||||
buf[1] = (uint8_t) (((uint32_t) dlba) % 60);
|
||||
dlba /= 60;
|
||||
buf[0] = (uint8_t) dlba;
|
||||
#endif
|
||||
lba += 150;
|
||||
buf[0] = (lba / 75) / 60;
|
||||
buf[1] = (lba / 75) % 60;
|
||||
buf[2] = lba % 75;
|
||||
}
|
||||
|
||||
#if 0
|
||||
static void lba_to_msf(uint8_t *buf, int lba)
|
||||
static int iso_sector_data_type(int sector, int ismsf)
|
||||
{
|
||||
lba += 150;
|
||||
buf[0] = (lba / 75) / 60;
|
||||
buf[1] = (lba / 75) % 60;
|
||||
buf[2] = lba % 75;
|
||||
return 2; /* Always Mode 1 */
|
||||
}
|
||||
#endif
|
||||
|
||||
static void iso_readsector_raw(uint8_t *b, int sector, int ismsf)
|
||||
{
|
||||
@@ -406,7 +384,10 @@ static CDROM iso_cdrom =
|
||||
iso_readtoc_session,
|
||||
iso_readtoc_raw,
|
||||
iso_getcurrentsubchannel,
|
||||
iso_readsector,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
iso_sector_data_type,
|
||||
iso_readsector_raw,
|
||||
iso_playaudio,
|
||||
iso_seek,
|
||||
|
||||
@@ -62,8 +62,9 @@ static void null_load(void)
|
||||
{
|
||||
}
|
||||
|
||||
static void null_readsector(uint8_t *b, int sector)
|
||||
static int null_sector_data_type(int sector, int ismsf)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void null_readsector_raw(uint8_t *b, int sector, int ismsf)
|
||||
@@ -126,7 +127,10 @@ static CDROM null_cdrom =
|
||||
null_readtoc_session,
|
||||
null_readtoc_raw,
|
||||
null_getcurrentsubchannel,
|
||||
null_readsector,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
null_sector_data_type,
|
||||
null_readsector_raw,
|
||||
null_playaudio,
|
||||
null_seek,
|
||||
|
||||
@@ -10,7 +10,10 @@ typedef struct CDROM
|
||||
int (*readtoc_session)(uint8_t *b, int msf, int maxlen);
|
||||
int (*readtoc_raw)(uint8_t *b, int maxlen);
|
||||
uint8_t (*getcurrentsubchannel)(uint8_t *b, int msf);
|
||||
void (*readsector)(uint8_t *b, int sector);
|
||||
void (*read_capacity)(uint8_t *b);
|
||||
void (*read_header)(uint8_t *in_cdb, uint8_t *b);
|
||||
void (*read_disc_information)(uint8_t *b);
|
||||
int (*sector_data_type)(int sector, int ismsf);
|
||||
void (*readsector_raw)(uint8_t *b, int sector, int ismsf);
|
||||
void (*playaudio)(uint32_t pos, uint32_t len, int ismsf);
|
||||
void (*seek)(uint32_t pos);
|
||||
|
||||
@@ -29,8 +29,8 @@ RecompOpFn recomp_opcodes[512] =
|
||||
{
|
||||
/*16-bit data*/
|
||||
/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/
|
||||
/*00*/ ropADD_b_rmw, ropADD_w_rmw, ropADD_b_rm, ropADD_w_rm, ropADD_AL_imm, ropADD_AX_imm, ropPUSH_ES_16, NULL, ropOR_b_rmw, ropOR_w_rmw, ropOR_b_rm, ropOR_w_rm, ropOR_AL_imm, ropOR_AX_imm, ropPUSH_CS_16, NULL,
|
||||
/*10*/ NULL, NULL, NULL, NULL, NULL, NULL, ropPUSH_SS_16, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropPUSH_DS_16, NULL,
|
||||
/*00*/ ropADD_b_rmw, ropADD_w_rmw, ropADD_b_rm, ropADD_w_rm, ropADD_AL_imm, ropADD_AX_imm, ropPUSH_ES_16, ropPOP_ES_16, ropOR_b_rmw, ropOR_w_rmw, ropOR_b_rm, ropOR_w_rm, ropOR_AL_imm, ropOR_AX_imm, ropPUSH_CS_16, NULL,
|
||||
/*10*/ NULL, NULL, NULL, NULL, NULL, NULL, ropPUSH_SS_16, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropPUSH_DS_16, ropPOP_DS_16,
|
||||
/*20*/ ropAND_b_rmw, ropAND_w_rmw, ropAND_b_rm, ropAND_w_rm, ropAND_AL_imm, ropAND_AX_imm, NULL, NULL, ropSUB_b_rmw, ropSUB_w_rmw, ropSUB_b_rm, ropSUB_w_rm, ropSUB_AL_imm, ropSUB_AX_imm, NULL, NULL,
|
||||
/*30*/ ropXOR_b_rmw, ropXOR_w_rmw, ropXOR_b_rm, ropXOR_w_rm, ropXOR_AL_imm, ropXOR_AX_imm, NULL, NULL, ropCMP_b_rmw, ropCMP_w_rmw, ropCMP_b_rm, ropCMP_w_rm, ropCMP_AL_imm, ropCMP_AX_imm, NULL, NULL,
|
||||
|
||||
@@ -39,20 +39,20 @@ RecompOpFn recomp_opcodes[512] =
|
||||
/*60*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropPUSH_imm_16, NULL, ropPUSH_imm_b16,NULL, NULL, NULL, NULL, NULL,
|
||||
/*70*/ ropJO, ropJNO, ropJB, ropJNB, ropJE, ropJNE, ropJBE, ropJNBE, ropJS, ropJNS, ropJP, ropJNP, ropJL, ropJNL, ropJLE, ropJNLE,
|
||||
|
||||
/*80*/ rop80, rop81_w, rop80, rop83_w, ropTEST_b_rm, ropTEST_w_rm, ropXCHG_b, ropXCHG_w, ropMOV_b_r, ropMOV_w_r, ropMOV_r_b, ropMOV_r_w, NULL, ropLEA_w, NULL, NULL,
|
||||
/*80*/ rop80, rop81_w, rop80, rop83_w, ropTEST_b_rm, ropTEST_w_rm, ropXCHG_b, ropXCHG_w, ropMOV_b_r, ropMOV_w_r, ropMOV_r_b, ropMOV_r_w, ropMOV_w_seg, ropLEA_w, ropMOV_seg_w, NULL,
|
||||
/*90*/ ropNOP, ropXCHG_AX_CX, ropXCHG_AX_DX, ropXCHG_AX_BX, ropXCHG_AX_SP, ropXCHG_AX_BP, ropXCHG_AX_SI, ropXCHG_AX_DI, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/*a0*/ ropMOV_AL_a, ropMOV_AX_a, ropMOV_a_AL, ropMOV_a_AX, NULL, NULL, NULL, NULL, ropTEST_AL_imm, ropTEST_AX_imm, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/*b0*/ ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rw_imm, ropMOV_rw_imm, ropMOV_rw_imm, ropMOV_rw_imm, ropMOV_rw_imm, ropMOV_rw_imm, ropMOV_rw_imm, ropMOV_rw_imm,
|
||||
|
||||
/*c0*/ ropC0, ropC1_w, ropRET_imm_16, ropRET_16, NULL, NULL, ropMOV_b_imm, ropMOV_w_imm, NULL, ropLEAVE_16, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/*c0*/ ropC0, ropC1_w, ropRET_imm_16, ropRET_16, ropLES, ropLDS, ropMOV_b_imm, ropMOV_w_imm, NULL, ropLEAVE_16, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/*d0*/ ropD0, ropD1_w, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/*e0*/ NULL, NULL, ropLOOP, ropJCXZ, NULL, NULL, NULL, NULL, ropCALL_r16, ropJMP_r16, NULL, ropJMP_r8, NULL, NULL, NULL, NULL,
|
||||
/*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, ropF6, ropF7_w, NULL, NULL, NULL, NULL, ropCLD, ropSTD, ropFE, ropFF_16,
|
||||
/*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, ropF6, ropF7_w, NULL, NULL, ropCLI, ropSTI, ropCLD, ropSTD, ropFE, ropFF_16,
|
||||
|
||||
/*32-bit data*/
|
||||
/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/
|
||||
/*00*/ ropADD_b_rmw, ropADD_l_rmw, ropADD_b_rm, ropADD_l_rm, ropADD_AL_imm, ropADD_EAX_imm, ropPUSH_ES_32, NULL, ropOR_b_rmw, ropOR_l_rmw, ropOR_b_rm, ropOR_l_rm, ropOR_AL_imm, ropOR_EAX_imm, ropPUSH_CS_32, NULL,
|
||||
/*10*/ NULL, NULL, NULL, NULL, NULL, NULL, ropPUSH_SS_32, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropPUSH_DS_32, NULL,
|
||||
/*00*/ ropADD_b_rmw, ropADD_l_rmw, ropADD_b_rm, ropADD_l_rm, ropADD_AL_imm, ropADD_EAX_imm, ropPUSH_ES_32, ropPOP_ES_32, ropOR_b_rmw, ropOR_l_rmw, ropOR_b_rm, ropOR_l_rm, ropOR_AL_imm, ropOR_EAX_imm, ropPUSH_CS_32, NULL,
|
||||
/*10*/ NULL, NULL, NULL, NULL, NULL, NULL, ropPUSH_SS_32, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropPUSH_DS_32, ropPOP_DS_32,
|
||||
/*20*/ ropAND_b_rmw, ropAND_l_rmw, ropAND_b_rm, ropAND_l_rm, ropAND_AL_imm, ropAND_EAX_imm, NULL, NULL, ropSUB_b_rmw, ropSUB_l_rmw, ropSUB_b_rm, ropSUB_l_rm, ropSUB_AL_imm, ropSUB_EAX_imm, NULL, NULL,
|
||||
/*30*/ ropXOR_b_rmw, ropXOR_l_rmw, ropXOR_b_rm, ropXOR_l_rm, ropXOR_AL_imm, ropXOR_EAX_imm, NULL, NULL, ropCMP_b_rmw, ropCMP_l_rmw, ropCMP_b_rm, ropCMP_l_rm, ropCMP_AL_imm, ropCMP_EAX_imm, NULL, NULL,
|
||||
|
||||
@@ -61,15 +61,15 @@ RecompOpFn recomp_opcodes[512] =
|
||||
/*60*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropPUSH_imm_32, NULL, ropPUSH_imm_b32,NULL, NULL, NULL, NULL, NULL,
|
||||
/*70*/ ropJO, ropJNO, ropJB, ropJNB, ropJE, ropJNE, ropJBE, ropJNBE, ropJS, ropJNS, ropJP, ropJNP, ropJL, ropJNL, ropJLE, ropJNLE,
|
||||
|
||||
/*80*/ rop80, rop81_l, rop80, rop83_l, ropTEST_b_rm, ropTEST_l_rm, ropXCHG_b, ropXCHG_l, ropMOV_b_r, ropMOV_l_r, ropMOV_r_b, ropMOV_r_l, NULL, ropLEA_l, NULL, NULL,
|
||||
/*80*/ rop80, rop81_l, rop80, rop83_l, ropTEST_b_rm, ropTEST_l_rm, ropXCHG_b, ropXCHG_l, ropMOV_b_r, ropMOV_l_r, ropMOV_r_b, ropMOV_r_l, ropMOV_w_seg, ropLEA_l, ropMOV_seg_w, NULL,
|
||||
/*90*/ ropNOP, ropXCHG_EAX_ECX,ropXCHG_EAX_EDX,ropXCHG_EAX_EBX,ropXCHG_EAX_ESP,ropXCHG_EAX_EBP,ropXCHG_EAX_ESI,ropXCHG_EAX_EDI,NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/*a0*/ ropMOV_AL_a, ropMOV_EAX_a, ropMOV_a_AL, ropMOV_a_EAX, NULL, NULL, NULL, NULL, ropTEST_AL_imm, ropTEST_EAX_imm,NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/*b0*/ ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rl_imm, ropMOV_rl_imm, ropMOV_rl_imm, ropMOV_rl_imm, ropMOV_rl_imm, ropMOV_rl_imm, ropMOV_rl_imm, ropMOV_rl_imm,
|
||||
|
||||
/*c0*/ ropC0, ropC1_l, ropRET_imm_32, ropRET_32, NULL, NULL, ropMOV_b_imm, ropMOV_l_imm, NULL, ropLEAVE_32, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/*c0*/ ropC0, ropC1_l, ropRET_imm_32, ropRET_32, ropLES, ropLDS, ropMOV_b_imm, ropMOV_l_imm, NULL, ropLEAVE_32, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/*d0*/ ropD0, ropD1_l, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/*e0*/ NULL, NULL, ropLOOP, ropJCXZ, NULL, NULL, NULL, NULL, ropCALL_r32, ropJMP_r32, NULL, ropJMP_r8, NULL, NULL, NULL, NULL,
|
||||
/*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, ropF6, ropF7_l, NULL, NULL, NULL, NULL, ropCLD, ropSTD, ropFE, ropFF_32
|
||||
/*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, ropF6, ropF7_l, NULL, NULL, ropCLI, ropSTI, ropCLD, ropSTD, ropFE, ropFF_32
|
||||
};
|
||||
|
||||
RecompOpFn recomp_opcodes_0f[512] =
|
||||
@@ -88,8 +88,8 @@ RecompOpFn recomp_opcodes_0f[512] =
|
||||
|
||||
/*80*/ ropJO_w, ropJNO_w, ropJB_w, ropJNB_w, ropJE_w, ropJNE_w, ropJBE_w, ropJNBE_w, ropJS_w, ropJNS_w, ropJP_w, ropJNP_w, ropJL_w, ropJNL_w, ropJLE_w, ropJNLE_w,
|
||||
/*90*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/*a0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/*b0*/ NULL, NULL, NULL, NULL, NULL, NULL, ropMOVZX_w_b, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropMOVSX_w_b, NULL,
|
||||
/*a0*/ ropPUSH_FS_16, ropPOP_FS_16, NULL, NULL, NULL, NULL, NULL, NULL, ropPUSH_GS_16, ropPOP_GS_16, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/*b0*/ NULL, NULL, ropLSS, NULL, ropLFS, ropLGS, ropMOVZX_w_b, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropMOVSX_w_b, NULL,
|
||||
|
||||
/*c0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/*d0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
@@ -110,8 +110,8 @@ RecompOpFn recomp_opcodes_0f[512] =
|
||||
|
||||
/*80*/ ropJO_l, ropJNO_l, ropJB_l, ropJNB_l, ropJE_l, ropJNE_l, ropJBE_l, ropJNBE_l, ropJS_l, ropJNS_l, ropJP_l, ropJNP_l, ropJL_l, ropJNL_l, ropJLE_l, ropJNLE_l,
|
||||
/*90*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/*a0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/*b0*/ NULL, NULL, NULL, NULL, NULL, NULL, ropMOVZX_l_b, ropMOVZX_l_w, NULL, NULL, NULL, NULL, NULL, NULL, ropMOVSX_l_b, ropMOVSX_l_w,
|
||||
/*a0*/ ropPUSH_FS_32, ropPOP_FS_32, NULL, NULL, NULL, NULL, NULL, NULL, ropPUSH_GS_32, ropPOP_GS_32, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/*b0*/ NULL, NULL, ropLSS, NULL, ropLFS, ropLGS, ropMOVZX_l_b, ropMOVZX_l_w, NULL, NULL, NULL, NULL, NULL, NULL, ropMOVSX_l_b, ropMOVSX_l_w,
|
||||
|
||||
/*c0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/*d0*/ NULL, ropPSRLW, ropPSRLD, ropPSRLQ, NULL, ropPMULLW, NULL, NULL, ropPSUBUSB, ropPSUBUSW, NULL, ropPAND, ropPADDUSB, ropPADDUSW, NULL, ropPANDN,
|
||||
@@ -188,7 +188,7 @@ RecompOpFn recomp_opcodes_d9[512] =
|
||||
|
||||
/*c0*/ ropFLD, ropFLD, ropFLD, ropFLD, ropFLD, ropFLD, ropFLD, ropFLD, ropFXCH, ropFXCH, ropFXCH, ropFXCH, ropFXCH, ropFXCH, ropFXCH, ropFXCH,
|
||||
/*d0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/*e0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/*e0*/ ropFCHS, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropFLD1, ropFLDL2T, ropFLDL2E, ropFLDPI, ropFLDEG2, ropFLDLN2, ropFLDZ, NULL,
|
||||
/*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
|
||||
/*32-bit data*/
|
||||
@@ -210,7 +210,7 @@ RecompOpFn recomp_opcodes_d9[512] =
|
||||
|
||||
/*c0*/ ropFLD, ropFLD, ropFLD, ropFLD, ropFLD, ropFLD, ropFLD, ropFLD, ropFXCH, ropFXCH, ropFXCH, ropFXCH, ropFXCH, ropFXCH, ropFXCH, ropFXCH,
|
||||
/*d0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/*e0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/*e0*/ ropFCHS, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropFLD1, ropFLDL2T, ropFLDL2E, ropFLDPI, ropFLDEG2, ropFLDLN2, ropFLDZ, NULL,
|
||||
/*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
};
|
||||
|
||||
@@ -422,7 +422,7 @@ RecompOpFn recomp_opcodes_de[512] =
|
||||
/*b0*/ ropFDIViw, ropFDIViw, ropFDIViw, ropFDIViw, ropFDIViw, ropFDIViw, ropFDIViw, ropFDIViw, ropFDIVRiw, ropFDIVRiw, ropFDIVRiw, ropFDIVRiw, ropFDIVRiw, ropFDIVRiw, ropFDIVRiw, ropFDIVRiw,
|
||||
|
||||
/*c0*/ ropFADDP, ropFADDP, ropFADDP, ropFADDP, ropFADDP, ropFADDP, ropFADDP, ropFADDP, ropFMULP, ropFMULP, ropFMULP, ropFMULP, ropFMULP, ropFMULP, ropFMULP, ropFMULP,
|
||||
/*d0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/*d0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropFCOMPP, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/*e0*/ ropFSUBRP, ropFSUBRP, ropFSUBRP, ropFSUBRP, ropFSUBRP, ropFSUBRP, ropFSUBRP, ropFSUBRP, ropFSUBP, ropFSUBP, ropFSUBP, ropFSUBP, ropFSUBP, ropFSUBP, ropFSUBP, ropFSUBP,
|
||||
/*f0*/ ropFDIVRP, ropFDIVRP, ropFDIVRP, ropFDIVRP, ropFDIVRP, ropFDIVRP, ropFDIVRP, ropFDIVRP, ropFDIVP, ropFDIVP, ropFDIVP, ropFDIVP, ropFDIVP, ropFDIVP, ropFDIVP, ropFDIVP,
|
||||
|
||||
@@ -444,7 +444,7 @@ RecompOpFn recomp_opcodes_de[512] =
|
||||
/*b0*/ ropFDIViw, ropFDIViw, ropFDIViw, ropFDIViw, ropFDIViw, ropFDIViw, ropFDIViw, ropFDIViw, ropFDIVRiw, ropFDIVRiw, ropFDIVRiw, ropFDIVRiw, ropFDIVRiw, ropFDIVRiw, ropFDIVRiw, ropFDIVRiw,
|
||||
|
||||
/*c0*/ ropFADDP, ropFADDP, ropFADDP, ropFADDP, ropFADDP, ropFADDP, ropFADDP, ropFADDP, ropFMULP, ropFMULP, ropFMULP, ropFMULP, ropFMULP, ropFMULP, ropFMULP, ropFMULP,
|
||||
/*d0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/*d0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropFCOMPP, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/*e0*/ ropFSUBRP, ropFSUBRP, ropFSUBRP, ropFSUBRP, ropFSUBRP, ropFSUBRP, ropFSUBRP, ropFSUBRP, ropFSUBP, ropFSUBP, ropFSUBP, ropFSUBP, ropFSUBP, ropFSUBP, ropFSUBP, ropFSUBP,
|
||||
/*f0*/ ropFDIVRP, ropFDIVRP, ropFDIVRP, ropFDIVRP, ropFDIVRP, ropFDIVRP, ropFDIVRP, ropFDIVRP, ropFDIVP, ropFDIVP, ropFDIVP, ropFDIVP, ropFDIVP, ropFDIVP, ropFDIVP, ropFDIVP,
|
||||
};
|
||||
|
||||
@@ -477,6 +477,14 @@ static uint32_t ropFSUBRP(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uin
|
||||
return op_pc;
|
||||
}
|
||||
|
||||
static uint32_t ropFCOMPP(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
{
|
||||
FP_ENTER();
|
||||
FP_COMPARE_REG(0, 1);
|
||||
FP_POP2();
|
||||
|
||||
return op_pc;
|
||||
}
|
||||
|
||||
static uint32_t ropFSTSW_AX(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
{
|
||||
@@ -600,3 +608,31 @@ static uint32_t ropFSTCW(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint
|
||||
|
||||
return op_pc + 1;
|
||||
}
|
||||
|
||||
|
||||
static uint32_t ropFCHS(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
{
|
||||
FP_ENTER();
|
||||
FP_FCHS();
|
||||
|
||||
return op_pc;
|
||||
}
|
||||
|
||||
#define opFLDimm(name, v) \
|
||||
static uint32_t ropFLD ## name(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \
|
||||
{ \
|
||||
static double fp_imm = v; \
|
||||
\
|
||||
FP_ENTER(); \
|
||||
FP_LOAD_IMM_Q(*(uint64_t *)&fp_imm); \
|
||||
\
|
||||
return op_pc; \
|
||||
}
|
||||
|
||||
opFLDimm(1, 1.0)
|
||||
opFLDimm(L2T, 3.3219280948873623)
|
||||
opFLDimm(L2E, 1.4426950408889634);
|
||||
opFLDimm(PI, 3.141592653589793);
|
||||
opFLDimm(EG2, 0.3010299956639812);
|
||||
opFLDimm(LN2, 0.693147180559945);
|
||||
opFLDimm(Z, 0.0)
|
||||
|
||||
@@ -14,6 +14,17 @@ static uint32_t ropSTD(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32
|
||||
return op_pc;
|
||||
}
|
||||
|
||||
static uint32_t ropCLI(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
{
|
||||
CLEAR_BITS((uintptr_t)&flags, I_FLAG);
|
||||
return op_pc;
|
||||
}
|
||||
static uint32_t ropSTI(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
{
|
||||
SET_BITS((uintptr_t)&flags, I_FLAG);
|
||||
return op_pc;
|
||||
}
|
||||
|
||||
static uint32_t ropFE(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
{
|
||||
x86seg *target_seg;
|
||||
@@ -71,7 +82,7 @@ static uint32_t ropFF_16(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint
|
||||
x86seg *target_seg;
|
||||
int host_reg;
|
||||
|
||||
if ((fetchdat & 0x30) != 0x00 && (fetchdat & 0x38) != 0x10 && (fetchdat & 0x38) != 0x20)// && (fetchdat & 0x38) != 0x30)
|
||||
if ((fetchdat & 0x30) != 0x00 && (fetchdat & 0x08))
|
||||
return 0;
|
||||
|
||||
if ((fetchdat & 0x30) == 0x00)
|
||||
@@ -163,7 +174,7 @@ static uint32_t ropFF_32(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint
|
||||
x86seg *target_seg;
|
||||
int host_reg;
|
||||
|
||||
if ((fetchdat & 0x30) != 0x00 && (fetchdat & 0x38) != 0x10 && (fetchdat & 0x38) != 0x20)// && (fetchdat & 0x38) != 0x30)
|
||||
if ((fetchdat & 0x30) != 0x00 && (fetchdat & 0x08))
|
||||
return 0;
|
||||
|
||||
if ((fetchdat & 0x30) == 0x00)
|
||||
|
||||
@@ -504,3 +504,153 @@ static uint32_t ropMOVSX_l_w(uint8_t opcode, uint32_t fetchdat, uint32_t op_32,
|
||||
|
||||
return op_pc + 1;
|
||||
}
|
||||
|
||||
static uint32_t ropMOV_w_seg(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
{
|
||||
int host_reg;
|
||||
|
||||
switch (fetchdat & 0x38)
|
||||
{
|
||||
case 0x00: /*ES*/
|
||||
host_reg = LOAD_VAR_WL(&ES);
|
||||
break;
|
||||
case 0x08: /*CS*/
|
||||
host_reg = LOAD_VAR_WL(&CS);
|
||||
break;
|
||||
case 0x18: /*DS*/
|
||||
host_reg = LOAD_VAR_WL(&DS);
|
||||
break;
|
||||
case 0x10: /*SS*/
|
||||
host_reg = LOAD_VAR_WL(&SS);
|
||||
break;
|
||||
case 0x20: /*FS*/
|
||||
host_reg = LOAD_VAR_WL(&FS);
|
||||
break;
|
||||
case 0x28: /*GS*/
|
||||
host_reg = LOAD_VAR_WL(&GS);
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ((fetchdat & 0xc0) == 0xc0)
|
||||
{
|
||||
if (op_32 & 0x100)
|
||||
STORE_REG_TARGET_L_RELEASE(host_reg, fetchdat & 7);
|
||||
else
|
||||
STORE_REG_TARGET_W_RELEASE(host_reg, fetchdat & 7);
|
||||
}
|
||||
else
|
||||
{
|
||||
x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32);
|
||||
|
||||
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc);
|
||||
|
||||
CHECK_SEG_WRITE(target_seg);
|
||||
CHECK_SEG_LIMITS(target_seg, 1);
|
||||
|
||||
MEM_STORE_ADDR_EA_W(target_seg, host_reg);
|
||||
RELEASE_REG(host_reg);
|
||||
}
|
||||
|
||||
return op_pc + 1;
|
||||
}
|
||||
static uint32_t ropMOV_seg_w(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
{
|
||||
int host_reg;
|
||||
|
||||
switch (fetchdat & 0x38)
|
||||
{
|
||||
case 0x00: /*ES*/
|
||||
case 0x18: /*DS*/
|
||||
case 0x20: /*FS*/
|
||||
case 0x28: /*GS*/
|
||||
break;
|
||||
case 0x10: /*SS*/
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
||||
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc);
|
||||
|
||||
if ((fetchdat & 0xc0) == 0xc0)
|
||||
host_reg = LOAD_REG_W(fetchdat & 7);
|
||||
else
|
||||
{
|
||||
x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32);
|
||||
|
||||
CHECK_SEG_READ(target_seg);
|
||||
MEM_LOAD_ADDR_EA_W(target_seg);
|
||||
|
||||
host_reg = 0;
|
||||
}
|
||||
|
||||
switch (fetchdat & 0x38)
|
||||
{
|
||||
case 0x00: /*ES*/
|
||||
LOAD_SEG(host_reg, &_es);
|
||||
break;
|
||||
case 0x18: /*DS*/
|
||||
LOAD_SEG(host_reg, &_ds);
|
||||
break;
|
||||
case 0x20: /*FS*/
|
||||
LOAD_SEG(host_reg, &_fs);
|
||||
break;
|
||||
case 0x28: /*GS*/
|
||||
LOAD_SEG(host_reg, &_gs);
|
||||
break;
|
||||
}
|
||||
|
||||
return op_pc + 1;
|
||||
}
|
||||
|
||||
#define ropLseg(seg, rseg) \
|
||||
static uint32_t ropL ## seg(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \
|
||||
{ \
|
||||
int dest_reg = (fetchdat >> 3) & 7; \
|
||||
x86seg *target_seg; \
|
||||
\
|
||||
if ((fetchdat & 0xc0) == 0xc0) \
|
||||
return 0; \
|
||||
\
|
||||
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); \
|
||||
target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); \
|
||||
SAVE_EA(); \
|
||||
\
|
||||
if (op_32 & 0x100) \
|
||||
{ \
|
||||
MEM_LOAD_ADDR_EA_L(target_seg); \
|
||||
STORE_HOST_REG_ADDR((uintptr_t)&codegen_temp, 0); \
|
||||
LOAD_EA(); \
|
||||
MEM_LOAD_ADDR_EA_W_OFFSET(target_seg, 4); \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
MEM_LOAD_ADDR_EA_W(target_seg); \
|
||||
STORE_HOST_REG_ADDR_W((uintptr_t)&codegen_temp, 0); \
|
||||
LOAD_EA(); \
|
||||
MEM_LOAD_ADDR_EA_W_OFFSET(target_seg, 2); \
|
||||
} \
|
||||
LOAD_SEG(0, &rseg); \
|
||||
if (op_32 & 0x100) \
|
||||
{ \
|
||||
\
|
||||
int host_reg = LOAD_VAR_L((uintptr_t)&codegen_temp); \
|
||||
STORE_REG_TARGET_L_RELEASE(host_reg, dest_reg); \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
int host_reg = LOAD_VAR_W((uintptr_t)&codegen_temp); \
|
||||
STORE_REG_TARGET_W_RELEASE(host_reg, dest_reg); \
|
||||
} \
|
||||
\
|
||||
if (&rseg == &_ss) \
|
||||
CPU_BLOCK_END(); /*Instruction might change stack size, so end block here*/ \
|
||||
return op_pc + 1; \
|
||||
}
|
||||
|
||||
ropLseg(DS, _ds)
|
||||
ropLseg(ES, _es)
|
||||
ropLseg(FS, _fs)
|
||||
ropLseg(GS, _gs)
|
||||
ropLseg(SS, _ss)
|
||||
|
||||
@@ -247,4 +247,37 @@ static uint32_t ropPUSH_ ## seg ## _32(uint8_t opcode, uint32_t fetchdat, uint32
|
||||
ROP_PUSH_SEG(CS)
|
||||
ROP_PUSH_SEG(DS)
|
||||
ROP_PUSH_SEG(ES)
|
||||
ROP_PUSH_SEG(FS)
|
||||
ROP_PUSH_SEG(GS)
|
||||
ROP_PUSH_SEG(SS)
|
||||
|
||||
#define ROP_POP_SEG(seg, rseg) \
|
||||
static uint32_t ropPOP_ ## seg ## _16(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \
|
||||
{ \
|
||||
int host_reg; \
|
||||
\
|
||||
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); \
|
||||
LOAD_STACK_TO_EA(0); \
|
||||
MEM_LOAD_ADDR_EA_W(&_ss); \
|
||||
LOAD_SEG(0, &rseg); \
|
||||
SP_MODIFY(2); \
|
||||
\
|
||||
return op_pc; \
|
||||
} \
|
||||
static uint32_t ropPOP_ ## seg ## _32(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \
|
||||
{ \
|
||||
int host_reg; \
|
||||
\
|
||||
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); \
|
||||
LOAD_STACK_TO_EA(0); \
|
||||
MEM_LOAD_ADDR_EA_W(&_ss); \
|
||||
LOAD_SEG(0, &rseg); \
|
||||
SP_MODIFY(4); \
|
||||
\
|
||||
return op_pc; \
|
||||
}
|
||||
|
||||
ROP_POP_SEG(DS, _ds)
|
||||
ROP_POP_SEG(ES, _es)
|
||||
ROP_POP_SEG(FS, _fs)
|
||||
ROP_POP_SEG(GS, _gs)
|
||||
|
||||
@@ -1105,6 +1105,13 @@ static void MEM_LOAD_ADDR_EA_W(x86seg *seg)
|
||||
addlong(BLOCK_EXIT_OFFSET - (block_pos + 4));
|
||||
/*done:*/
|
||||
}
|
||||
static void MEM_LOAD_ADDR_EA_W_OFFSET(x86seg *seg, int offset)
|
||||
{
|
||||
addbyte(0x83); /*ADD EAX, offset*/
|
||||
addbyte(0xc0);
|
||||
addbyte(offset);
|
||||
MEM_LOAD_ADDR_EA_W(seg);
|
||||
}
|
||||
static void MEM_LOAD_ADDR_EA_L(x86seg *seg)
|
||||
{
|
||||
if (IS_32_ADDR(&seg->base))
|
||||
@@ -3346,6 +3353,10 @@ static int LOAD_VAR_W(uintptr_t addr)
|
||||
|
||||
return host_reg;
|
||||
}
|
||||
static int LOAD_VAR_WL(uintptr_t addr)
|
||||
{
|
||||
return LOAD_VAR_W(addr);
|
||||
}
|
||||
static int LOAD_VAR_L(uintptr_t addr)
|
||||
{
|
||||
int host_reg = REG_EBX;
|
||||
@@ -3390,9 +3401,9 @@ static int LOAD_HOST_REG(int host_reg)
|
||||
if (host_reg & 8)
|
||||
addbyte(0x44);
|
||||
addbyte(0x89);
|
||||
addbyte(0xc0 | REG_ECX | ((host_reg & 7) << 3));
|
||||
addbyte(0xc0 | REG_EBX | ((host_reg & 7) << 3));
|
||||
|
||||
return REG_ECX | (host_reg & 0x10);
|
||||
return REG_EBX | (host_reg & 0x10);
|
||||
}
|
||||
|
||||
static int ZERO_EXTEND_W_B(int reg)
|
||||
@@ -3897,6 +3908,26 @@ static void FP_POP()
|
||||
addbyte(0x45);
|
||||
addbyte(cpu_state_offset(TOP));
|
||||
}
|
||||
static void FP_POP2()
|
||||
{
|
||||
addbyte(0x8b); /*MOV EAX, [TOP]*/
|
||||
addbyte(0x45);
|
||||
addbyte(cpu_state_offset(TOP));
|
||||
addbyte(0xc6); /*MOVB tag[EAX], 3*/
|
||||
addbyte(0x44);
|
||||
addbyte(0x05);
|
||||
addbyte(cpu_state_offset(tag));
|
||||
addbyte(3);
|
||||
addbyte(0x83); /*ADD AL, 2*/
|
||||
addbyte(0xc0);
|
||||
addbyte(2);
|
||||
addbyte(0x83); /*AND AL, 7*/
|
||||
addbyte(0xe0);
|
||||
addbyte(7);
|
||||
addbyte(0x89); /*MOV [TOP], EAX*/
|
||||
addbyte(0x45);
|
||||
addbyte(cpu_state_offset(TOP));
|
||||
}
|
||||
|
||||
static void FP_LOAD_S()
|
||||
{
|
||||
@@ -4074,6 +4105,65 @@ static void FP_LOAD_IQ()
|
||||
addbyte(cpu_state_offset(tag));
|
||||
}
|
||||
|
||||
static void FP_LOAD_IMM_Q(uint64_t v)
|
||||
{
|
||||
addbyte(0x8b); /*MOV EBX, TOP*/
|
||||
addbyte(0x5d);
|
||||
addbyte(cpu_state_offset(TOP));
|
||||
addbyte(0x83); /*SUB EBX, 1*/
|
||||
addbyte(0xeb);
|
||||
addbyte(0x01);
|
||||
addbyte(0x83); /*AND EBX, 7*/
|
||||
addbyte(0xe3);
|
||||
addbyte(7);
|
||||
addbyte(0xc7); /*MOV ST[EBP+EBX*8], v*/
|
||||
addbyte(0x44);
|
||||
addbyte(0xdd);
|
||||
addbyte(cpu_state_offset(ST));
|
||||
addlong(v & 0xffffffff);
|
||||
addbyte(0xc7); /*MOV ST[EBP+EBX*8]+4, v*/
|
||||
addbyte(0x44);
|
||||
addbyte(0xdd);
|
||||
addbyte(cpu_state_offset(ST) + 4);
|
||||
addlong(v >> 32);
|
||||
addbyte(0x89); /*MOV TOP, EBX*/
|
||||
addbyte(0x5d);
|
||||
addbyte(cpu_state_offset(TOP));
|
||||
addbyte(0xc6); /*MOV [tag+EBX], (v ? 0 : 1)*/
|
||||
addbyte(0x44);
|
||||
addbyte(0x1d);
|
||||
addbyte(cpu_state_offset(tag));
|
||||
addbyte(v ? 0 : 1);
|
||||
}
|
||||
|
||||
static void FP_FCHS()
|
||||
{
|
||||
addbyte(0x8b); /*MOV EAX, TOP*/
|
||||
addbyte(0x45);
|
||||
addbyte(cpu_state_offset(TOP));
|
||||
addbyte(0xf2); /*SUBSD XMM0, XMM0*/
|
||||
addbyte(0x0f);
|
||||
addbyte(0x5c);
|
||||
addbyte(0xc0);
|
||||
addbyte(0xf2); /*SUBSD XMM0, ST[EAX*8]*/
|
||||
addbyte(0x0f);
|
||||
addbyte(0x5c);
|
||||
addbyte(0x44);
|
||||
addbyte(0xc5);
|
||||
addbyte(cpu_state_offset(ST));
|
||||
addbyte(0x80); /*AND tag[EAX], ~TAG_UINT64*/
|
||||
addbyte(0x64);
|
||||
addbyte(0x05);
|
||||
addbyte(cpu_state_offset(tag[0]));
|
||||
addbyte(~TAG_UINT64);
|
||||
addbyte(0xf2); /*MOVSD ST[EAX*8], XMM0*/
|
||||
addbyte(0x0f);
|
||||
addbyte(0x11);
|
||||
addbyte(0x44);
|
||||
addbyte(0xc5);
|
||||
addbyte(cpu_state_offset(ST));
|
||||
}
|
||||
|
||||
static int FP_LOAD_REG(int reg)
|
||||
{
|
||||
addbyte(0x8b); /*MOV EBX, TOP*/
|
||||
@@ -5923,3 +6013,17 @@ static void MEM_STORE_ADDR_EA_L_NO_ABRT(x86seg *seg, int host_reg)
|
||||
call_long(writememll);
|
||||
/*done:*/
|
||||
}
|
||||
|
||||
static void LOAD_SEG(int host_reg, void *seg)
|
||||
{
|
||||
load_param_2_64(&codeblock[block_current], (uint64_t)seg);
|
||||
load_param_1_reg_32(host_reg);
|
||||
CALL_FUNC(loadseg);
|
||||
addbyte(0x80); /*CMP abrt, 0*/
|
||||
addbyte(0x7d);
|
||||
addbyte(cpu_state_offset(abrt));
|
||||
addbyte(0);
|
||||
addbyte(0x0f); /*JNE end*/
|
||||
addbyte(0x85);
|
||||
addlong(BLOCK_EXIT_OFFSET - (block_pos + 4));
|
||||
}
|
||||
|
||||
@@ -145,6 +145,18 @@ static int LOAD_VAR_W(uintptr_t addr)
|
||||
|
||||
return host_reg;
|
||||
}
|
||||
static int LOAD_VAR_WL(uintptr_t addr)
|
||||
{
|
||||
int host_reg = find_host_reg();
|
||||
host_reg_mapping[host_reg] = 0;
|
||||
|
||||
addbyte(0x0f); /*MOVZX host_reg, [addr]*/
|
||||
addbyte(0xb7);
|
||||
addbyte(0x05 | (host_reg << 3));
|
||||
addlong((uint32_t)addr);
|
||||
|
||||
return host_reg;
|
||||
}
|
||||
static int LOAD_VAR_L(uintptr_t addr)
|
||||
{
|
||||
int host_reg = find_host_reg();
|
||||
@@ -693,6 +705,19 @@ static void MEM_LOAD_ADDR_EA_W(x86seg *seg)
|
||||
|
||||
host_reg_mapping[0] = 8;
|
||||
}
|
||||
static void MEM_LOAD_ADDR_EA_W_OFFSET(x86seg *seg, int offset)
|
||||
{
|
||||
addbyte(0x8b); /*MOVL EDX, seg->base*/
|
||||
addbyte(0x05 | (REG_EDX << 3));
|
||||
addlong((uint32_t)&seg->base);
|
||||
addbyte(0x83); /*ADD EAX, offset*/
|
||||
addbyte(0xc0);
|
||||
addbyte(offset);
|
||||
addbyte(0xe8); /*CALL mem_load_addr_ea_w*/
|
||||
addlong(mem_load_addr_ea_w - (uint32_t)(&codeblock[block_current].data[block_pos + 4]));
|
||||
|
||||
host_reg_mapping[0] = 8;
|
||||
}
|
||||
static int MEM_LOAD_ADDR_EA_W_NO_ABRT(x86seg *seg)
|
||||
{
|
||||
addbyte(0x8b); /*MOVL EDX, seg->base*/
|
||||
@@ -2169,6 +2194,59 @@ static void FP_LOAD_IQ()
|
||||
}
|
||||
}
|
||||
|
||||
static void FP_LOAD_IMM_Q(uint64_t v)
|
||||
{
|
||||
if (codeblock[block_current].flags & CODEBLOCK_STATIC_TOP)
|
||||
{
|
||||
addbyte(0xc7); /*MOV ST[reg][EBP], v*/
|
||||
addbyte(0x45);
|
||||
addbyte(cpu_state_offset(ST[(cpu_state.TOP - 1) & 7]));
|
||||
addlong(v & 0xffffffff);
|
||||
addbyte(0xc7); /*MOV ST[reg][EBP]+4, v*/
|
||||
addbyte(0x45);
|
||||
addbyte(cpu_state_offset(ST[(cpu_state.TOP - 1) & 7]) + 4);
|
||||
addlong(v >> 32);
|
||||
addbyte(0xc6); /*MOVB TOP[EBP], (TOP-1) & 7*/
|
||||
addbyte(0x45);
|
||||
addbyte(cpu_state_offset(TOP));
|
||||
addbyte((cpu_state.TOP - 1) & 7);
|
||||
addbyte(0xc6); /*MOVB tag[reg][EBP], 1:0*/
|
||||
addbyte(0x45);
|
||||
addbyte(cpu_state_offset(tag[(cpu_state.TOP - 1) & 7]));
|
||||
addbyte(v ? 0 : 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
addbyte(0x8b); /*MOV EBX, TOP*/
|
||||
addbyte(0x5d);
|
||||
addbyte(cpu_state_offset(TOP));
|
||||
addbyte(0x83); /*SUB EBX, 1*/
|
||||
addbyte(0xeb);
|
||||
addbyte(1);
|
||||
addbyte(0x83); /*AND EBX, 7*/
|
||||
addbyte(0xe3);
|
||||
addbyte(7);
|
||||
addbyte(0xc7); /*MOV ST[EBP+EBX*8], v*/
|
||||
addbyte(0x44);
|
||||
addbyte(0xdd);
|
||||
addbyte(cpu_state_offset(ST));
|
||||
addlong(v & 0xffffffff);
|
||||
addbyte(0xc7); /*MOV ST[EBP+EBX*8]+4, v*/
|
||||
addbyte(0x44);
|
||||
addbyte(0xdd);
|
||||
addbyte(cpu_state_offset(ST) + 4);
|
||||
addlong(v >> 32);
|
||||
addbyte(0xc6); /*MOVB tag[reg][EBP], 1:0*/
|
||||
addbyte(0x44);
|
||||
addbyte(0x1d);
|
||||
addbyte(cpu_state_offset(tag[0]));
|
||||
addbyte(v ? 0 : 1);
|
||||
addbyte(0x89); /*MOV TOP, EBX*/
|
||||
addbyte(0x5d);
|
||||
addbyte(cpu_state_offset(TOP));
|
||||
}
|
||||
}
|
||||
|
||||
static int FP_LOAD_REG(int reg)
|
||||
{
|
||||
if (codeblock[block_current].flags & CODEBLOCK_STATIC_TOP)
|
||||
@@ -2425,6 +2503,42 @@ static void FP_POP()
|
||||
addbyte(cpu_state_offset(TOP));
|
||||
}
|
||||
}
|
||||
static void FP_POP2()
|
||||
{
|
||||
if (codeblock[block_current].flags & CODEBLOCK_STATIC_TOP)
|
||||
{
|
||||
addbyte(0xc6); /*MOVB tag[0][EBP], 3*/
|
||||
addbyte(0x45);
|
||||
addbyte(cpu_state_offset(tag[cpu_state.TOP]));
|
||||
addbyte(3);
|
||||
addbyte(0xc6); /*MOVB tag[1][EBP], 3*/
|
||||
addbyte(0x45);
|
||||
addbyte(cpu_state_offset(tag[(cpu_state.TOP+1)&7]));
|
||||
addbyte(3);
|
||||
addbyte(0xc6); /*MOVB TOP[EBP], (TOP+2) & 7*/
|
||||
addbyte(0x45);
|
||||
addbyte(cpu_state_offset(TOP));
|
||||
addbyte((cpu_state.TOP + 2) & 7);
|
||||
}
|
||||
else
|
||||
{
|
||||
addbyte(0x8b); /*MOV EAX, TOP*/
|
||||
addbyte(0x45);
|
||||
addbyte(cpu_state_offset(TOP));
|
||||
addbyte(0xc6); /*MOVB tag[EAX], 3*/
|
||||
addbyte(0x44);
|
||||
addbyte(0x05);
|
||||
addbyte(cpu_state_offset(tag[0]));
|
||||
addbyte(3);
|
||||
addbyte(0x04); /*ADD AL, 2*/
|
||||
addbyte(2);
|
||||
addbyte(0x24); /*AND AL, 7*/
|
||||
addbyte(7);
|
||||
addbyte(0x88); /*MOV TOP, AL*/
|
||||
addbyte(0x45);
|
||||
addbyte(cpu_state_offset(TOP));
|
||||
}
|
||||
}
|
||||
|
||||
#define FPU_ADD 0x00
|
||||
#define FPU_DIV 0x30
|
||||
@@ -3162,6 +3276,47 @@ static void FP_COMPARE_REG(int dst, int src)
|
||||
}
|
||||
}
|
||||
|
||||
static void FP_FCHS()
|
||||
{
|
||||
if (codeblock[block_current].flags & CODEBLOCK_STATIC_TOP)
|
||||
{
|
||||
addbyte(0xdd); /*FLD ST[0][EBP]*/
|
||||
addbyte(0x45);
|
||||
addbyte(cpu_state_offset(ST[cpu_state.TOP]));
|
||||
addbyte(0xd9); /*FCHS*/
|
||||
addbyte(0xe0);
|
||||
addbyte(0x80); /*AND tag[dst][EBP], ~TAG_UINT64*/
|
||||
addbyte(0x65);
|
||||
addbyte(cpu_state_offset(tag[cpu_state.TOP]));
|
||||
addbyte(~TAG_UINT64);
|
||||
addbyte(0xdd); /*FSTP ST[dst][EBP]*/
|
||||
addbyte(0x5d);
|
||||
addbyte(cpu_state_offset(ST[cpu_state.TOP]));
|
||||
}
|
||||
else
|
||||
{
|
||||
addbyte(0x8b); /*MOV EAX, TOP*/
|
||||
addbyte(0x45);
|
||||
addbyte(cpu_state_offset(TOP));
|
||||
|
||||
addbyte(0xdd); /*FLD [ESI+EAX*8]*/
|
||||
addbyte(0x44);
|
||||
addbyte(0xc5);
|
||||
addbyte(cpu_state_offset(ST));
|
||||
addbyte(0x80); /*AND tag[EAX], ~TAG_UINT64*/
|
||||
addbyte(0x64);
|
||||
addbyte(0x05);
|
||||
addbyte(cpu_state_offset(tag[0]));
|
||||
addbyte(~TAG_UINT64);
|
||||
addbyte(0xd9); /*FCHS*/
|
||||
addbyte(0xe0);
|
||||
addbyte(0xdd); /*FSTP ST[EAX*8]*/
|
||||
addbyte(0x5c);
|
||||
addbyte(0xc5);
|
||||
addbyte(cpu_state_offset(ST));
|
||||
}
|
||||
}
|
||||
|
||||
static void UPDATE_NPXC(int reg)
|
||||
{
|
||||
addbyte(0x66); /*AND cpu_state.new_npxc, ~0xc00*/
|
||||
@@ -3664,3 +3819,23 @@ static void MEM_CHECK_WRITE_L(x86seg *seg)
|
||||
addlong(mem_check_write_l - (uint32_t)(&codeblock[block_current].data[block_pos + 4]));
|
||||
LOAD_EA();
|
||||
}
|
||||
|
||||
static void LOAD_SEG(int host_reg, void *seg)
|
||||
{
|
||||
addbyte(0xc7); /*MOV [ESP+4], seg*/
|
||||
addbyte(0x44);
|
||||
addbyte(0x24);
|
||||
addbyte(4);
|
||||
addlong((uint32_t)seg);
|
||||
addbyte(0x89); /*MOV [ESP], host_reg*/
|
||||
addbyte(0x04 | (host_reg << 3));
|
||||
addbyte(0x24);
|
||||
CALL_FUNC(loadseg);
|
||||
addbyte(0x80); /*CMP abrt, 0*/
|
||||
addbyte(0x7d);
|
||||
addbyte(cpu_state_offset(abrt));
|
||||
addbyte(0);
|
||||
addbyte(0x0f); /*JNE end*/
|
||||
addbyte(0x85);
|
||||
addlong(BLOCK_EXIT_OFFSET - (block_pos + 4));
|
||||
}
|
||||
|
||||
@@ -550,17 +550,21 @@ static uint32_t gen_MEM_LOAD_ADDR_EA_B_NO_ABRT()
|
||||
addbyte(0x83); /*ADD ESP, 8*/
|
||||
addbyte(0xc4);
|
||||
addbyte(8);
|
||||
#ifndef RELEASE_BUILD
|
||||
addbyte(0x80); /*CMP abrt, 0*/
|
||||
addbyte(0x7d);
|
||||
addbyte(cpu_state_offset(abrt));
|
||||
addbyte(0);
|
||||
#endif
|
||||
addbyte(0x0f); /*MOVZX ECX, AL*/
|
||||
addbyte(0xb6);
|
||||
addbyte(0xc8);
|
||||
#ifndef RELEASE_BUILD
|
||||
addbyte(0x75); /*JNE mem_abrt_rout*/
|
||||
addbyte(1);
|
||||
#endif
|
||||
addbyte(0xc3); /*RET*/
|
||||
|
||||
#ifndef RELEASE_BUILD
|
||||
addbyte(0xc7); /*MOV [ESP], gen_MEM_LOAD_ADDR_EA_B_NO_ABRT_err*/
|
||||
addbyte(0x04);
|
||||
addbyte(0x24);
|
||||
@@ -568,7 +572,7 @@ static uint32_t gen_MEM_LOAD_ADDR_EA_B_NO_ABRT()
|
||||
addbyte(0xe8); /*CALL fatal*/
|
||||
addlong((uint32_t)fatal - (uint32_t)(&codeblock[block_current].data[block_pos + 4]));
|
||||
/*Should not return!*/
|
||||
|
||||
#endif
|
||||
return addr;
|
||||
}
|
||||
|
||||
@@ -615,17 +619,21 @@ static uint32_t gen_MEM_LOAD_ADDR_EA_W_NO_ABRT()
|
||||
addbyte(0x83); /*ADD ESP, 8*/
|
||||
addbyte(0xc4);
|
||||
addbyte(8);
|
||||
#ifndef RELEASE_BUILD
|
||||
addbyte(0x80); /*CMP abrt, 0*/
|
||||
addbyte(0x7d);
|
||||
addbyte(cpu_state_offset(abrt));
|
||||
addbyte(0);
|
||||
#endif
|
||||
addbyte(0x0f); /*MOVZX ECX, AX*/
|
||||
addbyte(0xb7);
|
||||
addbyte(0xc8);
|
||||
#ifndef RELEASE_BUILD
|
||||
addbyte(0x75); /*JNE mem_abrt_rout*/
|
||||
addbyte(1);
|
||||
#endif
|
||||
addbyte(0xc3); /*RET*/
|
||||
|
||||
#ifndef RELEASE_BUILD
|
||||
addbyte(0xc7); /*MOV [ESP], gen_MEM_LOAD_ADDR_EA_W_NO_ABRT_err*/
|
||||
addbyte(0x04);
|
||||
addbyte(0x24);
|
||||
@@ -633,7 +641,7 @@ static uint32_t gen_MEM_LOAD_ADDR_EA_W_NO_ABRT()
|
||||
addbyte(0xe8); /*CALL fatal*/
|
||||
addlong((uint32_t)fatal - (uint32_t)(&codeblock[block_current].data[block_pos + 4]));
|
||||
/*Should not return!*/
|
||||
|
||||
#endif
|
||||
return addr;
|
||||
}
|
||||
|
||||
@@ -681,14 +689,16 @@ static uint32_t gen_MEM_LOAD_ADDR_EA_L_NO_ABRT()
|
||||
addbyte(8);
|
||||
addbyte(0x89); /*MOV ECX, EAX*/
|
||||
addbyte(0xc1);
|
||||
#ifndef RELEASE_BUILD
|
||||
addbyte(0x80); /*CMP abrt, 0*/
|
||||
addbyte(0x7d);
|
||||
addbyte(cpu_state_offset(abrt));
|
||||
addbyte(0);
|
||||
addbyte(0x75); /*JNE mem_abrt_rout*/
|
||||
addbyte(1);
|
||||
#endif
|
||||
addbyte(0xc3); /*RET*/
|
||||
|
||||
#ifndef RELEASE_BUILD
|
||||
addbyte(0x83); /*SUBL 4,%esp*/
|
||||
addbyte(0xEC);
|
||||
addbyte(4);
|
||||
@@ -699,7 +709,7 @@ static uint32_t gen_MEM_LOAD_ADDR_EA_L_NO_ABRT()
|
||||
addbyte(0xe8); /*CALL fatal*/
|
||||
addlong((uint32_t)fatal - (uint32_t)(&codeblock[block_current].data[block_pos + 4]));
|
||||
/*Should not return!*/
|
||||
|
||||
#endif
|
||||
return addr;
|
||||
}
|
||||
|
||||
@@ -740,14 +750,16 @@ static uint32_t gen_MEM_STORE_ADDR_EA_B_NO_ABRT()
|
||||
addbyte(0x83); /*ADD ESP, 12*/
|
||||
addbyte(0xc4);
|
||||
addbyte(12);
|
||||
#ifndef RELEASE_BUILD
|
||||
addbyte(0x80); /*CMP abrt, 0*/
|
||||
addbyte(0x7d);
|
||||
addbyte(cpu_state_offset(abrt));
|
||||
addbyte(0);
|
||||
addbyte(0x75); /*JNE mem_abrt_rout*/
|
||||
addbyte(1);
|
||||
#endif
|
||||
addbyte(0xc3); /*RET*/
|
||||
|
||||
#ifndef RELEASE_BUILD
|
||||
addbyte(0xc7); /*MOV [ESP], gen_MEM_STORE_ADDR_EA_B_NO_ABRT_err*/
|
||||
addbyte(0x04);
|
||||
addbyte(0x24);
|
||||
@@ -755,7 +767,7 @@ static uint32_t gen_MEM_STORE_ADDR_EA_B_NO_ABRT()
|
||||
addbyte(0xe8); /*CALL fatal*/
|
||||
addlong((uint32_t)fatal - (uint32_t)(&codeblock[block_current].data[block_pos + 4]));
|
||||
/*Should not return!*/
|
||||
|
||||
#endif
|
||||
return addr;
|
||||
}
|
||||
|
||||
@@ -804,14 +816,16 @@ static uint32_t gen_MEM_STORE_ADDR_EA_W_NO_ABRT()
|
||||
addbyte(0x83); /*ADD ESP, 12*/
|
||||
addbyte(0xc4);
|
||||
addbyte(12);
|
||||
#ifndef RELEASE_BUILD
|
||||
addbyte(0x80); /*CMP abrt, 0*/
|
||||
addbyte(0x7d);
|
||||
addbyte(cpu_state_offset(abrt));
|
||||
addbyte(0);
|
||||
addbyte(0x75); /*JNE mem_abrt_rout*/
|
||||
addbyte(1);
|
||||
#endif
|
||||
addbyte(0xc3); /*RET*/
|
||||
|
||||
#ifndef RELEASE_BUILD
|
||||
addbyte(0xc7); /*MOV [ESP], gen_MEM_STORE_ADDR_EA_W_NO_ABRT_err*/
|
||||
addbyte(0x04);
|
||||
addbyte(0x24);
|
||||
@@ -819,7 +833,7 @@ static uint32_t gen_MEM_STORE_ADDR_EA_W_NO_ABRT()
|
||||
addbyte(0xe8); /*CALL fatal*/
|
||||
addlong((uint32_t)fatal - (uint32_t)(&codeblock[block_current].data[block_pos + 4]));
|
||||
/*Should not return!*/
|
||||
|
||||
#endif
|
||||
return addr;
|
||||
}
|
||||
|
||||
@@ -867,14 +881,16 @@ static uint32_t gen_MEM_STORE_ADDR_EA_L_NO_ABRT()
|
||||
addbyte(0x83); /*ADD ESP, 12*/
|
||||
addbyte(0xc4);
|
||||
addbyte(12);
|
||||
#ifndef RELEASE_BUILD
|
||||
addbyte(0x80); /*CMP abrt, 0*/
|
||||
addbyte(0x7d);
|
||||
addbyte(cpu_state_offset(abrt));
|
||||
addbyte(0);
|
||||
addbyte(0x75); /*JNE mem_abrt_rout*/
|
||||
addbyte(1);
|
||||
#endif
|
||||
addbyte(0xc3); /*RET*/
|
||||
|
||||
#ifndef RELEASE_BUILD
|
||||
addbyte(0xc7); /*MOV [ESP], gen_MEM_STORE_ADDR_EA_W_NO_ABRT_err*/
|
||||
addbyte(0x04);
|
||||
addbyte(0x24);
|
||||
@@ -882,7 +898,7 @@ static uint32_t gen_MEM_STORE_ADDR_EA_L_NO_ABRT()
|
||||
addbyte(0xe8); /*CALL fatal*/
|
||||
addlong((uint32_t)fatal - (uint32_t)(&codeblock[block_current].data[block_pos + 4]));
|
||||
/*Should not return!*/
|
||||
|
||||
#endif
|
||||
return addr;
|
||||
}
|
||||
|
||||
|
||||
594
src/cpu.c
594
src/cpu.c
@@ -77,8 +77,13 @@ int cpu_use_dynarec;
|
||||
|
||||
uint64_t cpu_CR4_mask;
|
||||
|
||||
int cpu_cycles_read, cpu_cycles_read_l, cpu_cycles_write, cpu_cycles_write_l;
|
||||
int cpu_prefetch_cycles, cpu_prefetch_width;
|
||||
int cpu_waitstates;
|
||||
int cpu_cache_int_enabled, cpu_cache_ext_enabled;
|
||||
|
||||
int is286, is386;
|
||||
int israpidcad;
|
||||
int israpidcad, is_pentium;
|
||||
|
||||
uint64_t tsc = 0;
|
||||
|
||||
@@ -159,218 +164,251 @@ static struct
|
||||
CPU cpus_8088[] =
|
||||
{
|
||||
/*8088 standard*/
|
||||
{"8088/4.77", CPU_8088, 0, 4772728, 1, 0, 0, 0, 0, 0},
|
||||
{"8088/7.16", CPU_8088, 1, 14318184/2, 1, 0, 0, 0, 0, 0},
|
||||
{"8088/8", CPU_8088, 1, 8000000, 1, 0, 0, 0, 0, 0},
|
||||
{"8088/10", CPU_8088, 2, 10000000, 1, 0, 0, 0, 0, 0},
|
||||
{"8088/12", CPU_8088, 3, 12000000, 1, 0, 0, 0, 0, 0},
|
||||
{"8088/16", CPU_8088, 4, 16000000, 1, 0, 0, 0, 0, 0},
|
||||
{"", -1, 0, 0, 0, 0}
|
||||
{"8088/4.77", CPU_8088, 0, 4772728, 1, 0, 0, 0, 0, 0, 0,0,0,0},
|
||||
{"8088/7.16", CPU_8088, 1, 14318184/2, 1, 0, 0, 0, 0, 0, 0,0,0,0},
|
||||
{"8088/8", CPU_8088, 1, 8000000, 1, 0, 0, 0, 0, 0, 0,0,0,0},
|
||||
{"8088/10", CPU_8088, 2, 10000000, 1, 0, 0, 0, 0, 0, 0,0,0,0},
|
||||
{"8088/12", CPU_8088, 3, 12000000, 1, 0, 0, 0, 0, 0, 0,0,0,0},
|
||||
{"8088/16", CPU_8088, 4, 16000000, 1, 0, 0, 0, 0, 0, 0,0,0,0},
|
||||
{"", -1, 0, 0, 0, 0, 0,0,0,0}
|
||||
};
|
||||
|
||||
CPU cpus_pcjr[] =
|
||||
{
|
||||
/*8088 PCjr*/
|
||||
{"8088/4.77", CPU_8088, 0, 4772728, 1, 0, 0, 0, 0, 0},
|
||||
{"", -1, 0, 0, 0, 0}
|
||||
{"8088/4.77", CPU_8088, 0, 4772728, 1, 0, 0, 0, 0, 0, 0,0,0,0},
|
||||
{"", -1, 0, 0, 0, 0, 0,0,0,0}
|
||||
};
|
||||
|
||||
CPU cpus_8086[] =
|
||||
{
|
||||
/*8086 standard*/
|
||||
{"8086/7.16", CPU_8086, 1, 14318184/2, 1, 0, 0, 0, 0, 0},
|
||||
{"8086/8", CPU_8086, 1, 8000000, 1, 0, 0, 0, 0, 0},
|
||||
{"8086/9.54", CPU_8086, 1, 4772728*2, 1, 0, 0, 0, 0, 0},
|
||||
{"8086/10", CPU_8086, 2, 10000000, 1, 0, 0, 0, 0, 0},
|
||||
{"8086/12", CPU_8086, 3, 12000000, 1, 0, 0, 0, 0, 0},
|
||||
{"8086/16", CPU_8086, 4, 16000000, 1, 0, 0, 0, 0, 0},
|
||||
{"", -1, 0, 0, 0, 0}
|
||||
{"8086/7.16", CPU_8086, 1, 14318184/2, 1, 0, 0, 0, 0, 0, 0,0,0,0},
|
||||
{"8086/8", CPU_8086, 1, 8000000, 1, 0, 0, 0, 0, 0, 0,0,0,0},
|
||||
{"8086/9.54", CPU_8086, 1, 4772728*2, 1, 0, 0, 0, 0, 0, 0,0,0,0},
|
||||
{"8086/10", CPU_8086, 2, 10000000, 1, 0, 0, 0, 0, 0, 0,0,0,0},
|
||||
{"8086/12", CPU_8086, 3, 12000000, 1, 0, 0, 0, 0, 0, 0,0,0,0},
|
||||
{"8086/16", CPU_8086, 4, 16000000, 1, 0, 0, 0, 0, 0, 0,0,0,0},
|
||||
{"", -1, 0, 0, 0, 0, 0,0,0,0}
|
||||
};
|
||||
|
||||
CPU cpus_pc1512[] =
|
||||
{
|
||||
/*8086 Amstrad*/
|
||||
{"8086/8", CPU_8086, 1, 8000000, 1, 0, 0, 0, 0, 0},
|
||||
{"", -1, 0, 0, 0, 0}
|
||||
{"8086/8", CPU_8086, 1, 8000000, 1, 0, 0, 0, 0, 0, 0,0,0,0},
|
||||
{"", -1, 0, 0, 0, 0, 0,0,0,0}
|
||||
};
|
||||
|
||||
CPU cpus_286[] =
|
||||
{
|
||||
/*286*/
|
||||
{"286/6", CPU_286, 0, 6000000, 1, 0, 0, 0, 0, 0},
|
||||
{"286/8", CPU_286, 1, 8000000, 1, 0, 0, 0, 0, 0},
|
||||
{"286/10", CPU_286, 2, 10000000, 1, 0, 0, 0, 0, 0},
|
||||
{"286/12", CPU_286, 3, 12000000, 1, 0, 0, 0, 0, 0},
|
||||
{"286/16", CPU_286, 4, 16000000, 1, 0, 0, 0, 0, 0},
|
||||
{"286/20", CPU_286, 5, 20000000, 1, 0, 0, 0, 0, 0},
|
||||
{"286/25", CPU_286, 6, 25000000, 1, 0, 0, 0, 0, 0},
|
||||
{"286/6", CPU_286, 0, 6000000, 1, 0, 0, 0, 0, 0, 2,2,2,2},
|
||||
{"286/8", CPU_286, 1, 8000000, 1, 0, 0, 0, 0, 0, 2,2,2,2},
|
||||
{"286/10", CPU_286, 2, 10000000, 1, 0, 0, 0, 0, 0, 2,2,2,2},
|
||||
{"286/12", CPU_286, 3, 12000000, 1, 0, 0, 0, 0, 0, 3,3,3,3},
|
||||
{"286/16", CPU_286, 4, 16000000, 1, 0, 0, 0, 0, 0, 3,3,3,3},
|
||||
{"286/20", CPU_286, 5, 20000000, 1, 0, 0, 0, 0, 0, 4,4,4,4},
|
||||
{"286/25", CPU_286, 6, 25000000, 1, 0, 0, 0, 0, 0, 4,4,4,4},
|
||||
{"", -1, 0, 0, 0, 0}
|
||||
};
|
||||
|
||||
CPU cpus_ibmat[] =
|
||||
{
|
||||
/*286*/
|
||||
{"286/6", CPU_286, 0, 6000000, 1, 0, 0, 0, 0, 0},
|
||||
{"286/8", CPU_286, 0, 8000000, 1, 0, 0, 0, 0, 0},
|
||||
{"286/6", CPU_286, 0, 6000000, 1, 0, 0, 0, 0, 0, 3,3,3,3},
|
||||
{"286/8", CPU_286, 0, 8000000, 1, 0, 0, 0, 0, 0, 3,3,3,3},
|
||||
{"", -1, 0, 0, 0, 0}
|
||||
};
|
||||
|
||||
CPU cpus_ps1_m2011[] =
|
||||
{
|
||||
/*286*/
|
||||
{"286/10", CPU_286, 2, 10000000, 1, 0, 0, 0, 0, 0},
|
||||
{"286/10", CPU_286, 2, 10000000, 1, 0, 0, 0, 0, 0, 2,2,2,2},
|
||||
{"", -1, 0, 0, 0, 0}
|
||||
};
|
||||
|
||||
CPU cpus_i386[] =
|
||||
{
|
||||
/*i386*/
|
||||
{"i386SX/16", CPU_386SX, 0, 16000000, 1, 0, 0x2308, 0, 0, 0},
|
||||
{"i386SX/20", CPU_386SX, 1, 20000000, 1, 0, 0x2308, 0, 0, 0},
|
||||
{"i386SX/25", CPU_386SX, 2, 25000000, 1, 0, 0x2308, 0, 0, 0},
|
||||
{"i386SX/33", CPU_386SX, 3, 33333333, 1, 0, 0x2308, 0, 0, 0},
|
||||
{"i386SX/40", CPU_386SX, 4, 40000000, 1, 0, 0x2308, 0, 0, 0},
|
||||
{"i386DX/16", CPU_386DX, 0, 16000000, 1, 0, 0x0308, 0, 0, 0},
|
||||
{"i386DX/20", CPU_386DX, 1, 20000000, 1, 0, 0x0308, 0, 0, 0},
|
||||
{"i386DX/25", CPU_386DX, 2, 25000000, 1, 0, 0x0308, 0, 0, 0},
|
||||
{"i386DX/33", CPU_386DX, 3, 33333333, 1, 0, 0x0308, 0, 0, 0},
|
||||
{"i386DX/40", CPU_386DX, 4, 40000000, 1, 0, 0x0308, 0, 0, 0},
|
||||
{"RapidCAD/25", CPU_RAPIDCAD, 2, 25000000, 1, 0, 0x430, 0, 0, 0},
|
||||
{"RapidCAD/33", CPU_RAPIDCAD, 3, 33333333, 1, 0, 0x430, 0, 0, 0},
|
||||
{"RapidCAD/40", CPU_RAPIDCAD, 4, 40000000, 1, 0, 0x430, 0, 0, 0},
|
||||
{"i386SX/16", CPU_386SX, 0, 16000000, 1, 0, 0x2308, 0, 0, 0, 3,3,3,3},
|
||||
{"i386SX/20", CPU_386SX, 1, 20000000, 1, 0, 0x2308, 0, 0, 0, 4,4,3,3},
|
||||
{"i386SX/25", CPU_386SX, 2, 25000000, 1, 0, 0x2308, 0, 0, 0, 4,4,3,3},
|
||||
{"i386SX/33", CPU_386SX, 3, 33333333, 1, 0, 0x2308, 0, 0, 0, 6,6,3,3},
|
||||
{"i386SX/40", CPU_386SX, 4, 40000000, 1, 0, 0x2308, 0, 0, 0, 7,7,3,3},
|
||||
{"i386DX/16", CPU_386DX, 0, 16000000, 1, 0, 0x0308, 0, 0, 0, 3,3,3,3},
|
||||
{"i386DX/20", CPU_386DX, 1, 20000000, 1, 0, 0x0308, 0, 0, 0, 4,4,3,3},
|
||||
{"i386DX/25", CPU_386DX, 2, 25000000, 1, 0, 0x0308, 0, 0, 0, 4,4,3,3},
|
||||
{"i386DX/33", CPU_386DX, 3, 33333333, 1, 0, 0x0308, 0, 0, 0, 6,6,3,3},
|
||||
{"i386DX/40", CPU_386DX, 4, 40000000, 1, 0, 0x0308, 0, 0, 0, 7,7,3,3},
|
||||
{"RapidCAD/25", CPU_RAPIDCAD, 2, 25000000, 1, 0, 0x430, 0, 0, 0, 4,4,3,3},
|
||||
{"RapidCAD/33", CPU_RAPIDCAD, 3, 33333333, 1, 0, 0x430, 0, 0, 0, 6,6,3,3},
|
||||
{"RapidCAD/40", CPU_RAPIDCAD, 4, 40000000, 1, 0, 0x430, 0, 0, 0, 7,7,3,3},
|
||||
{"", -1, 0, 0, 0}
|
||||
};
|
||||
|
||||
CPU cpus_i386DX[] =
|
||||
{
|
||||
/*i386*/
|
||||
{"i386DX/16", CPU_386DX, 0, 16000000, 1, 0, 0x0308, 0, 0, 0, 3,3,3,3},
|
||||
{"i386DX/20", CPU_386DX, 1, 20000000, 1, 0, 0x0308, 0, 0, 0, 4,4,3,3},
|
||||
{"i386DX/25", CPU_386DX, 2, 25000000, 1, 0, 0x0308, 0, 0, 0, 4,4,3,3},
|
||||
{"i386DX/33", CPU_386DX, 3, 33333333, 1, 0, 0x0308, 0, 0, 0, 6,6,3,3},
|
||||
{"i386DX/40", CPU_386DX, 4, 40000000, 1, 0, 0x0308, 0, 0, 0, 7,7,3,3},
|
||||
{"RapidCAD/25", CPU_RAPIDCAD, 2, 25000000, 1, 0, 0x430, 0, 0, 0, 4,4,3,3},
|
||||
{"RapidCAD/33", CPU_RAPIDCAD, 3, 33333333, 1, 0, 0x430, 0, 0, 0, 6,6,3,3},
|
||||
{"RapidCAD/40", CPU_RAPIDCAD, 4, 40000000, 1, 0, 0x430, 0, 0, 0, 7,7,3,3},
|
||||
{"", -1, 0, 0, 0}
|
||||
};
|
||||
|
||||
CPU cpus_acer[] =
|
||||
{
|
||||
/*i386*/
|
||||
{"i386SX/25", CPU_386SX, 2, 25000000, 1, 0, 0x2308, 0, 0, 0},
|
||||
{"i386SX/25", CPU_386SX, 2, 25000000, 1, 0, 0x2308, 0, 0, 0, 4,4,4,4},
|
||||
{"", -1, 0, 0, 0}
|
||||
};
|
||||
|
||||
CPU cpus_Am386[] =
|
||||
{
|
||||
/*Am386*/
|
||||
{"Am386SX/16", CPU_386SX, 0, 16000000, 1, 0, 0x2308, 0, 0, 0},
|
||||
{"Am386SX/20", CPU_386SX, 1, 20000000, 1, 0, 0x2308, 0, 0, 0},
|
||||
{"Am386SX/25", CPU_386SX, 2, 25000000, 1, 0, 0x2308, 0, 0, 0},
|
||||
{"Am386SX/33", CPU_386SX, 3, 33333333, 1, 0, 0x2308, 0, 0, 0},
|
||||
{"Am386SX/40", CPU_386SX, 4, 40000000, 1, 0, 0x2308, 0, 0, 0},
|
||||
{"Am386DX/25", CPU_386DX, 2, 25000000, 1, 0, 0x0308, 0, 0, 0},
|
||||
{"Am386DX/33", CPU_386DX, 3, 33333333, 1, 0, 0x0308, 0, 0, 0},
|
||||
{"Am386DX/40", CPU_386DX, 4, 40000000, 1, 0, 0x0308, 0, 0, 0},
|
||||
{"Am386SX/16", CPU_386SX, 0, 16000000, 1, 0, 0x2308, 0, 0, 0, 3,3,3,3},
|
||||
{"Am386SX/20", CPU_386SX, 1, 20000000, 1, 0, 0x2308, 0, 0, 0, 4,4,3,3},
|
||||
{"Am386SX/25", CPU_386SX, 2, 25000000, 1, 0, 0x2308, 0, 0, 0, 4,4,3,3},
|
||||
{"Am386SX/33", CPU_386SX, 3, 33333333, 1, 0, 0x2308, 0, 0, 0, 6,6,3,3},
|
||||
{"Am386SX/40", CPU_386SX, 4, 40000000, 1, 0, 0x2308, 0, 0, 0, 7,7,3,3},
|
||||
{"Am386DX/25", CPU_386DX, 2, 25000000, 1, 0, 0x0308, 0, 0, 0, 4,4,3,3},
|
||||
{"Am386DX/33", CPU_386DX, 3, 33333333, 1, 0, 0x0308, 0, 0, 0, 6,6,3,3},
|
||||
{"Am386DX/40", CPU_386DX, 4, 40000000, 1, 0, 0x0308, 0, 0, 0, 7,7,3,3},
|
||||
{"", -1, 0, 0, 0}
|
||||
};
|
||||
|
||||
CPU cpus_Am386DX[] =
|
||||
|
||||
{
|
||||
/*Am386*/
|
||||
{"Am386DX/25", CPU_386DX, 2, 25000000, 1, 0, 0x0308, 0, 0, 0, 4,4,3,3},
|
||||
{"Am386DX/33", CPU_386DX, 3, 33333333, 1, 0, 0x0308, 0, 0, 0, 6,6,3,3},
|
||||
{"Am386DX/40", CPU_386DX, 4, 40000000, 1, 0, 0x0308, 0, 0, 0, 7,7,3,3},
|
||||
{"", -1, 0, 0, 0}
|
||||
};
|
||||
|
||||
CPU cpus_486SDLC[] =
|
||||
{
|
||||
/*Cx486SLC/DLC*/
|
||||
{"Cx486SLC/20", CPU_486SLC, 1, 20000000, 1, 0, 0, 0, 0x0000, 0},
|
||||
{"Cx486SLC/25", CPU_486SLC, 2, 25000000, 1, 0, 0, 0, 0x0000, 0},
|
||||
{"Cx486SLC/33", CPU_486SLC, 3, 33333333, 1, 0, 0, 0, 0x0000, 0},
|
||||
{"Cx486SRx2/32", CPU_486SLC, 3, 32000000, 2, 0, 0, 0, 0x0006, 0},
|
||||
{"Cx486SRx2/40", CPU_486SLC, 4, 40000000, 2, 0, 0, 0, 0x0006, 0},
|
||||
{"Cx486SRx2/50", CPU_486SLC, 5, 50000000, 2, 0, 0, 0, 0x0006, 0},
|
||||
{"Cx486DLC/25", CPU_486DLC, 2, 25000000, 1, 0, 0, 0, 0x0001, 0},
|
||||
{"Cx486DLC/33", CPU_486DLC, 3, 33333333, 1, 0, 0, 0, 0x0001, 0},
|
||||
{"Cx486DLC/40", CPU_486DLC, 4, 40000000, 1, 0, 0, 0, 0x0001, 0},
|
||||
{"Cx486DRx2/32", CPU_486DLC, 3, 32000000, 2, 0, 0, 0, 0x0007, 0},
|
||||
{"Cx486DRx2/40", CPU_486DLC, 4, 40000000, 2, 0, 0, 0, 0x0007, 0},
|
||||
{"Cx486DRx2/50", CPU_486DLC, 5, 50000000, 2, 0, 0, 0, 0x0007, 0},
|
||||
{"Cx486DRx2/66", CPU_486DLC, 6, 66666666, 2, 0, 0, 0, 0x0007, 0},
|
||||
{"Cx486SLC/20", CPU_486SLC, 1, 20000000, 1, 0, 0x400, 0, 0x0000, 0, 4,4,3,3},
|
||||
{"Cx486SLC/25", CPU_486SLC, 2, 25000000, 1, 0, 0x400, 0, 0x0000, 0, 4,4,3,3},
|
||||
{"Cx486SLC/33", CPU_486SLC, 3, 33333333, 1, 0, 0x400, 0, 0x0000, 0, 6,6,3,3},
|
||||
{"Cx486SRx2/32", CPU_486SLC, 3, 32000000, 2, 0, 0x406, 0, 0x0006, 0, 6,6,6,6},
|
||||
{"Cx486SRx2/40", CPU_486SLC, 4, 40000000, 2, 0, 0x406, 0, 0x0006, 0, 8,8,6,6},
|
||||
{"Cx486SRx2/50", CPU_486SLC, 5, 50000000, 2, 0, 0x406, 0, 0x0006, 0, 8,8,6,6},
|
||||
{"Cx486DLC/25", CPU_486DLC, 2, 25000000, 1, 0, 0x401, 0, 0x0001, 0, 4,4,3,3},
|
||||
{"Cx486DLC/33", CPU_486DLC, 3, 33333333, 1, 0, 0x401, 0, 0x0001, 0, 6,6,3,3},
|
||||
{"Cx486DLC/40", CPU_486DLC, 4, 40000000, 1, 0, 0x401, 0, 0x0001, 0, 7,7,3,3},
|
||||
{"Cx486DRx2/32", CPU_486DLC, 3, 32000000, 2, 0, 0x407, 0, 0x0007, 0, 6,6,6,6},
|
||||
{"Cx486DRx2/40", CPU_486DLC, 4, 40000000, 2, 0, 0x407, 0, 0x0007, 0, 8,8,6,6},
|
||||
{"Cx486DRx2/50", CPU_486DLC, 5, 50000000, 2, 0, 0x407, 0, 0x0007, 0, 8,8,6,6},
|
||||
{"Cx486DRx2/66", CPU_486DLC, 6, 66666666, 2, 0, 0x407, 0, 0x0007, 0, 12,12,6,6},
|
||||
{"", -1, 0, 0, 0}
|
||||
};
|
||||
|
||||
CPU cpus_486DLC[] =
|
||||
{
|
||||
/*Cx486DLC*/
|
||||
{"Cx486DLC/25", CPU_486DLC, 2, 25000000, 1, 0, 0x401, 0, 0x0001, 0, 4,4,3,3},
|
||||
{"Cx486DLC/33", CPU_486DLC, 3, 33333333, 1, 0, 0x401, 0, 0x0001, 0, 6,6,3,3},
|
||||
{"Cx486DLC/40", CPU_486DLC, 4, 40000000, 1, 0, 0x401, 0, 0x0001, 0, 7,7,3,3},
|
||||
{"Cx486DRx2/32", CPU_486DLC, 3, 32000000, 2, 0, 0x407, 0, 0x0007, 0, 6,6,6,6},
|
||||
{"Cx486DRx2/40", CPU_486DLC, 4, 40000000, 2, 0, 0x407, 0, 0x0007, 0, 8,8,6,6},
|
||||
{"Cx486DRx2/50", CPU_486DLC, 5, 50000000, 2, 0, 0x407, 0, 0x0007, 0, 8,8,6,6},
|
||||
{"Cx486DRx2/66", CPU_486DLC, 6, 66666666, 2, 0, 0x407, 0, 0x0007, 0, 12,12,6,6},
|
||||
{"", -1, 0, 0, 0}
|
||||
};
|
||||
|
||||
CPU cpus_i486[] =
|
||||
{
|
||||
/*i486*/
|
||||
{"i486SX/16", CPU_i486SX, 0, 16000000, 1, 16000000, 0x42a, 0, 0, CPU_SUPPORTS_DYNAREC},
|
||||
{"i486SX/20", CPU_i486SX, 1, 20000000, 1, 20000000, 0x42a, 0, 0, CPU_SUPPORTS_DYNAREC},
|
||||
{"i486SX/25", CPU_i486SX, 2, 25000000, 1, 25000000, 0x42a, 0, 0, CPU_SUPPORTS_DYNAREC},
|
||||
{"i486SX/33", CPU_i486SX, 3, 33333333, 1, 33333333, 0x42a, 0, 0, CPU_SUPPORTS_DYNAREC},
|
||||
{"i486SX2/50", CPU_i486SX, 5, 50000000, 2, 25000000, 0x45b, 0, 0, CPU_SUPPORTS_DYNAREC},
|
||||
{"i486DX/25", CPU_i486DX, 2, 25000000, 1, 25000000, 0x404, 0, 0, CPU_SUPPORTS_DYNAREC},
|
||||
{"i486DX/33", CPU_i486DX, 3, 33333333, 1, 33333333, 0x404, 0, 0, CPU_SUPPORTS_DYNAREC},
|
||||
{"i486DX/50", CPU_i486DX, 5, 50000000, 1, 25000000, 0x404, 0, 0, CPU_SUPPORTS_DYNAREC},
|
||||
{"i486DX2/40", CPU_i486DX, 4, 40000000, 2, 20000000, 0x430, 0, 0, CPU_SUPPORTS_DYNAREC},
|
||||
{"i486DX2/50", CPU_i486DX, 5, 50000000, 2, 25000000, 0x430, 0, 0, CPU_SUPPORTS_DYNAREC},
|
||||
{"i486DX2/66", CPU_i486DX, 6, 66666666, 2, 33333333, 0x430, 0, 0, CPU_SUPPORTS_DYNAREC},
|
||||
{"iDX4/75", CPU_i486DX, 7, 75000000, 3, 25000000, 0x481, 0x481, 0, CPU_SUPPORTS_DYNAREC}, /*CPUID available on DX4, >= 75 MHz*/
|
||||
{"iDX4/100", CPU_i486DX,10, 100000000, 3, 33333333, 0x481, 0x481, 0, CPU_SUPPORTS_DYNAREC}, /*Is on some real Intel DX2s, limit here is pretty arbitary*/
|
||||
{"Pentium OverDrive/63", CPU_PENTIUM, 6, 62500000, 3, 25000000, 0x1531, 0x1531, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC},
|
||||
{"Pentium OverDrive/83", CPU_PENTIUM, 8, 83333333, 3, 33333333, 0x1532, 0x1532, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC},
|
||||
{"i486SX/16", CPU_i486SX, 0, 16000000, 1, 16000000, 0x42a, 0, 0, CPU_SUPPORTS_DYNAREC, 3,3,3,3},
|
||||
{"i486SX/20", CPU_i486SX, 1, 20000000, 1, 20000000, 0x42a, 0, 0, CPU_SUPPORTS_DYNAREC, 4,4,3,3},
|
||||
{"i486SX/25", CPU_i486SX, 2, 25000000, 1, 25000000, 0x42a, 0, 0, CPU_SUPPORTS_DYNAREC, 4,4,3,3},
|
||||
{"i486SX/33", CPU_i486SX, 3, 33333333, 1, 33333333, 0x42a, 0, 0, CPU_SUPPORTS_DYNAREC, 6,6,3,3},
|
||||
{"i486SX2/50", CPU_i486SX, 5, 50000000, 2, 25000000, 0x45b, 0, 0, CPU_SUPPORTS_DYNAREC, 8,8,6,6},
|
||||
{"i486DX/25", CPU_i486DX, 2, 25000000, 1, 25000000, 0x404, 0, 0, CPU_SUPPORTS_DYNAREC, 4,4,3,3},
|
||||
{"i486DX/33", CPU_i486DX, 3, 33333333, 1, 33333333, 0x404, 0, 0, CPU_SUPPORTS_DYNAREC, 6,6,3,3},
|
||||
{"i486DX/50", CPU_i486DX, 5, 50000000, 1, 25000000, 0x404, 0, 0, CPU_SUPPORTS_DYNAREC, 8,8,4,4},
|
||||
{"i486DX2/40", CPU_i486DX, 4, 40000000, 2, 20000000, 0x430, 0, 0, CPU_SUPPORTS_DYNAREC, 8,8,6,6},
|
||||
{"i486DX2/50", CPU_i486DX, 5, 50000000, 2, 25000000, 0x430, 0, 0, CPU_SUPPORTS_DYNAREC, 8,8,6,6},
|
||||
{"i486DX2/66", CPU_i486DX, 6, 66666666, 2, 33333333, 0x430, 0, 0, CPU_SUPPORTS_DYNAREC, 12,12,6,6},
|
||||
{"iDX4/75", CPU_i486DX, 7, 75000000, 3, 25000000, 0x481, 0x481, 0, CPU_SUPPORTS_DYNAREC, 12,12,9,9}, /*CPUID available on DX4, >= 75 MHz*/
|
||||
{"iDX4/100", CPU_i486DX,10, 100000000, 3, 33333333, 0x481, 0x481, 0, CPU_SUPPORTS_DYNAREC, 18,18,9,9}, /*Is on some real Intel DX2s, limit here is pretty arbitary*/
|
||||
{"Pentium OverDrive/63", CPU_PENTIUM, 6, 62500000, 3, 25000000, 0x1531, 0x1531, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 10,10,7,7},
|
||||
{"Pentium OverDrive/83", CPU_PENTIUM, 8, 83333333, 3, 33333333, 0x1532, 0x1532, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,8,8},
|
||||
{"", -1, 0, 0, 0}
|
||||
};
|
||||
|
||||
CPU cpus_Am486[] =
|
||||
{
|
||||
/*Am486/5x86*/
|
||||
{"Am486SX/33", CPU_Am486SX, 3, 33333333, 1, 33333333, 0x42a, 0, 0, CPU_SUPPORTS_DYNAREC},
|
||||
{"Am486SX/40", CPU_Am486SX, 4, 40000000, 1, 20000000, 0x42a, 0, 0, CPU_SUPPORTS_DYNAREC},
|
||||
{"Am486SX2/50", CPU_Am486SX, 5, 50000000, 2, 25000000, 0x45b, 0x45b, 0, CPU_SUPPORTS_DYNAREC}, /*CPUID available on SX2, DX2, DX4, 5x86, >= 50 MHz*/
|
||||
{"Am486SX2/66", CPU_Am486SX, 6, 66666666, 2, 33333333, 0x45b, 0x45b, 0, CPU_SUPPORTS_DYNAREC}, /*Isn't on all real AMD SX2s and DX2s, availability here is pretty arbitary (and distinguishes them from the Intel chips)*/
|
||||
{"Am486DX/33", CPU_Am486DX, 3, 33333333, 1, 33333333, 0x430, 0, 0, CPU_SUPPORTS_DYNAREC},
|
||||
{"Am486DX/40", CPU_Am486DX, 4, 40000000, 1, 20000000, 0x430, 0, 0, CPU_SUPPORTS_DYNAREC},
|
||||
{"Am486DX2/50", CPU_Am486DX, 5, 50000000, 2, 25000000, 0x470, 0x470, 0, CPU_SUPPORTS_DYNAREC},
|
||||
{"Am486DX2/66", CPU_Am486DX, 6, 66666666, 2, 33333333, 0x470, 0x470, 0, CPU_SUPPORTS_DYNAREC},
|
||||
{"Am486DX2/80", CPU_Am486DX, 8, 80000000, 2, 20000000, 0x470, 0x470, 0, CPU_SUPPORTS_DYNAREC},
|
||||
{"Am486DX4/75", CPU_Am486DX, 7, 75000000, 3, 25000000, 0x482, 0x482, 0, CPU_SUPPORTS_DYNAREC},
|
||||
{"Am486DX4/90", CPU_Am486DX, 9, 90000000, 3, 30000000, 0x482, 0x482, 0, CPU_SUPPORTS_DYNAREC},
|
||||
{"Am486DX4/100", CPU_Am486DX, 10, 100000000, 3, 33333333, 0x482, 0x482, 0, CPU_SUPPORTS_DYNAREC},
|
||||
{"Am486DX4/120", CPU_Am486DX, 11, 120000000, 3, 20000000, 0x482, 0x482, 0, CPU_SUPPORTS_DYNAREC},
|
||||
{"Am5x86/P75", CPU_Am486DX, 12, 133333333, 4, 33333333, 0x4e0, 0x4e0, 0, CPU_SUPPORTS_DYNAREC},
|
||||
{"Am5x86/P75+", CPU_Am486DX, 13, 160000000, 4, 20000000, 0x4e0, 0x4e0, 0, CPU_SUPPORTS_DYNAREC},
|
||||
{"Am486SX/33", CPU_Am486SX, 3, 33333333, 1, 33333333, 0x42a, 0, 0, CPU_SUPPORTS_DYNAREC, 6,6,3,3},
|
||||
{"Am486SX/40", CPU_Am486SX, 4, 40000000, 1, 20000000, 0x42a, 0, 0, CPU_SUPPORTS_DYNAREC, 7,7,3,3},
|
||||
{"Am486SX2/50", CPU_Am486SX, 5, 50000000, 2, 25000000, 0x45b, 0x45b, 0, CPU_SUPPORTS_DYNAREC, 8,8,6,6}, /*CPUID available on SX2, DX2, DX4, 5x86, >= 50 MHz*/
|
||||
{"Am486SX2/66", CPU_Am486SX, 6, 66666666, 2, 33333333, 0x45b, 0x45b, 0, CPU_SUPPORTS_DYNAREC, 12,12,6,6}, /*Isn't on all real AMD SX2s and DX2s, availability here is pretty arbitary (and distinguishes them from the Intel chips)*/
|
||||
{"Am486DX/33", CPU_Am486DX, 3, 33333333, 1, 33333333, 0x430, 0, 0, CPU_SUPPORTS_DYNAREC, 6,6,3,3},
|
||||
{"Am486DX/40", CPU_Am486DX, 4, 40000000, 1, 20000000, 0x430, 0, 0, CPU_SUPPORTS_DYNAREC, 7,7,3,3},
|
||||
{"Am486DX2/50", CPU_Am486DX, 5, 50000000, 2, 25000000, 0x470, 0x470, 0, CPU_SUPPORTS_DYNAREC, 8,8,6,6},
|
||||
{"Am486DX2/66", CPU_Am486DX, 6, 66666666, 2, 33333333, 0x470, 0x470, 0, CPU_SUPPORTS_DYNAREC, 12,12,6,6},
|
||||
{"Am486DX2/80", CPU_Am486DX, 8, 80000000, 2, 20000000, 0x470, 0x470, 0, CPU_SUPPORTS_DYNAREC, 14,14,6,6},
|
||||
{"Am486DX4/75", CPU_Am486DX, 7, 75000000, 3, 25000000, 0x482, 0x482, 0, CPU_SUPPORTS_DYNAREC, 12,12,9,9},
|
||||
{"Am486DX4/90", CPU_Am486DX, 9, 90000000, 3, 30000000, 0x482, 0x482, 0, CPU_SUPPORTS_DYNAREC, 15,15,9,9},
|
||||
{"Am486DX4/100", CPU_Am486DX, 10, 100000000, 3, 33333333, 0x482, 0x482, 0, CPU_SUPPORTS_DYNAREC, 15,15,9,9},
|
||||
{"Am486DX4/120", CPU_Am486DX, 11, 120000000, 3, 20000000, 0x482, 0x482, 0, CPU_SUPPORTS_DYNAREC, 21,21,9,9},
|
||||
{"Am5x86/P75", CPU_Am486DX, 12, 133333333, 4, 33333333, 0x4e0, 0x4e0, 0, CPU_SUPPORTS_DYNAREC, 24,24,12,12},
|
||||
{"Am5x86/P75+", CPU_Am486DX, 13, 160000000, 4, 20000000, 0x4e0, 0x4e0, 0, CPU_SUPPORTS_DYNAREC, 28,28,12,12},
|
||||
{"", -1, 0, 0, 0}
|
||||
};
|
||||
|
||||
CPU cpus_Cx486[] =
|
||||
{
|
||||
/*Cx486/5x86*/
|
||||
{"Cx486S/25", CPU_Cx486S, 2, 25000000, 1, 25000000, 0x420, 0, 0x0010, CPU_SUPPORTS_DYNAREC},
|
||||
{"Cx486S/33", CPU_Cx486S, 3, 33333333, 1, 33333333, 0x420, 0, 0x0010, CPU_SUPPORTS_DYNAREC},
|
||||
{"Cx486S/40", CPU_Cx486S, 4, 40000000, 1, 20000000, 0x420, 0, 0x0010, CPU_SUPPORTS_DYNAREC},
|
||||
{"Cx486DX/33", CPU_Cx486DX, 3, 33333333, 1, 33333333, 0x430, 0, 0x051a, CPU_SUPPORTS_DYNAREC},
|
||||
{"Cx486DX/40", CPU_Cx486DX, 4, 40000000, 1, 20000000, 0x430, 0, 0x051a, CPU_SUPPORTS_DYNAREC},
|
||||
{"Cx486DX2/50", CPU_Cx486DX, 5, 50000000, 2, 25000000, 0x430, 0, 0x081b, CPU_SUPPORTS_DYNAREC},
|
||||
{"Cx486DX2/66", CPU_Cx486DX, 6, 66666666, 2, 33333333, 0x430, 0, 0x0b1b, CPU_SUPPORTS_DYNAREC},
|
||||
{"Cx486DX2/80", CPU_Cx486DX, 8, 80000000, 2, 20000000, 0x430, 0, 0x311b, CPU_SUPPORTS_DYNAREC},
|
||||
{"Cx486DX4/75", CPU_Cx486DX, 7, 75000000, 3, 25000000, 0x480, 0, 0x361f, CPU_SUPPORTS_DYNAREC},
|
||||
{"Cx486DX4/100", CPU_Cx486DX, 10, 100000000, 3, 33333333, 0x480, 0, 0x361f, CPU_SUPPORTS_DYNAREC},
|
||||
{"Cx5x86/100", CPU_Cx5x86, 10, 100000000, 3, 33333333, 0x480, 0, 0x002f, CPU_SUPPORTS_DYNAREC},
|
||||
{"Cx5x86/120", CPU_Cx5x86, 11, 120000000, 3, 20000000, 0x480, 0, 0x002f, CPU_SUPPORTS_DYNAREC},
|
||||
{"Cx5x86/133", CPU_Cx5x86, 12, 133333333, 4, 33333333, 0x480, 0, 0x002f, CPU_SUPPORTS_DYNAREC},
|
||||
{"Cx486S/25", CPU_Cx486S, 2, 25000000, 1, 25000000, 0x420, 0, 0x0010, CPU_SUPPORTS_DYNAREC, 4,4,3,3},
|
||||
{"Cx486S/33", CPU_Cx486S, 3, 33333333, 1, 33333333, 0x420, 0, 0x0010, CPU_SUPPORTS_DYNAREC, 6,6,3,3},
|
||||
{"Cx486S/40", CPU_Cx486S, 4, 40000000, 1, 20000000, 0x420, 0, 0x0010, CPU_SUPPORTS_DYNAREC, 7,7,3,3},
|
||||
{"Cx486DX/33", CPU_Cx486DX, 3, 33333333, 1, 33333333, 0x430, 0, 0x051a, CPU_SUPPORTS_DYNAREC, 6,6,3,3},
|
||||
{"Cx486DX/40", CPU_Cx486DX, 4, 40000000, 1, 20000000, 0x430, 0, 0x051a, CPU_SUPPORTS_DYNAREC, 7,7,3,3},
|
||||
{"Cx486DX2/50", CPU_Cx486DX, 5, 50000000, 2, 25000000, 0x430, 0, 0x081b, CPU_SUPPORTS_DYNAREC, 8,8,6,6},
|
||||
{"Cx486DX2/66", CPU_Cx486DX, 6, 66666666, 2, 33333333, 0x430, 0, 0x0b1b, CPU_SUPPORTS_DYNAREC, 12,12,6,6},
|
||||
{"Cx486DX2/80", CPU_Cx486DX, 8, 80000000, 2, 20000000, 0x430, 0, 0x311b, CPU_SUPPORTS_DYNAREC, 14,14,16,16},
|
||||
{"Cx486DX4/75", CPU_Cx486DX, 7, 75000000, 3, 25000000, 0x480, 0, 0x361f, CPU_SUPPORTS_DYNAREC, 12,12,9,9},
|
||||
{"Cx486DX4/100", CPU_Cx486DX, 10, 100000000, 3, 33333333, 0x480, 0, 0x361f, CPU_SUPPORTS_DYNAREC, 15,15,9,9},
|
||||
{"Cx5x86/100", CPU_Cx5x86, 10, 100000000, 3, 33333333, 0x480, 0, 0x002f, CPU_SUPPORTS_DYNAREC, 15,15,9,9},
|
||||
{"Cx5x86/120", CPU_Cx5x86, 11, 120000000, 3, 20000000, 0x480, 0, 0x002f, CPU_SUPPORTS_DYNAREC, 21,21,9,9},
|
||||
{"Cx5x86/133", CPU_Cx5x86, 12, 133333333, 4, 33333333, 0x480, 0, 0x002f, CPU_SUPPORTS_DYNAREC, 24,24,12,12},
|
||||
{"", -1, 0, 0, 0}
|
||||
};
|
||||
|
||||
CPU cpus_6x86[] =
|
||||
{
|
||||
/*Cyrix 6x86*/
|
||||
{"6x86-P90", CPU_Cx6x86, 17, 80000000, 3, 40000000, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC},
|
||||
{"6x86-PR120+", CPU_Cx6x86, 17, 100000000, 3, 25000000, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC},
|
||||
{"6x86-PR133+", CPU_Cx6x86, 17, 110000000, 3, 27500000, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC},
|
||||
{"6x86-PR150+", CPU_Cx6x86, 17, 120000000, 3, 30000000, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC},
|
||||
{"6x86-PR166+", CPU_Cx6x86, 17, 133333333, 3, 33333333, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC},
|
||||
{"6x86-PR200+", CPU_Cx6x86, 17, 150000000, 3, 37500000, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC},
|
||||
{"6x86-P90", CPU_Cx6x86, 17, 80000000, 3, 40000000, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 8,8,6,6},
|
||||
{"6x86-PR120+", CPU_Cx6x86, 17, 100000000, 3, 25000000, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 10,10,6,6},
|
||||
{"6x86-PR133+", CPU_Cx6x86, 17, 110000000, 3, 27500000, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 10,10,6,6},
|
||||
{"6x86-PR150+", CPU_Cx6x86, 17, 120000000, 3, 30000000, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6},
|
||||
{"6x86-PR166+", CPU_Cx6x86, 17, 133333333, 3, 33333333, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6},
|
||||
{"6x86-PR200+", CPU_Cx6x86, 17, 150000000, 3, 37500000, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6},
|
||||
|
||||
/*Cyrix 6x86L*/
|
||||
{"6x86L-PR133+", CPU_Cx6x86L, 19, 110000000, 3, 27500000, 0x540, 0x540, 0x2231, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC},
|
||||
{"6x86L-PR150+", CPU_Cx6x86L, 19, 120000000, 3, 30000000, 0x540, 0x540, 0x2231, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC},
|
||||
{"6x86L-PR166+", CPU_Cx6x86L, 19, 133333333, 3, 33333333, 0x540, 0x540, 0x2231, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC},
|
||||
{"6x86L-PR200+", CPU_Cx6x86L, 19, 150000000, 3, 37500000, 0x540, 0x540, 0x2231, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC},
|
||||
{"6x86L-PR133+", CPU_Cx6x86L, 19, 110000000, 3, 27500000, 0x540, 0x540, 0x2231, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 10,10,6,6},
|
||||
{"6x86L-PR150+", CPU_Cx6x86L, 19, 120000000, 3, 30000000, 0x540, 0x540, 0x2231, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6},
|
||||
{"6x86L-PR166+", CPU_Cx6x86L, 19, 133333333, 3, 33333333, 0x540, 0x540, 0x2231, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6},
|
||||
{"6x86L-PR200+", CPU_Cx6x86L, 19, 150000000, 3, 37500000, 0x540, 0x540, 0x2231, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6},
|
||||
|
||||
/*Cyrix 6x86MX*/
|
||||
{"6x86MX-PR90/75",CPU_Cx6x86MX, 18, 75000000, 2, 25000000, 0x600, 0x600, 0x0451, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC},
|
||||
{"6x86MX-PR90", CPU_Cx6x86MX, 18, 90000000, 2, 30000000, 0x600, 0x600, 0x0451, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC},
|
||||
{"6x86MX-PR133", CPU_Cx6x86MX, 18, 100000000, 2, 33333333, 0x600, 0x600, 0x0451, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC},
|
||||
{"6x86MX-PR150", CPU_Cx6x86MX, 18, 120000000, 3, 30000000, 0x600, 0x600, 0x0451, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC},
|
||||
{"6x86MX-PR166", CPU_Cx6x86MX, 18, 133333333, 3, 33333333, 0x600, 0x600, 0x0451, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC},
|
||||
{"6x86MX-PR200", CPU_Cx6x86MX, 18, 166666666, 3, 33333333, 0x600, 0x600, 0x0452, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC},
|
||||
{"6x86MX-PR233", CPU_Cx6x86MX, 18, 188888888, 3, 37500000, 0x600, 0x600, 0x0452, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC},
|
||||
{"6x86MX-PR266", CPU_Cx6x86MX, 18, 207500000, 3, 41666667, 0x600, 0x600, 0x0452, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC},
|
||||
{"6x86MX-PR300", CPU_Cx6x86MX, 18, 233333333, 3, 33333333, 0x600, 0x600, 0x0454, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC},
|
||||
{"6x86MX-PR333", CPU_Cx6x86MX, 18, 250000000, 3, 41666667, 0x600, 0x600, 0x0453, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC},
|
||||
{"6x86MX-PR366", CPU_Cx6x86MX, 18, 250000000, 3, 33333333, 0x600, 0x600, 0x0452, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC},
|
||||
{"6x86MX-PR400", CPU_Cx6x86MX, 18, 285000000, 3, 31666667, 0x600, 0x600, 0x0453, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC},
|
||||
{"6x86MX-PR166", CPU_Cx6x86MX, 18, 133333333, 3, 33333333, 0x600, 0x600, 0x0451, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6},
|
||||
{"6x86MX-PR200", CPU_Cx6x86MX, 18, 166666666, 3, 33333333, 0x600, 0x600, 0x0452, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7},
|
||||
{"6x86MX-PR233", CPU_Cx6x86MX, 18, 188888888, 3, 37500000, 0x600, 0x600, 0x0452, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7},
|
||||
{"6x86MX-PR266", CPU_Cx6x86MX, 18, 207500000, 3, 41666667, 0x600, 0x600, 0x0452, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 17,17,7,7},
|
||||
{"6x86MX-PR300", CPU_Cx6x86MX, 18, 233333333, 3, 33333333, 0x600, 0x600, 0x0454, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 21,21,7,7},
|
||||
{"6x86MX-PR333", CPU_Cx6x86MX, 18, 250000000, 3, 41666667, 0x600, 0x600, 0x0453, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 20,20,9,9},
|
||||
{"6x86MX-PR366", CPU_Cx6x86MX, 18, 250000000, 3, 33333333, 0x600, 0x600, 0x0452, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 24,24,12,12},
|
||||
{"6x86MX-PR400", CPU_Cx6x86MX, 18, 285000000, 3, 31666667, 0x600, 0x600, 0x0453, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18,9,9},
|
||||
{"", -1, 0, 0, 0}
|
||||
};
|
||||
|
||||
@@ -379,191 +417,164 @@ CPU cpus_Cx486[] =
|
||||
CPU cpus_WinChip[] =
|
||||
{
|
||||
/*IDT WinChip*/
|
||||
{"WinChip 75", CPU_WINCHIP, 7, 75000000, 2, 25000000, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC},
|
||||
{"WinChip 90", CPU_WINCHIP, 9, 90000000, 2, 30000000, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC},
|
||||
{"WinChip 100", CPU_WINCHIP, 10, 100000000, 2, 33333333, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC},
|
||||
{"WinChip 120", CPU_WINCHIP, 11, 120000000, 2, 30000000, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC},
|
||||
{"WinChip 133", CPU_WINCHIP, 12, 133333333, 2, 33333333, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC},
|
||||
{"WinChip 150", CPU_WINCHIP, 13, 150000000, 3, 30000000, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC},
|
||||
{"WinChip 166", CPU_WINCHIP, 15, 166666666, 3, 33333333, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC},
|
||||
{"WinChip 180", CPU_WINCHIP, 16, 180000000, 3, 30000000, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC},
|
||||
{"WinChip 200", CPU_WINCHIP, 17, 200000000, 3, 33333333, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC},
|
||||
{"WinChip 225", CPU_WINCHIP, 17, 225000000, 3, 37500000, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC},
|
||||
{"WinChip 240", CPU_WINCHIP, 17, 240000000, 6, 30000000, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC},
|
||||
{"WinChip 75", CPU_WINCHIP, 7, 75000000, 2, 25000000, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 8,8,4,4},
|
||||
{"WinChip 90", CPU_WINCHIP, 9, 90000000, 2, 30000000, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 9,9,4,4},
|
||||
{"WinChip 100", CPU_WINCHIP, 10, 100000000, 2, 33333333, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 9,9,4,4},
|
||||
{"WinChip 120", CPU_WINCHIP, 11, 120000000, 2, 30000000, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 12,12,6,6},
|
||||
{"WinChip 133", CPU_WINCHIP, 12, 133333333, 2, 33333333, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 12,12,6,6},
|
||||
{"WinChip 150", CPU_WINCHIP, 13, 150000000, 3, 30000000, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 15,15,7,7},
|
||||
{"WinChip 166", CPU_WINCHIP, 15, 166666666, 3, 33333333, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 15,15,7,7},
|
||||
{"WinChip 180", CPU_WINCHIP, 16, 180000000, 3, 30000000, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 18,18,9,9},
|
||||
{"WinChip 200", CPU_WINCHIP, 17, 200000000, 3, 33333333, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 18,18,9,9},
|
||||
{"WinChip 225", CPU_WINCHIP, 17, 225000000, 3, 37500000, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 18,18,9,9},
|
||||
{"WinChip 240", CPU_WINCHIP, 17, 240000000, 6, 30000000, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 24,24,12,12},
|
||||
{"", -1, 0, 0, 0}
|
||||
};
|
||||
|
||||
CPU cpus_Pentium5V[] =
|
||||
{
|
||||
/*Intel Pentium (5V, socket 4)*/
|
||||
{"Pentium 60", CPU_PENTIUM, 6, 60000000, 1, 30000000, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC},
|
||||
{"Pentium 66", CPU_PENTIUM, 6, 66666666, 1, 33333333, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC},
|
||||
{"Pentium OverDrive 120",CPU_PENTIUM, 14, 120000000, 2, 30000000, 0x51A, 0x51A, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC},
|
||||
{"Pentium OverDrive 133",CPU_PENTIUM, 16, 133333333, 2, 33333333, 0x51A, 0x51A, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC},
|
||||
{"Pentium 60", CPU_PENTIUM, 6, 60000000, 1, 30000000, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 6,6,3,3},
|
||||
{"Pentium 66", CPU_PENTIUM, 6, 66666666, 1, 33333333, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 6,6,3,3},
|
||||
{"Pentium OverDrive 120",CPU_PENTIUM, 14, 120000000, 2, 30000000, 0x51A, 0x51A, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6},
|
||||
{"Pentium OverDrive 133",CPU_PENTIUM, 16, 133333333, 2, 33333333, 0x51A, 0x51A, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6},
|
||||
{"", -1, 0, 0, 0}
|
||||
};
|
||||
|
||||
CPU cpus_Pentium5V50[] =
|
||||
{
|
||||
/*Intel Pentium (5V, socket 4, including 50 MHz FSB)*/
|
||||
{"Pentium 50 (Q0399)",CPU_PENTIUM, 5, 50000000, 1, 25000000, 0x513, 0x513, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC},
|
||||
{"Pentium 60", CPU_PENTIUM, 6, 60000000, 1, 30000000, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC},
|
||||
{"Pentium 66", CPU_PENTIUM, 6, 66666666, 1, 33333333, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC},
|
||||
{"Pentium OverDrive 100",CPU_PENTIUM, 13, 100000000, 2, 25000000, 0x51A, 0x51A, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC},
|
||||
{"Pentium OverDrive 120",CPU_PENTIUM, 14, 120000000, 2, 30000000, 0x51A, 0x51A, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC},
|
||||
{"Pentium OverDrive 133",CPU_PENTIUM, 16, 133333333, 2, 33333333, 0x51A, 0x51A, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC},
|
||||
{"Pentium 50 (Q0399)",CPU_PENTIUM, 5, 50000000, 1, 25000000, 0x513, 0x513, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 4,4,3,3},
|
||||
{"Pentium 60", CPU_PENTIUM, 6, 60000000, 1, 30000000, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 6,6,3,3},
|
||||
{"Pentium 66", CPU_PENTIUM, 6, 66666666, 1, 33333333, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 6,6,3,3},
|
||||
{"Pentium OverDrive 100",CPU_PENTIUM, 13, 100000000, 2, 25000000, 0x51A, 0x51A, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 8,8,6,6},
|
||||
{"Pentium OverDrive 120",CPU_PENTIUM, 14, 120000000, 2, 30000000, 0x51A, 0x51A, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6},
|
||||
{"Pentium OverDrive 133",CPU_PENTIUM, 16, 133333333, 2, 33333333, 0x51A, 0x51A, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6},
|
||||
{"", -1, 0, 0, 0}
|
||||
};
|
||||
|
||||
CPU cpus_PentiumS5[] =
|
||||
{
|
||||
/*Intel Pentium (Socket 5)*/
|
||||
{"Pentium 75", CPU_PENTIUM, 9, 75000000, 2, 25000000, 0x524, 0x524, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC},
|
||||
{"Pentium OverDrive MMX 75",CPU_PENTIUMMMX,9,75000000,2,25000000,0x1542,0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC},
|
||||
{"Pentium 90", CPU_PENTIUM, 12, 90000000, 2, 30000000, 0x524, 0x524, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_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},
|
||||
{"Pentium OverDrive 125",CPU_PENTIUM,15, 125000000, 3, 25000000, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC},
|
||||
{"Pentium OverDrive 150",CPU_PENTIUM,17, 150000000, 3, 30000000, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC},
|
||||
{"Pentium OverDrive 166",CPU_PENTIUM,17, 166666666, 3, 33333333, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC},
|
||||
{"Pentium OverDrive MMX 125", CPU_PENTIUMMMX,15,125000000, 3, 25000000, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC},
|
||||
{"Pentium OverDrive MMX 150/60", CPU_PENTIUMMMX,17,150000000, 3, 30000000, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC},
|
||||
{"Pentium OverDrive MMX 166", CPU_PENTIUMMMX,19,166000000, 3, 33333333, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC},
|
||||
{"Pentium OverDrive MMX 180", CPU_PENTIUMMMX,20,180000000, 3, 30000000, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC},
|
||||
{"Pentium OverDrive MMX 200", CPU_PENTIUMMMX,21,200000000, 3, 33333333, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC},
|
||||
{"Pentium 75", CPU_PENTIUM, 9, 75000000, 2, 25000000, 0x524, 0x524, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 7,7,4,4},
|
||||
{"Pentium OverDrive MMX 75",CPU_PENTIUMMMX,9,75000000,2,25000000,0x1542,0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 7,7,4,4},
|
||||
{"Pentium 90", CPU_PENTIUM, 12, 90000000, 2, 30000000, 0x524, 0x524, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9,9,4,4},
|
||||
{"Pentium 100/50", CPU_PENTIUM, 13, 100000000, 2, 25000000, 0x525, 0x525, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 10,10,6,6},
|
||||
{"Pentium 100/66", CPU_PENTIUM, 13, 100000000, 2, 33333333, 0x525, 0x525, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9,9,4,4},
|
||||
{"Pentium 120", CPU_PENTIUM, 14, 120000000, 2, 30000000, 0x526, 0x526, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6},
|
||||
{"Pentium OverDrive 125",CPU_PENTIUM,15, 125000000, 3, 25000000, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,7,7},
|
||||
{"Pentium OverDrive 150",CPU_PENTIUM,17, 150000000, 3, 30000000, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7},
|
||||
{"Pentium OverDrive 166",CPU_PENTIUM,17, 166666666, 3, 33333333, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7},
|
||||
{"Pentium OverDrive MMX 125", CPU_PENTIUMMMX,15,125000000, 3, 25000000, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,7,7},
|
||||
{"Pentium OverDrive MMX 150/60", CPU_PENTIUMMMX,17,150000000, 3, 30000000, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7},
|
||||
{"Pentium OverDrive MMX 166", CPU_PENTIUMMMX,19,166000000, 3, 33333333, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7},
|
||||
{"Pentium OverDrive MMX 180", CPU_PENTIUMMMX,20,180000000, 3, 30000000, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18,9,9},
|
||||
{"Pentium OverDrive MMX 200", CPU_PENTIUMMMX,21,200000000, 3, 33333333, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18,9,9},
|
||||
{"", -1, 0, 0, 0}
|
||||
};
|
||||
|
||||
CPU cpus_Pentium[] =
|
||||
{
|
||||
/*Intel Pentium*/
|
||||
{"Pentium 75", CPU_PENTIUM, 9, 75000000, 2, 25000000, 0x524, 0x524, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC},
|
||||
{"Pentium OverDrive MMX 75",CPU_PENTIUMMMX,9,75000000,2,25000000,0x1542,0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC},
|
||||
{"Pentium 90", CPU_PENTIUM, 12, 90000000, 2, 30000000, 0x524, 0x524, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_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},
|
||||
{"Pentium 133", CPU_PENTIUM, 16, 133333333, 2, 33333333, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC},
|
||||
{"Pentium 150", CPU_PENTIUM, 17, 150000000, 3, 30000000, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC},
|
||||
{"Pentium 166", CPU_PENTIUM, 19, 166666666, 3, 33333333, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC},
|
||||
{"Pentium 200", CPU_PENTIUM, 21, 200000000, 3, 33333333, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC},
|
||||
{"Pentium MMX 166", CPU_PENTIUMMMX, 19, 166666666, 3, 33333333, 0x543, 0x543, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC},
|
||||
{"Pentium MMX 200", CPU_PENTIUMMMX, 21, 200000000, 3, 33333333, 0x543, 0x543, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC},
|
||||
{"Pentium MMX 233", CPU_PENTIUMMMX, 24, 233333333, 4, 33333333, 0x543, 0x543, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC},
|
||||
{"Mobile Pentium MMX 120", CPU_PENTIUMMMX, 14, 120000000, 2, 30000000, 0x543, 0x543, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC},
|
||||
{"Mobile Pentium MMX 133", CPU_PENTIUMMMX, 16, 133333333, 2, 33333333, 0x543, 0x543, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC},
|
||||
{"Mobile Pentium MMX 150", CPU_PENTIUMMMX, 17, 150000000, 3, 30000000, 0x544, 0x544, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC},
|
||||
{"Mobile Pentium MMX 166", CPU_PENTIUMMMX, 19, 166666666, 3, 33333333, 0x544, 0x544, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC},
|
||||
{"Mobile Pentium MMX 200", CPU_PENTIUMMMX, 21, 200000000, 3, 33333333, 0x581, 0x581, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC},
|
||||
{"Mobile Pentium MMX 233", CPU_PENTIUMMMX, 24, 233333333, 4, 33333333, 0x581, 0x581, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC},
|
||||
{"Mobile Pentium MMX 266", CPU_PENTIUMMMX, 26, 266666666, 4, 33333333, 0x582, 0x582, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC},
|
||||
{"Mobile Pentium MMX 300", CPU_PENTIUMMMX, 28, 300000000, 5, 33333333, 0x582, 0x582, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC},
|
||||
{"Pentium OverDrive 125",CPU_PENTIUM,15, 125000000, 3, 25000000, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC},
|
||||
{"Pentium OverDrive 150",CPU_PENTIUM,17, 150000000, 3, 30000000, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC},
|
||||
{"Pentium OverDrive 166",CPU_PENTIUM,17, 166666666, 3, 33333333, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC},
|
||||
{"Pentium OverDrive MMX 125", CPU_PENTIUMMMX,15,125000000, 3, 25000000, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC},
|
||||
{"Pentium OverDrive MMX 150/60", CPU_PENTIUMMMX,17,150000000, 3, 30000000, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC},
|
||||
{"Pentium OverDrive MMX 166", CPU_PENTIUMMMX,19,166000000, 3, 33333333, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC},
|
||||
{"Pentium OverDrive MMX 180", CPU_PENTIUMMMX,20,180000000, 3, 30000000, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC},
|
||||
{"Pentium OverDrive MMX 200", CPU_PENTIUMMMX,21,200000000, 3, 33333333, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC},
|
||||
{"Pentium 75", CPU_PENTIUM, 9, 75000000, 2, 25000000, 0x524, 0x524, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 7,7,4,4},
|
||||
{"Pentium OverDrive MMX 75",CPU_PENTIUMMMX,9,75000000,2,25000000,0x1542,0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 7,7,4,4},
|
||||
{"Pentium 90", CPU_PENTIUM, 12, 90000000, 2, 30000000, 0x524, 0x524, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9,9,4,4},
|
||||
{"Pentium 100/50", CPU_PENTIUM, 13, 100000000, 2, 25000000, 0x525, 0x525, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 10,10,6,6},
|
||||
{"Pentium 100/66", CPU_PENTIUM, 13, 100000000, 2, 33333333, 0x525, 0x525, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9,9,4,4},
|
||||
{"Pentium 120", CPU_PENTIUM, 14, 120000000, 2, 30000000, 0x526, 0x526, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6},
|
||||
{"Pentium 133", CPU_PENTIUM, 16, 133333333, 2, 33333333, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6},
|
||||
{"Pentium 150", CPU_PENTIUM, 17, 150000000, 3, 30000000, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7},
|
||||
{"Pentium 166", CPU_PENTIUM, 19, 166666666, 3, 33333333, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7},
|
||||
{"Pentium 200", CPU_PENTIUM, 21, 200000000, 3, 33333333, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18,9,9},
|
||||
{"Pentium MMX 166", CPU_PENTIUMMMX, 19, 166666666, 3, 33333333, 0x543, 0x543, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7},
|
||||
{"Pentium MMX 200", CPU_PENTIUMMMX, 21, 200000000, 3, 33333333, 0x543, 0x543, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18,9,9},
|
||||
{"Pentium MMX 233", CPU_PENTIUMMMX, 24, 233333333, 4, 33333333, 0x543, 0x543, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 21,21,10,10},
|
||||
{"Mobile Pentium MMX 120", CPU_PENTIUMMMX, 14, 120000000, 2, 30000000, 0x543, 0x543, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6},
|
||||
{"Mobile Pentium MMX 133", CPU_PENTIUMMMX, 16, 133333333, 2, 33333333, 0x543, 0x543, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6},
|
||||
{"Mobile Pentium MMX 150", CPU_PENTIUMMMX, 17, 150000000, 3, 30000000, 0x544, 0x544, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7},
|
||||
{"Mobile Pentium MMX 166", CPU_PENTIUMMMX, 19, 166666666, 3, 33333333, 0x544, 0x544, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7},
|
||||
{"Mobile Pentium MMX 200", CPU_PENTIUMMMX, 21, 200000000, 3, 33333333, 0x581, 0x581, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18,9,9},
|
||||
{"Mobile Pentium MMX 233", CPU_PENTIUMMMX, 24, 233333333, 4, 33333333, 0x581, 0x581, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 21,21,10,10},
|
||||
{"Mobile Pentium MMX 266", CPU_PENTIUMMMX, 26, 266666666, 4, 33333333, 0x582, 0x582, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 24,24,12,12},
|
||||
{"Mobile Pentium MMX 300", CPU_PENTIUMMMX, 28, 300000000, 5, 33333333, 0x582, 0x582, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27,27,13,13},
|
||||
{"Pentium OverDrive 125",CPU_PENTIUM,15, 125000000, 3, 25000000, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,7,7},
|
||||
{"Pentium OverDrive 150",CPU_PENTIUM,17, 150000000, 3, 30000000, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7},
|
||||
{"Pentium OverDrive 166",CPU_PENTIUM,17, 166666666, 3, 33333333, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7},
|
||||
{"Pentium OverDrive MMX 125", CPU_PENTIUMMMX,15,125000000, 3, 25000000, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,7,7},
|
||||
{"Pentium OverDrive MMX 150/60", CPU_PENTIUMMMX,17,150000000, 3, 30000000, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7},
|
||||
{"Pentium OverDrive MMX 166", CPU_PENTIUMMMX,19,166000000, 3, 33333333, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7},
|
||||
{"Pentium OverDrive MMX 180", CPU_PENTIUMMMX,20,180000000, 3, 30000000, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18,9,9},
|
||||
{"Pentium OverDrive MMX 200", CPU_PENTIUMMMX,21,200000000, 3, 33333333, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18,9,9},
|
||||
{"", -1, 0, 0, 0}
|
||||
};
|
||||
|
||||
CPU cpus_K5[] =
|
||||
{
|
||||
/*AMD K5 (Socket 5)*/
|
||||
{"K5 (5k86) 75 (P75)", CPU_K5, 9, 75000000, 2, 25000000, 0x500, 0x500, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC},
|
||||
{"K5 (SSA/5) 75 (PR75)", CPU_K5, 9, 75000000, 2, 25000000, 0x501, 0x501, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC},
|
||||
{"K5 (5k86) 90 (P90)", CPU_K5, 12, 90000000, 2, 30000000, 0x500, 0x500, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC},
|
||||
{"K5 (SSA/5) 90 (PR90)", CPU_K5, 12, 90000000, 2, 30000000, 0x501, 0x501, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC},
|
||||
{"K5 (5k86) 100 (P100)", CPU_K5, 13, 100000000, 2, 33333333, 0x500, 0x500, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC},
|
||||
{"K5 (SSA/5) 100 (PR100)",CPU_K5, 13, 100000000, 2, 33333333, 0x501, 0x501, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC},
|
||||
{"K5 (5k86) 90 (PR120)", CPU_5K86, 14, 120000000, 2, 30000000, 0x511, 0x511, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC},
|
||||
{"K5 (5k86) 100 (PR133)", CPU_5K86, 16, 133333333, 2, 33333333, 0x514, 0x514, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC},
|
||||
{"K5 (5k86) 105 (PR150)", CPU_5K86, 17, 150000000, 3, 30000000, 0x524, 0x524, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC},
|
||||
{"K5 (5k86) 116.5 (PR166)",CPU_5K86, 19, 166666666,3, 33333333, 0x524, 0x524, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC},
|
||||
{"K5 (5k86) 133 (PR200)", CPU_5K86, 21, 200000000, 3, 33333333, 0x534, 0x534, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC},
|
||||
{"K5 (5k86) 75 (P75)", CPU_K5, 9, 75000000, 2, 25000000, 0x500, 0x500, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 7,7,4,4},
|
||||
{"K5 (SSA/5) 75 (PR75)", CPU_K5, 9, 75000000, 2, 25000000, 0x501, 0x501, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 7,7,4,4},
|
||||
{"K5 (5k86) 90 (P90)", CPU_K5, 12, 90000000, 2, 30000000, 0x500, 0x500, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9,9,4,4},
|
||||
{"K5 (SSA/5) 90 (PR90)", CPU_K5, 12, 90000000, 2, 30000000, 0x501, 0x501, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9,9,4,4},
|
||||
{"K5 (5k86) 100 (P100)", CPU_K5, 13, 100000000, 2, 33333333, 0x500, 0x500, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9,9,4,4},
|
||||
{"K5 (SSA/5) 100 (PR100)",CPU_K5, 13, 100000000, 2, 33333333, 0x501, 0x501, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9,9,4,4},
|
||||
{"K5 (5k86) 90 (PR120)", CPU_5K86, 14, 120000000, 2, 30000000, 0x511, 0x511, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6},
|
||||
{"K5 (5k86) 100 (PR133)", CPU_5K86, 16, 133333333, 2, 33333333, 0x514, 0x514, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6},
|
||||
{"K5 (5k86) 105 (PR150)", CPU_5K86, 17, 150000000, 3, 30000000, 0x524, 0x524, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7},
|
||||
{"K5 (5k86) 116.5 (PR166)",CPU_5K86, 19, 166666666,3, 33333333, 0x524, 0x524, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7},
|
||||
{"K5 (5k86) 133 (PR200)", CPU_5K86, 21, 200000000, 3, 33333333, 0x534, 0x534, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18,9,9},
|
||||
{"", -1, 0, 0, 0}
|
||||
};
|
||||
|
||||
CPU cpus_K56[] =
|
||||
{
|
||||
/*AMD K5 and K6 (Socket 7)*/
|
||||
{"K5 (5k86) 75 (P75)", CPU_K5, 9, 75000000, 2, 25000000, 0x500, 0x500, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC},
|
||||
{"K5 (SSA/5) 75 (PR75)", CPU_K5, 9, 75000000, 2, 25000000, 0x501, 0x501, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC},
|
||||
{"K5 (5k86) 90 (P90)", CPU_K5, 12, 90000000, 2, 30000000, 0x500, 0x500, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC},
|
||||
{"K5 (SSA/5) 90 (PR90)", CPU_K5, 12, 90000000, 2, 30000000, 0x501, 0x501, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC},
|
||||
{"K5 (5k86) 100 (P100)", CPU_K5, 13, 100000000, 2, 33333333, 0x500, 0x500, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC},
|
||||
{"K5 (SSA/5) 100 (PR100)",CPU_K5, 13, 100000000, 2, 33333333, 0x501, 0x501, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC},
|
||||
{"K5 (5k86) 90 (PR120)", CPU_5K86, 14, 120000000, 2, 30000000, 0x511, 0x511, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC},
|
||||
{"K5 (5k86) 100 (PR133)", CPU_5K86, 16, 133333333, 2, 33333333, 0x514, 0x514, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC},
|
||||
{"K5 (5k86) 105 (PR150)", CPU_5K86, 17, 150000000, 3, 30000000, 0x524, 0x524, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC},
|
||||
{"K5 (5k86) 116.5 (PR166)",CPU_5K86, 19, 166666666,3, 33333333, 0x524, 0x524, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC},
|
||||
{"K5 (5k86) 133 (PR200)", CPU_5K86, 21, 200000000, 3, 33333333, 0x534, 0x534, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC},
|
||||
{"K6 (Model 6) 166", CPU_K6, 19, 166666666, 3, 33333333, 0x562, 0x562, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC},
|
||||
{"K6 (Model 6) 200", CPU_K6, 21, 200000000, 3, 33333333, 0x562, 0x562, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC},
|
||||
{"K6 (Model 6) 233", CPU_K6, 24, 233333333, 4, 33333333, 0x562, 0x562, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC},
|
||||
{"K6 (Model 7) 200", CPU_K6, 21, 200000000, 3, 33333333, 0x570, 0x570, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC},
|
||||
{"K6 (Model 7) 233", CPU_K6, 24, 233333333, 4, 33333333, 0x570, 0x570, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC},
|
||||
{"K6 (Model 7) 266", CPU_K6, 26, 266666666, 4, 33333333, 0x570, 0x570, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC},
|
||||
{"K6 (Model 7) 300", CPU_K6, 28, 300000000, 5, 33333333, 0x570, 0x570, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC},
|
||||
{"K5 (5k86) 75 (P75)", CPU_K5, 9, 75000000, 2, 25000000, 0x500, 0x500, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 7,7,4,4},
|
||||
{"K5 (SSA/5) 75 (PR75)", CPU_K5, 9, 75000000, 2, 25000000, 0x501, 0x501, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 7,7,4,4},
|
||||
{"K5 (5k86) 90 (P90)", CPU_K5, 12, 90000000, 2, 30000000, 0x500, 0x500, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9,9,4,4},
|
||||
{"K5 (SSA/5) 90 (PR90)", CPU_K5, 12, 90000000, 2, 30000000, 0x501, 0x501, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9,9,4,4},
|
||||
{"K5 (5k86) 100 (P100)", CPU_K5, 13, 100000000, 2, 33333333, 0x500, 0x500, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9,9,4,4},
|
||||
{"K5 (SSA/5) 100 (PR100)",CPU_K5, 13, 100000000, 2, 33333333, 0x501, 0x501, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9,9,4,4},
|
||||
{"K5 (5k86) 90 (PR120)", CPU_5K86, 14, 120000000, 2, 30000000, 0x511, 0x511, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6},
|
||||
{"K5 (5k86) 100 (PR133)", CPU_5K86, 16, 133333333, 2, 33333333, 0x514, 0x514, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6},
|
||||
{"K5 (5k86) 105 (PR150)", CPU_5K86, 17, 150000000, 3, 30000000, 0x524, 0x524, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7},
|
||||
{"K5 (5k86) 116.5 (PR166)",CPU_5K86, 19, 166666666,3, 33333333, 0x524, 0x524, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7},
|
||||
{"K5 (5k86) 133 (PR200)", CPU_5K86, 21, 200000000, 3, 33333333, 0x534, 0x534, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18,9,9},
|
||||
{"K6 (Model 6) 166", CPU_K6, 19, 166666666, 3, 33333333, 0x562, 0x562, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7},
|
||||
{"K6 (Model 6) 200", CPU_K6, 21, 200000000, 3, 33333333, 0x562, 0x562, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18,9,9},
|
||||
{"K6 (Model 6) 233", CPU_K6, 24, 233333333, 4, 33333333, 0x562, 0x562, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 21,21,10,10},
|
||||
{"K6 (Model 7) 200", CPU_K6, 21, 200000000, 3, 33333333, 0x570, 0x570, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18,9,9},
|
||||
{"K6 (Model 7) 233", CPU_K6, 24, 233333333, 4, 33333333, 0x570, 0x570, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 21,21,10,10},
|
||||
{"K6 (Model 7) 266", CPU_K6, 26, 266666666, 4, 33333333, 0x570, 0x570, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 24,24,12,12},
|
||||
{"K6 (Model 7) 300", CPU_K6, 28, 300000000, 5, 33333333, 0x570, 0x570, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27,27,13,13},
|
||||
{"", -1, 0, 0, 0}
|
||||
};
|
||||
|
||||
CPU cpus_PentiumPro[] =
|
||||
{
|
||||
/*Intel Pentium Pro and II Overdrive*/
|
||||
{"Pentium Pro 50", CPU_PENTIUMPRO, 5, 50000000, 1, 25000000, 0x612, 0x612, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC},
|
||||
{"Pentium Pro 60" , CPU_PENTIUMPRO, 6, 60000000, 1, 30000000, 0x612, 0x612, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC},
|
||||
{"Pentium Pro 66" , CPU_PENTIUMPRO, 6, 66666666, 1, 33333333, 0x612, 0x612, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC},
|
||||
{"Pentium Pro 75", CPU_PENTIUMPRO, 9, 75000000, 2, 25000000, 0x612, 0x612, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC},
|
||||
{"Pentium Pro 150", CPU_PENTIUMPRO, 17, 150000000, 3, 30000000, 0x612, 0x612, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC},
|
||||
{"Pentium Pro 166", CPU_PENTIUMPRO, 19, 166666666, 3, 33333333, 0x617, 0x617, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC},
|
||||
{"Pentium Pro 180", CPU_PENTIUMPRO, 20, 180000000, 3, 30000000, 0x617, 0x617, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC},
|
||||
{"Pentium Pro 200", CPU_PENTIUMPRO, 21, 200000000, 3, 33333333, 0x617, 0x617, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC},
|
||||
{"Pentium II Overdrive 50", CPU_PENTIUM2D, 5, 50000000, 1, 25000000, 0x1632, 0x1632, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC},
|
||||
{"Pentium II Overdrive 60", CPU_PENTIUM2D, 6, 60000000, 1, 30000000, 0x1632, 0x1632, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC},
|
||||
{"Pentium II Overdrive 66", CPU_PENTIUM2D, 6, 66666666, 1, 33333333, 0x1632, 0x1632, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC},
|
||||
{"Pentium II Overdrive 75", CPU_PENTIUM2D, 9, 75000000, 2, 25000000, 0x1632, 0x1632, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC},
|
||||
{"Pentium II Overdrive 210", CPU_PENTIUM2D, 22, 210000000, 4, 30000000, 0x1632, 0x1632, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC},
|
||||
{"Pentium II Overdrive 233", CPU_PENTIUM2D, 24, 233333333, 4, 33333333, 0x1632, 0x1632, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC},
|
||||
{"Pentium II Overdrive 240", CPU_PENTIUM2D, 25, 240000000, 4, 30000000, 0x1632, 0x1632, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC},
|
||||
{"Pentium II Overdrive 266", CPU_PENTIUM2D, 26, 266666666, 4, 33333333, 0x1632, 0x1632, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC},
|
||||
{"Pentium II Overdrive 270", CPU_PENTIUM2D, 27, 270000000, 5, 30000000, 0x1632, 0x1632, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC},
|
||||
{"Pentium II Overdrive 300/66",CPU_PENTIUM2D, 28, 300000000, 5, 33333333, 0x1632, 0x1632, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC},
|
||||
{"Pentium II Overdrive 300/60",CPU_PENTIUM2D, 28, 300000000, 5, 30000000, 0x1632, 0x1632, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC},
|
||||
{"Pentium II Overdrive 333", CPU_PENTIUM2D, 29, 333333333, 5, 33333333, 0x1632, 0x1632, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC},
|
||||
{"Pentium Pro 50", CPU_PENTIUMPRO, 5, 50000000, 1, 25000000, 0x612, 0x612, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 4,4,3,3},
|
||||
{"Pentium Pro 60" , CPU_PENTIUMPRO, 6, 60000000, 1, 30000000, 0x612, 0x612, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 6,6,3,3},
|
||||
{"Pentium Pro 66" , CPU_PENTIUMPRO, 6, 66666666, 1, 33333333, 0x612, 0x612, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 6,6,3,3},
|
||||
{"Pentium Pro 75", CPU_PENTIUMPRO, 9, 75000000, 2, 25000000, 0x612, 0x612, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 7,7,4,4},
|
||||
{"Pentium Pro 150", CPU_PENTIUMPRO, 17, 150000000, 3, 30000000, 0x612, 0x612, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7},
|
||||
{"Pentium Pro 166", CPU_PENTIUMPRO, 19, 166666666, 3, 33333333, 0x617, 0x617, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7},
|
||||
{"Pentium Pro 180", CPU_PENTIUMPRO, 20, 180000000, 3, 30000000, 0x617, 0x617, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18,9,9},
|
||||
{"Pentium Pro 200", CPU_PENTIUMPRO, 21, 200000000, 3, 33333333, 0x617, 0x617, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18,9,9},
|
||||
{"Pentium II Overdrive 50", CPU_PENTIUM2D, 5, 50000000, 1, 25000000, 0x1632, 0x1632, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 4,4,3,3},
|
||||
{"Pentium II Overdrive 60", CPU_PENTIUM2D, 6, 60000000, 1, 30000000, 0x1632, 0x1632, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 6,6,3,3},
|
||||
{"Pentium II Overdrive 66", CPU_PENTIUM2D, 6, 66666666, 1, 33333333, 0x1632, 0x1632, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 6,6,3,3},
|
||||
{"Pentium II Overdrive 75", CPU_PENTIUM2D, 9, 75000000, 2, 25000000, 0x1632, 0x1632, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 7,7,4,4},
|
||||
{"Pentium II Overdrive 210", CPU_PENTIUM2D, 22, 210000000, 4, 30000000, 0x1632, 0x1632, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 17,17,7,7},
|
||||
{"Pentium II Overdrive 233", CPU_PENTIUM2D, 24, 233333333, 4, 33333333, 0x1632, 0x1632, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 21,21,10,1},
|
||||
{"Pentium II Overdrive 240", CPU_PENTIUM2D, 25, 240000000, 4, 30000000, 0x1632, 0x1632, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 24,24,12,12},
|
||||
{"Pentium II Overdrive 266", CPU_PENTIUM2D, 26, 266666666, 4, 33333333, 0x1632, 0x1632, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 24,24,12,12},
|
||||
{"Pentium II Overdrive 270", CPU_PENTIUM2D, 27, 270000000, 5, 30000000, 0x1632, 0x1632, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 25,25,12,12},
|
||||
{"Pentium II Overdrive 300/66",CPU_PENTIUM2D, 28, 300000000, 5, 33333333, 0x1632, 0x1632, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 25,25,12,12},
|
||||
{"Pentium II Overdrive 300/60",CPU_PENTIUM2D, 28, 300000000, 5, 30000000, 0x1632, 0x1632, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27,27,13,13},
|
||||
{"Pentium II Overdrive 333", CPU_PENTIUM2D, 29, 333333333, 5, 33333333, 0x1632, 0x1632, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27,27,13,13},
|
||||
{"", -1, 0, 0, 0}
|
||||
};
|
||||
|
||||
#if 0
|
||||
CPU cpus_Pentium2[] =
|
||||
{
|
||||
/*Intel Pentium II Klamath*/
|
||||
{"Pentium II 75", CPU_PENTIUM2, 9, 75000000, 2, 25000000, 0x632, 0x632, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC},
|
||||
{"Pentium II 75 (634)",CPU_PENTIUM2, 9, 75000000, 2, 25000000, 0x634, 0x634, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC},
|
||||
{"Pentium II 233", CPU_PENTIUM2, 24, 233333333, 4, 33333333, 0x632, 0x632, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC},
|
||||
{"Pentium II 266", CPU_PENTIUM2, 26, 266666666, 4, 33333333, 0x633, 0x633, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC},
|
||||
{"Pentium II 300", CPU_PENTIUM2, 28, 300000000, 5, 33333333, 0x634, 0x634, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC},
|
||||
{"", -1, 0, 0, 0}
|
||||
};
|
||||
|
||||
CPU cpus_Pentium2D[] =
|
||||
{
|
||||
/*Intel Pentium II Deschutes*/
|
||||
{"Pentium II D 75", CPU_PENTIUM2D, 9, 75000000, 2, 25000000, 0x654, 0x654, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC},
|
||||
{"Pentium II D 266", CPU_PENTIUM2D, 26, 266666666, 4, 33333333, 0x650, 0x650, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC},
|
||||
{"Pentium II D 300", CPU_PENTIUM2D, 28, 300000000, 5, 33333333, 0x650, 0x650, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC},
|
||||
{"Pentium II D 333", CPU_PENTIUM2D, 29, 333333333, 5, 33333333, 0x650, 0x650, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC},
|
||||
{"Pentium II D 350", CPU_PENTIUM2D, 30, 350000000, 4, 50000000, 0x653, 0x653, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC},
|
||||
{"Pentium II D 400", CPU_PENTIUM2D, 31, 400000000, 4, 50000000, 0x653, 0x653, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC},
|
||||
{"Pentium II D 450", CPU_PENTIUM2D, 32, 450000000, 5, 50000000, 0x654, 0x654, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC},
|
||||
{"Pentium II D 500", CPU_PENTIUM2D, 33, 500000000, 5, 50000000, 0x654, 0x654, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC},
|
||||
{"", -1, 0, 0, 0}
|
||||
};
|
||||
#endif
|
||||
|
||||
void cpu_set_edx()
|
||||
{
|
||||
EDX = models[model].cpu[cpu_manufacturer].cpus[cpu].edx_reset;
|
||||
@@ -589,9 +600,10 @@ void cpu_set()
|
||||
is386 = (cpu_s->cpu_type >= CPU_386SX);
|
||||
israpidcad = (cpu_s->cpu_type == CPU_RAPIDCAD);
|
||||
is486 = (cpu_s->cpu_type >= CPU_i486SX) || (cpu_s->cpu_type == CPU_486SLC || cpu_s->cpu_type == CPU_486DLC || cpu_s->cpu_type == CPU_RAPIDCAD);
|
||||
is_pentium= (cpu_s->cpu_type >= CPU_WINCHIP);
|
||||
hasfpu = (cpu_s->cpu_type >= CPU_i486DX) || (cpu_s->cpu_type == CPU_RAPIDCAD);
|
||||
cpu_iscyrix = (cpu_s->cpu_type == CPU_486SLC || cpu_s->cpu_type == CPU_486DLC || cpu_s->cpu_type == CPU_Cx486S || cpu_s->cpu_type == CPU_Cx486DX || cpu_s->cpu_type == CPU_Cx5x86 || cpu_s->cpu_type == CPU_Cx6x86 || cpu_s->cpu_type == CPU_Cx6x86MX || cpu_s->cpu_type == CPU_Cx6x86L || cpu_s->cpu_type == CPU_CxGX1);
|
||||
cpu_16bitbus = (cpu_s->cpu_type == CPU_386SX || cpu_s->cpu_type == CPU_486SLC);
|
||||
cpu_16bitbus = cpu_16bitbus = (cpu_s->cpu_type == CPU_286 || cpu_s->cpu_type == CPU_386SX || cpu_s->cpu_type == CPU_486SLC);
|
||||
if (cpu_s->multi)
|
||||
cpu_busspeed = cpu_s->rspeed / cpu_s->multi;
|
||||
cpu_multi = cpu_s->multi;
|
||||
@@ -601,6 +613,8 @@ void cpu_set()
|
||||
cpu_hasCR4 = 0;
|
||||
ccr0 = ccr1 = ccr2 = ccr3 = ccr4 = ccr5 = ccr6 = 0;
|
||||
|
||||
cpu_update_waitstates();
|
||||
|
||||
isa_cycles = (int)(((int64_t)cpu_s->rspeed << ISA_CYCLES_SHIFT) / 8000000ll);
|
||||
|
||||
if (cpu_s->pci_speed)
|
||||
@@ -2318,3 +2332,43 @@ void x86_setopcodes(OpFn *opcodes, OpFn *opcodes_0f, OpFn *dynarec_opcodes, OpFn
|
||||
x86_dynarec_opcodes = dynarec_opcodes;
|
||||
x86_dynarec_opcodes_0f = dynarec_opcodes_0f;
|
||||
}
|
||||
|
||||
void cpu_update_waitstates()
|
||||
{
|
||||
cpu_s = &models[model].cpu[cpu_manufacturer].cpus[cpu];
|
||||
|
||||
cpu_prefetch_width = cpu_16bitbus ? 2 : 4;
|
||||
|
||||
if (cpu_cache_int_enabled)
|
||||
{
|
||||
/* Disable prefetch emulation */
|
||||
cpu_prefetch_cycles = 0;
|
||||
}
|
||||
else if (cpu_waitstates && (cpu_s->cpu_type >= CPU_286 && cpu_s->cpu_type <= CPU_386DX))
|
||||
{
|
||||
/* Waitstates override */
|
||||
cpu_prefetch_cycles = cpu_waitstates+1;
|
||||
cpu_cycles_read = cpu_waitstates+1;
|
||||
cpu_cycles_read_l = (cpu_16bitbus ? 2 : 1) * (cpu_waitstates+1);
|
||||
cpu_cycles_write = cpu_waitstates+1;
|
||||
cpu_cycles_write_l = (cpu_16bitbus ? 2 : 1) * (cpu_waitstates+1);
|
||||
}
|
||||
else if (cpu_cache_ext_enabled)
|
||||
{
|
||||
/* Use cache timings */
|
||||
cpu_prefetch_cycles = cpu_s->cache_read_cycles;
|
||||
cpu_cycles_read = cpu_s->cache_read_cycles;
|
||||
cpu_cycles_read_l = (cpu_16bitbus ? 2 : 1) * cpu_s->cache_read_cycles;
|
||||
cpu_cycles_write = cpu_s->cache_write_cycles;
|
||||
cpu_cycles_write_l = (cpu_16bitbus ? 2 : 1) * cpu_s->cache_write_cycles;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Use memory timings */
|
||||
cpu_prefetch_cycles = cpu_s->mem_read_cycles;
|
||||
cpu_cycles_read = cpu_s->mem_read_cycles;
|
||||
cpu_cycles_read_l = (cpu_16bitbus ? 2 : 1) * cpu_s->mem_read_cycles;
|
||||
cpu_cycles_write = cpu_s->mem_write_cycles;
|
||||
cpu_cycles_write_l = (cpu_16bitbus ? 2 : 1) * cpu_s->mem_write_cycles;
|
||||
}
|
||||
}
|
||||
|
||||
12
src/cpu.h
12
src/cpu.h
@@ -78,14 +78,19 @@ typedef struct
|
||||
uint32_t cpuid_model;
|
||||
uint16_t cyrix_id;
|
||||
int cpu_flags;
|
||||
int mem_read_cycles, mem_write_cycles;
|
||||
int cache_read_cycles, cache_write_cycles;
|
||||
} CPU;
|
||||
|
||||
extern CPU cpus_8088[];
|
||||
extern CPU cpus_8086[];
|
||||
extern CPU cpus_286[];
|
||||
extern CPU cpus_i386[];
|
||||
extern CPU cpus_i386DX[];
|
||||
extern CPU cpus_Am386[];
|
||||
extern CPU cpus_Am386DX[];
|
||||
extern CPU cpus_486SDLC[];
|
||||
extern CPU cpus_486DLC[];
|
||||
extern CPU cpus_i486[];
|
||||
extern CPU cpus_Am486[];
|
||||
extern CPU cpus_Cx486[];
|
||||
@@ -129,6 +134,11 @@ extern uint64_t cpu_CR4_mask;
|
||||
#define CPU_REQUIRES_DYNAREC 2
|
||||
// #define CPU_REQUIRES_DYNAREC 0
|
||||
|
||||
extern int cpu_cycles_read, cpu_cycles_read_l, cpu_cycles_write, cpu_cycles_write_l;
|
||||
extern int cpu_prefetch_cycles, cpu_prefetch_width;
|
||||
extern int cpu_waitstates;
|
||||
extern int cpu_cache_int_enabled, cpu_cache_ext_enabled;
|
||||
|
||||
extern uint64_t tsc;
|
||||
|
||||
void cyrix_write(uint16_t addr, uint8_t val, void *priv);
|
||||
@@ -149,4 +159,6 @@ extern int xt_cpu_multi;
|
||||
extern int isa_cycles;
|
||||
#define ISA_CYCLES(x) ((x * isa_cycles) >> ISA_CYCLES_SHIFT)
|
||||
|
||||
void cpu_update_waitstates();
|
||||
|
||||
#endif
|
||||
|
||||
65
src/device.c
65
src/device.c
@@ -1,9 +1,8 @@
|
||||
/* Copyright holders: Sarah Walker
|
||||
see COPYING for more details
|
||||
*/
|
||||
#include "ibm.h"
|
||||
#include "config.h"
|
||||
#include "cpu.h"
|
||||
#include "device.h"
|
||||
#include "model.h"
|
||||
#include "sound.h"
|
||||
|
||||
static void *device_priv[256];
|
||||
@@ -19,9 +18,9 @@ void device_init()
|
||||
void device_add(device_t *d)
|
||||
{
|
||||
int c = 0;
|
||||
void *priv;
|
||||
void *priv = NULL;
|
||||
|
||||
while ((c < 256) && (devices[c] != NULL))
|
||||
while (devices[c] != NULL && c < 256)
|
||||
c++;
|
||||
|
||||
if (c >= 256)
|
||||
@@ -29,9 +28,12 @@ void device_add(device_t *d)
|
||||
|
||||
current_device = d;
|
||||
|
||||
priv = d->init();
|
||||
if (priv == NULL)
|
||||
fatal("device_add : device init failed\n");
|
||||
if (d->init != NULL)
|
||||
{
|
||||
priv = d->init();
|
||||
if (priv == NULL)
|
||||
fatal("device_add : device init failed\n");
|
||||
}
|
||||
|
||||
devices[c] = d;
|
||||
device_priv[c] = priv;
|
||||
@@ -45,7 +47,8 @@ void device_close_all()
|
||||
{
|
||||
if (devices[c] != NULL)
|
||||
{
|
||||
devices[c]->close(device_priv[c]);
|
||||
if (devices[c]->close != NULL)
|
||||
devices[c]->close(device_priv[c]);
|
||||
devices[c] = device_priv[c] = NULL;
|
||||
}
|
||||
}
|
||||
@@ -77,8 +80,8 @@ void device_speed_changed()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sound_speed_changed();
|
||||
|
||||
sound_speed_changed();
|
||||
}
|
||||
|
||||
void device_force_redraw()
|
||||
@@ -138,3 +141,43 @@ char *device_get_config_string(char *s)
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int model_get_config_int(char *s)
|
||||
{
|
||||
device_t *device = model_getdevice(model);
|
||||
device_config_t *config;
|
||||
|
||||
if (!device)
|
||||
return 0;
|
||||
|
||||
config = device->config;
|
||||
|
||||
while (config->type != -1)
|
||||
{
|
||||
if (!strcmp(s, config->name))
|
||||
return config_get_int(device->name, s, config->default_int);
|
||||
|
||||
config++;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
char *model_get_config_string(char *s)
|
||||
{
|
||||
device_t *device = model_getdevice(model);
|
||||
device_config_t *config;
|
||||
|
||||
if (!device)
|
||||
return 0;
|
||||
|
||||
config = device->config;
|
||||
|
||||
while (config->type != -1)
|
||||
{
|
||||
if (!strcmp(s, config->name))
|
||||
return config_get_string(device->name, s, config->default_string);
|
||||
|
||||
config++;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -1,6 +1,3 @@
|
||||
/* Copyright holders: Sarah Walker
|
||||
see COPYING for more details
|
||||
*/
|
||||
#define CONFIG_STRING 0
|
||||
#define CONFIG_INT 1
|
||||
#define CONFIG_BINARY 2
|
||||
@@ -51,3 +48,6 @@ enum
|
||||
{
|
||||
DEVICE_NOT_WORKING = 1 /*Device does not currently work correctly and will be disabled in a release build*/
|
||||
};
|
||||
|
||||
int model_get_config_int(char *s);
|
||||
char *model_get_config_string(char *s);
|
||||
|
||||
67
src/disc.c
67
src/disc.c
@@ -14,20 +14,19 @@
|
||||
#include "fdd.h"
|
||||
#include "timer.h"
|
||||
|
||||
int disc_poll_time[2] = { 16, 16 };
|
||||
int disc_poll_time[FDD_NUM] = { 16, 16, 16, 16 };
|
||||
|
||||
int disc_track[2];
|
||||
int writeprot[2], fwriteprot[2];
|
||||
int disc_track[FDD_NUM];
|
||||
int writeprot[FDD_NUM], fwriteprot[FDD_NUM];
|
||||
|
||||
DRIVE drives[2];
|
||||
int drive_type[2];
|
||||
DRIVE drives[FDD_NUM];
|
||||
int drive_type[FDD_NUM];
|
||||
|
||||
int curdrive = 0;
|
||||
|
||||
int swwp = 0;
|
||||
int disable_write = 0;
|
||||
|
||||
//char discfns[2][260] = {"", ""};
|
||||
int defaultwriteprot = 0;
|
||||
|
||||
int fdc_time;
|
||||
@@ -35,11 +34,11 @@ int disc_time;
|
||||
|
||||
int fdc_ready;
|
||||
|
||||
int drive_empty[2] = {1, 1};
|
||||
int disc_changed[2];
|
||||
int drive_empty[FDD_NUM] = {1, 1, 1, 1};
|
||||
int disc_changed[FDD_NUM];
|
||||
|
||||
int motorspin;
|
||||
int motoron[2];
|
||||
int motoron[FDD_NUM];
|
||||
|
||||
int fdc_indexcount = 52;
|
||||
|
||||
@@ -111,8 +110,8 @@ void disc_load(int drive, char *fn)
|
||||
loaders[c].load(drive, fn);
|
||||
drive_empty[drive] = 0;
|
||||
strcpy(discfns[drive], fn);
|
||||
fdd_set_head(drive ^ fdd_swap, 0);
|
||||
fdd_forced_seek(drive ^ fdd_swap, 0);
|
||||
// fdd_set_head(real_drive(drive), 0);
|
||||
fdd_forced_seek(real_drive(drive), 0);
|
||||
disc_changed[drive] = 1;
|
||||
return;
|
||||
}
|
||||
@@ -120,7 +119,7 @@ void disc_load(int drive, char *fn)
|
||||
}
|
||||
pclog("Couldn't load %s %s\n",fn,p);
|
||||
drive_empty[drive] = 1;
|
||||
fdd_set_head(drive ^ fdd_swap, 0);
|
||||
fdd_set_head(real_drive(drive), 0);
|
||||
discfns[drive][0] = 0;
|
||||
}
|
||||
|
||||
@@ -129,7 +128,7 @@ void disc_close(int drive)
|
||||
// pclog("disc_close %i\n", drive);
|
||||
if (loaders[driveloaders[drive]].close) loaders[driveloaders[drive]].close(drive);
|
||||
drive_empty[drive] = 1;
|
||||
fdd_set_head(drive ^ fdd_swap, 0);
|
||||
fdd_set_head(real_drive(drive), 0);
|
||||
discfns[drive][0] = 0;
|
||||
drives[drive].hole = NULL;
|
||||
drives[drive].poll = NULL;
|
||||
@@ -148,7 +147,7 @@ static int disc_period = 32;
|
||||
|
||||
int disc_hole(int drive)
|
||||
{
|
||||
drive ^= fdd_swap;
|
||||
drive = real_drive(drive);
|
||||
|
||||
if (drives[drive].hole)
|
||||
{
|
||||
@@ -162,7 +161,7 @@ int disc_hole(int drive)
|
||||
|
||||
double disc_byteperiod(int drive)
|
||||
{
|
||||
drive ^= fdd_swap;
|
||||
drive = real_drive(drive);
|
||||
|
||||
if (drives[drive].byteperiod)
|
||||
{
|
||||
@@ -179,7 +178,7 @@ double disc_real_period(int drive)
|
||||
double ddbp;
|
||||
double dusec;
|
||||
|
||||
ddbp = disc_byteperiod(drive ^ fdd_swap);
|
||||
ddbp = disc_byteperiod(real_drive(drive));
|
||||
|
||||
dusec = (double) TIMER_USEC;
|
||||
|
||||
@@ -188,7 +187,7 @@ double disc_real_period(int drive)
|
||||
|
||||
void disc_poll(int drive)
|
||||
{
|
||||
if (drive > 1)
|
||||
if (drive >= FDD_NUM)
|
||||
{
|
||||
disc_poll_time[drive] += (int) (32.0 * TIMER_USEC);
|
||||
return;
|
||||
@@ -203,7 +202,7 @@ void disc_poll(int drive)
|
||||
{
|
||||
disc_notfound--;
|
||||
if (!disc_notfound)
|
||||
fdc_notfound();
|
||||
fdc_noidam();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -217,6 +216,16 @@ void disc_poll_1()
|
||||
disc_poll(1);
|
||||
}
|
||||
|
||||
void disc_poll_2()
|
||||
{
|
||||
disc_poll(2);
|
||||
}
|
||||
|
||||
void disc_poll_3()
|
||||
{
|
||||
disc_poll(3);
|
||||
}
|
||||
|
||||
int disc_get_bitcell_period(int rate)
|
||||
{
|
||||
int bit_rate;
|
||||
@@ -276,18 +285,20 @@ void disc_reset()
|
||||
disc_period = 32;
|
||||
timer_add(disc_poll_0, &(disc_poll_time[0]), &(motoron[0]), NULL);
|
||||
timer_add(disc_poll_1, &(disc_poll_time[1]), &(motoron[1]), NULL);
|
||||
timer_add(disc_poll_2, &(disc_poll_time[2]), &(motoron[2]), NULL);
|
||||
timer_add(disc_poll_3, &(disc_poll_time[3]), &(motoron[3]), NULL);
|
||||
}
|
||||
|
||||
void disc_init()
|
||||
{
|
||||
// pclog("disc_init %p\n", drives);
|
||||
drives[0].poll = drives[1].poll = 0;
|
||||
drives[0].seek = drives[1].seek = 0;
|
||||
drives[0].readsector = drives[1].readsector = 0;
|
||||
drives[0].poll = drives[1].poll = drives[2].poll = drives[3].poll = 0;
|
||||
drives[0].seek = drives[1].seek = drives[2].seek = drives[3].seek = 0;
|
||||
drives[0].readsector = drives[1].readsector = drives[2].readsector = drives[3].readsector = 0;
|
||||
disc_reset();
|
||||
}
|
||||
|
||||
int oldtrack[2] = {0, 0};
|
||||
int oldtrack[FDD_NUM] = {0, 0, 0, 0};
|
||||
void disc_seek(int drive, int track)
|
||||
{
|
||||
// pclog("disc_seek: drive=%i track=%i\n", drive, track);
|
||||
@@ -301,7 +312,7 @@ void disc_seek(int drive, int track)
|
||||
|
||||
void disc_readsector(int drive, int sector, int track, int side, int density, int sector_size)
|
||||
{
|
||||
drive ^= fdd_swap;
|
||||
drive = real_drive(drive);
|
||||
|
||||
if (drives[drive].readsector)
|
||||
drives[drive].readsector(drive, sector, track, side, density, sector_size);
|
||||
@@ -311,7 +322,7 @@ 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)
|
||||
{
|
||||
drive ^= fdd_swap;
|
||||
drive = real_drive(drive);
|
||||
|
||||
if (drives[drive].writesector)
|
||||
drives[drive].writesector(drive, sector, track, side, density, sector_size);
|
||||
@@ -321,7 +332,7 @@ void disc_writesector(int drive, int sector, int track, int side, int density, i
|
||||
|
||||
void disc_comparesector(int drive, int sector, int track, int side, int density, int sector_size)
|
||||
{
|
||||
drive ^= fdd_swap;
|
||||
drive = real_drive(drive);
|
||||
|
||||
if (drives[drive].comparesector)
|
||||
drives[drive].comparesector(drive, sector, track, side, density, sector_size);
|
||||
@@ -331,7 +342,7 @@ void disc_comparesector(int drive, int sector, int track, int side, int density,
|
||||
|
||||
void disc_readaddress(int drive, int track, int side, int density)
|
||||
{
|
||||
drive ^= fdd_swap;
|
||||
drive = real_drive(drive);
|
||||
|
||||
if (drives[drive].readaddress)
|
||||
drives[drive].readaddress(drive, track, side, density);
|
||||
@@ -339,7 +350,7 @@ 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)
|
||||
{
|
||||
drive ^= fdd_swap;
|
||||
drive = real_drive(drive);
|
||||
|
||||
if (drives[drive].format)
|
||||
drives[drive].format(drive, track, side, density, fill);
|
||||
@@ -349,7 +360,7 @@ void disc_format(int drive, int track, int side, int density, uint8_t fill)
|
||||
|
||||
void disc_stop(int drive)
|
||||
{
|
||||
drive ^= fdd_swap;
|
||||
drive = real_drive(drive);
|
||||
|
||||
if (drives[drive].stop)
|
||||
drives[drive].stop(drive);
|
||||
|
||||
23
src/disc.h
23
src/disc.h
@@ -1,6 +1,8 @@
|
||||
/* Copyright holders: Sarah Walker, Tenshi
|
||||
see COPYING for more details
|
||||
*/
|
||||
#define FDD_NUM 4
|
||||
|
||||
typedef struct
|
||||
{
|
||||
void (*seek)(int drive, int track);
|
||||
@@ -15,7 +17,7 @@ typedef struct
|
||||
void (*poll)(int drive);
|
||||
} DRIVE;
|
||||
|
||||
extern DRIVE drives[2];
|
||||
extern DRIVE drives[FDD_NUM];
|
||||
|
||||
extern int curdrive;
|
||||
|
||||
@@ -39,13 +41,12 @@ void disc_stop(int drive);
|
||||
int disc_empty(int drive);
|
||||
void disc_set_rate(int drive, int drvden, int rate);
|
||||
extern int disc_time;
|
||||
extern int disc_poll_time[2];
|
||||
extern int disc_poll_time[FDD_NUM];
|
||||
|
||||
void fdc_callback();
|
||||
int fdc_data(uint8_t dat);
|
||||
void fdc_spindown();
|
||||
void fdc_finishread();
|
||||
void fdc_notfound();
|
||||
void fdc_datacrcerror();
|
||||
void fdc_headercrcerror();
|
||||
void fdc_writeprotect();
|
||||
@@ -57,7 +58,7 @@ extern int fdc_ready;
|
||||
extern int fdc_indexcount;*/
|
||||
|
||||
extern int motorspin;
|
||||
extern int motoron[2];
|
||||
extern int motoron[FDD_NUM];
|
||||
|
||||
extern int swwp;
|
||||
extern int disable_write;
|
||||
@@ -65,16 +66,17 @@ extern int disable_write;
|
||||
extern int defaultwriteprot;
|
||||
//extern char discfns[4][260];
|
||||
|
||||
extern int writeprot[2], fwriteprot[2];
|
||||
extern int disc_track[2];
|
||||
extern int disc_changed[2];
|
||||
extern int drive_empty[2];
|
||||
extern int drive_type[2];
|
||||
extern int writeprot[FDD_NUM], fwriteprot[FDD_NUM];
|
||||
extern int disc_track[FDD_NUM];
|
||||
extern int disc_changed[FDD_NUM];
|
||||
extern int drive_empty[FDD_NUM];
|
||||
extern int drive_type[FDD_NUM];
|
||||
|
||||
/*Used in the Read A Track command. Only valid for disc_readsector(). */
|
||||
#define SECTOR_FIRST -2
|
||||
#define SECTOR_NEXT -1
|
||||
|
||||
#if 0
|
||||
/* Bits 0-3 define byte type, bit 5 defines whether it is a per-track (0) or per-sector (1) byte, if bit 7 is set, the byte is the index hole. */
|
||||
#define BYTE_GAP0 0x00
|
||||
#define BYTE_GAP1 0x10
|
||||
@@ -108,6 +110,7 @@ extern int drive_type[2];
|
||||
#define BYTE_TYPE_AM 0x03
|
||||
#define BYTE_TYPE_DATA 0x04
|
||||
#define BYTE_TYPE_CRC 0x05
|
||||
#endif
|
||||
|
||||
typedef union {
|
||||
uint16_t word;
|
||||
@@ -133,7 +136,7 @@ typedef struct
|
||||
uint8_t check_crc;
|
||||
} d86f_handler_t;
|
||||
|
||||
d86f_handler_t d86f_handler[2];
|
||||
d86f_handler_t d86f_handler[FDD_NUM];
|
||||
|
||||
void d86f_common_handlers(int drive);
|
||||
|
||||
|
||||
504
src/disc_86f.c
504
src/disc_86f.c
@@ -9,6 +9,7 @@
|
||||
#include "lzf/lzf.h"
|
||||
|
||||
#include "config.h"
|
||||
#include "dma.h"
|
||||
#include "disc.h"
|
||||
#include "disc_86f.h"
|
||||
#include "disc_random.h"
|
||||
@@ -195,193 +196,12 @@ static struct __attribute__((packed))
|
||||
int cur_track;
|
||||
uint32_t error_condition;
|
||||
int is_compressed;
|
||||
int id_found;
|
||||
uint8_t original_file_name[2048];
|
||||
uint8_t *filebuf;
|
||||
uint8_t *outbuf;
|
||||
} d86f[2];
|
||||
|
||||
#ifdef OLD_COMPRESS
|
||||
/* Compress from file source to file dest until EOF on source.
|
||||
def() returns Z_OK on success, Z_MEM_ERROR if memory could not be
|
||||
allocated for processing, Z_STREAM_ERROR if an invalid compression
|
||||
level is supplied, Z_VERSION_ERROR if the version of zlib.h and the
|
||||
version of the library linked do not match, or Z_ERRNO if there is
|
||||
an error reading or writing the files. */
|
||||
int def(FILE *source, FILE *dest, int level)
|
||||
{
|
||||
int ret, flush;
|
||||
unsigned have;
|
||||
z_stream strm;
|
||||
unsigned char in[CHUNK];
|
||||
unsigned char out[CHUNK];
|
||||
|
||||
/* allocate deflate state */
|
||||
strm.zalloc = Z_NULL;
|
||||
strm.zfree = Z_NULL;
|
||||
strm.opaque = Z_NULL;
|
||||
ret = deflateInit(&strm, level);
|
||||
if (ret != Z_OK)
|
||||
return ret;
|
||||
|
||||
/* compress until end of file */
|
||||
do {
|
||||
strm.avail_in = fread(in, 1, CHUNK, source);
|
||||
if (ferror(source)) {
|
||||
(void)deflateEnd(&strm);
|
||||
return Z_ERRNO;
|
||||
}
|
||||
flush = feof(source) ? Z_FINISH : Z_NO_FLUSH;
|
||||
strm.next_in = in;
|
||||
|
||||
/* run deflate() on input until output buffer not full, finish
|
||||
compression if all of source has been read in */
|
||||
do {
|
||||
strm.avail_out = CHUNK;
|
||||
strm.next_out = out;
|
||||
ret = deflate(&strm, flush); /* no bad return value */
|
||||
assert(ret != Z_STREAM_ERROR); /* state not clobbered */
|
||||
have = CHUNK - strm.avail_out;
|
||||
if (fwrite(out, 1, have, dest) != have || ferror(dest)) {
|
||||
(void)deflateEnd(&strm);
|
||||
return Z_ERRNO;
|
||||
}
|
||||
} while (strm.avail_out == 0);
|
||||
assert(strm.avail_in == 0); /* all input will be used */
|
||||
|
||||
/* done when last data in file processed */
|
||||
} while (flush != Z_FINISH);
|
||||
assert(ret == Z_STREAM_END); /* stream will be complete */
|
||||
|
||||
/* clean up and return */
|
||||
(void)deflateEnd(&strm);
|
||||
return Z_OK;
|
||||
}
|
||||
|
||||
/* Decompress from file source to file dest until stream ends or EOF.
|
||||
inf() returns Z_OK on success, Z_MEM_ERROR if memory could not be
|
||||
allocated for processing, Z_DATA_ERROR if the deflate data is
|
||||
invalid or incomplete, Z_VERSION_ERROR if the version of zlib.h and
|
||||
the version of the library linked do not match, or Z_ERRNO if there
|
||||
is an error reading or writing the files. */
|
||||
int inf(FILE *source, FILE *dest)
|
||||
{
|
||||
int ret;
|
||||
unsigned have;
|
||||
z_stream strm;
|
||||
unsigned char in[CHUNK];
|
||||
unsigned char out[CHUNK];
|
||||
|
||||
/* allocate inflate state */
|
||||
strm.zalloc = Z_NULL;
|
||||
strm.zfree = Z_NULL;
|
||||
strm.opaque = Z_NULL;
|
||||
strm.avail_in = 0;
|
||||
strm.next_in = Z_NULL;
|
||||
ret = inflateInit(&strm);
|
||||
if (ret != Z_OK)
|
||||
return ret;
|
||||
|
||||
/* decompress until deflate stream ends or end of file */
|
||||
do {
|
||||
strm.avail_in = fread(in, 1, CHUNK, source);
|
||||
if (ferror(source)) {
|
||||
(void)inflateEnd(&strm);
|
||||
return Z_ERRNO;
|
||||
}
|
||||
if (strm.avail_in == 0)
|
||||
break;
|
||||
strm.next_in = in;
|
||||
|
||||
/* run inflate() on input until output buffer not full */
|
||||
do {
|
||||
strm.avail_out = CHUNK;
|
||||
strm.next_out = out;
|
||||
ret = inflate(&strm, Z_NO_FLUSH);
|
||||
assert(ret != Z_STREAM_ERROR); /* state not clobbered */
|
||||
switch (ret) {
|
||||
case Z_NEED_DICT:
|
||||
ret = Z_DATA_ERROR; /* and fall through */
|
||||
case Z_DATA_ERROR:
|
||||
case Z_MEM_ERROR:
|
||||
(void)inflateEnd(&strm);
|
||||
return ret;
|
||||
}
|
||||
have = CHUNK - strm.avail_out;
|
||||
if (fwrite(out, 1, have, dest) != have || ferror(dest)) {
|
||||
(void)inflateEnd(&strm);
|
||||
return Z_ERRNO;
|
||||
}
|
||||
} while (strm.avail_out == 0);
|
||||
|
||||
/* done when inflate() says it's done */
|
||||
} while (ret != Z_STREAM_END);
|
||||
|
||||
/* clean up and return */
|
||||
(void)inflateEnd(&strm);
|
||||
return ret == Z_STREAM_END ? Z_OK : Z_DATA_ERROR;
|
||||
}
|
||||
|
||||
/* compress or decompress */
|
||||
int d86f_zlib(FILE *dst, FILE *src, int dir)
|
||||
{
|
||||
int ret;
|
||||
|
||||
/* do compression if no arguments */
|
||||
if (!dir) {
|
||||
ret = def(src, dst, Z_DEFAULT_COMPRESSION);
|
||||
if (ret != Z_OK)
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* do decompression if -d specified */
|
||||
else if (dir) {
|
||||
ret = inf(src, dst);
|
||||
if (ret != Z_OK)
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef OLD_CRC
|
||||
void d86f_generate_table64()
|
||||
{
|
||||
for(int i=0; i<256; ++i)
|
||||
{
|
||||
uint64_t crc = i;
|
||||
|
||||
for(unsigned int j=0; j<8; ++j)
|
||||
{
|
||||
// is current coefficient set?
|
||||
if(crc & 1)
|
||||
{
|
||||
// yes, then assume it gets zero'd (by implied x^64 coefficient of dividend)
|
||||
crc >>= 1;
|
||||
|
||||
// and add rest of the divisor
|
||||
crc ^= poly;
|
||||
}
|
||||
else
|
||||
{
|
||||
// no? then move to next coefficient
|
||||
crc >>= 1;
|
||||
}
|
||||
}
|
||||
|
||||
table[i] = crc;
|
||||
}
|
||||
}
|
||||
|
||||
void d86f_calccrc64(uint8_t b, uint64_t *crc)
|
||||
{
|
||||
uint8_t index = b ^ *crc;
|
||||
uint64_t lookup = table[index];
|
||||
|
||||
*crc >>= 8;
|
||||
*crc ^= lookup;
|
||||
}
|
||||
#endif
|
||||
uint32_t dma_over;
|
||||
} d86f[FDD_NUM];
|
||||
|
||||
static void d86f_setupcrc(uint16_t poly)
|
||||
{
|
||||
@@ -841,13 +661,66 @@ int d86f_format_conditions(int drive)
|
||||
return d86f_valid_bit_rate(drive);
|
||||
}
|
||||
|
||||
int d86f_wrong_densel(int drive)
|
||||
{
|
||||
int is_3mode = 0;
|
||||
|
||||
if ((fdd_get_flags(drive) & 7) == 3)
|
||||
{
|
||||
is_3mode = 1;
|
||||
}
|
||||
|
||||
switch (d86f_hole(drive))
|
||||
{
|
||||
case 0:
|
||||
default:
|
||||
if (fdd_get_densel(drive))
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
if (fdd_get_densel(drive))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (is_3mode)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
if (fdd_get_densel(drive))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
int d86f_can_format(int drive)
|
||||
{
|
||||
int temp;
|
||||
temp = !writeprot[drive];
|
||||
temp = temp && !swwp;
|
||||
temp = temp && fdd_can_read_medium(drive ^ fdd_swap);
|
||||
temp = temp && fdd_can_read_medium(real_drive(drive));
|
||||
temp = temp && d86f_handler[drive].format_conditions(drive); /* Allows proxied formats to add their own extra conditions to formatting. */
|
||||
temp = temp && !d86f_wrong_densel(drive);
|
||||
return temp;
|
||||
}
|
||||
|
||||
@@ -924,7 +797,7 @@ static int d86f_get_bitcell_period(int drive)
|
||||
if (!mfm) rate /= 2.0;
|
||||
size = (size * 250.0) / rate;
|
||||
size = (size * 300.0) / rpm;
|
||||
size = (size * fdd_getrpm(drive ^ fdd_swap)) / 300.0;
|
||||
size = (size * fdd_getrpm(real_drive(drive))) / 300.0;
|
||||
return (int) size;
|
||||
}
|
||||
|
||||
@@ -932,7 +805,7 @@ int d86f_can_read_address(int drive)
|
||||
{
|
||||
int temp = 0;
|
||||
temp = (fdc_get_bitcell_period() == d86f_get_bitcell_period(drive));
|
||||
temp = temp && fdd_can_read_medium(drive ^ fdd_swap);
|
||||
temp = temp && fdd_can_read_medium(real_drive(drive));
|
||||
temp = temp && (fdc_is_mfm() == d86f_is_mfm(drive));
|
||||
temp = temp && (d86f_get_encoding(drive) <= 1);
|
||||
return temp;
|
||||
@@ -1270,6 +1143,7 @@ void d86f_find_address_mark_mfm(int drive, int side, find_t *find, uint16_t req_
|
||||
else
|
||||
{
|
||||
/* Not skip mode, process the sector anyway. */
|
||||
// pclog("Wrong AM found (%04X) (%02X)\n", other_am, d86f[drive].state);
|
||||
fdc_set_wrong_am();
|
||||
d86f[drive].preceding_bit[side] = d86f[drive].last_word[side] & 1;
|
||||
d86f[drive].state++;
|
||||
@@ -1345,7 +1219,7 @@ void d86f_read_sector_id(int drive, int side, int match)
|
||||
if (d86f[drive].calc_crc.word != d86f[drive].track_crc.word)
|
||||
{
|
||||
d86f[drive].id_find.sync_marks = d86f[drive].id_find.bits_obtained = d86f[drive].id_find.bytes_obtained = 0;
|
||||
// printf("%04X != %04X (%08X)\n", d86f[drive].track_crc.word, d86f[drive].calc_crc.word, d86f[drive].last_sector.dword);
|
||||
printf("ID CRC error: %04X != %04X (%08X)\n", d86f[drive].track_crc.word, d86f[drive].calc_crc.word, d86f[drive].last_sector.dword);
|
||||
if ((d86f[drive].state != STATE_02_READ_ID) && (d86f[drive].state != STATE_0A_READ_ID))
|
||||
{
|
||||
d86f[drive].error_condition = 0;
|
||||
@@ -1373,8 +1247,9 @@ void d86f_read_sector_id(int drive, int side, int match)
|
||||
else
|
||||
{
|
||||
/* CRC is valid. */
|
||||
// pclog("Sector ID found: %08X\n", last_sector.dword);
|
||||
// pclog("Sector ID found: %08X; Requested: %08X\n", d86f[drive].last_sector.dword, d86f[drive].req_sector.dword);
|
||||
d86f[drive].id_find.sync_marks = d86f[drive].id_find.bits_obtained = d86f[drive].id_find.bytes_obtained = 0;
|
||||
d86f[drive].id_found++;
|
||||
if ((d86f[drive].last_sector.dword == d86f[drive].req_sector.dword) || !match)
|
||||
{
|
||||
// pclog("ID read (%02X)\n", d86f[drive].state);
|
||||
@@ -1395,6 +1270,20 @@ void d86f_read_sector_id(int drive, int side, int match)
|
||||
}
|
||||
else
|
||||
{
|
||||
if (d86f[drive].last_sector.id.c != d86f[drive].req_sector.id.c)
|
||||
{
|
||||
if (d86f[drive].last_sector.id.c == 0xFF)
|
||||
{
|
||||
// pclog("[State: %02X] [Side %i] Bad cylinder (%i != %i?) (%02X) (%08X) (%i)\n", d86f[drive].state, side, fdc_get_bitcell_period(), d86f_get_bitcell_period(drive), d86f_handler[drive].side_flags(drive), d86f[drive].req_sector.dword, d86f_handler[drive].get_raw_size(drive, side));
|
||||
d86f[drive].error_condition |= 8;
|
||||
}
|
||||
else
|
||||
{
|
||||
// pclog("[State: %02X] [Side %i] Wrong cylinder (%i != %i?) (%02X) (%08X) (%i)\n", d86f[drive].state, side, fdc_get_bitcell_period(), d86f_get_bitcell_period(drive), d86f_handler[drive].side_flags(drive), d86f[drive].req_sector.dword, d86f_handler[drive].get_raw_size(drive, side));
|
||||
d86f[drive].error_condition |= 0x10;
|
||||
}
|
||||
}
|
||||
|
||||
d86f[drive].state--;
|
||||
}
|
||||
}
|
||||
@@ -1414,9 +1303,17 @@ uint8_t d86f_get_data(int drive, int base)
|
||||
if (d86f[drive].data_find.bytes_obtained < (d86f_get_data_len(drive) + base))
|
||||
{
|
||||
data = fdc_getdata(d86f[drive].data_find.bytes_obtained == (d86f_get_data_len(drive) + base - 1));
|
||||
if (data == -1)
|
||||
if ((data & DMA_OVER) || (data == -1))
|
||||
{
|
||||
data = 0;
|
||||
d86f[drive].dma_over++;
|
||||
if (data == -1)
|
||||
{
|
||||
data = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
data &= 0xff;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -1457,6 +1354,7 @@ void d86f_read_sector_data(int drive, int side)
|
||||
{
|
||||
int data = 0;
|
||||
int recv_data = 0;
|
||||
int read_status = 0;
|
||||
uint16_t temp;
|
||||
uint32_t sector_len = d86f[drive].last_sector.id.n;
|
||||
uint32_t crc_pos = 0;
|
||||
@@ -1483,7 +1381,12 @@ void d86f_read_sector_data(int drive, int side)
|
||||
{
|
||||
if (d86f[drive].state != STATE_16_VERIFY_DATA)
|
||||
{
|
||||
fdc_data(data);
|
||||
read_status = fdc_data(data);
|
||||
if (read_status == -1)
|
||||
{
|
||||
d86f[drive].dma_over++;
|
||||
// pclog("DMA over now: %i\n", d86f[drive].dma_over);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1498,9 +1401,28 @@ void d86f_read_sector_data(int drive, int side)
|
||||
if (d86f[drive].data_find.bytes_obtained == (crc_pos + fdc_get_gap()))
|
||||
{
|
||||
/* We've got the data. */
|
||||
if (d86f[drive].dma_over > 1)
|
||||
{
|
||||
// pclog("DMA overrun while reading data!\n");
|
||||
d86f[drive].data_find.sync_marks = d86f[drive].data_find.bits_obtained = d86f[drive].data_find.bytes_obtained = 0;
|
||||
d86f[drive].error_condition = 0;
|
||||
d86f[drive].state = STATE_IDLE;
|
||||
fdc_finishread();
|
||||
fdc_overrun();
|
||||
|
||||
d86f_get_bit(drive, side);
|
||||
|
||||
d86f[drive].data_find.bits_obtained++;
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
// pclog("Bytes over DMA: %i\n", d86f[drive].dma_over);
|
||||
}
|
||||
|
||||
if ((d86f[drive].calc_crc.word != d86f[drive].track_crc.word) && (d86f[drive].state != STATE_02_READ_DATA))
|
||||
{
|
||||
// printf("%04X != %04X (%08X)\n", d86f[drive].track_crc.word, d86f[drive].calc_crc.word, d86f[drive].last_sector.dword);
|
||||
printf("Data CRC error: %04X != %04X (%08X)\n", d86f[drive].track_crc.word, d86f[drive].calc_crc.word, d86f[drive].last_sector.dword);
|
||||
d86f[drive].data_find.sync_marks = d86f[drive].data_find.bits_obtained = d86f[drive].data_find.bytes_obtained = 0;
|
||||
d86f[drive].error_condition = 0;
|
||||
d86f[drive].state = STATE_IDLE;
|
||||
@@ -1650,6 +1572,19 @@ void d86f_write_sector_data(int drive, int side, int mfm, uint16_t am)
|
||||
|
||||
if (d86f[drive].data_find.bytes_obtained == (crc_pos + fdc_get_gap()))
|
||||
{
|
||||
if (d86f[drive].dma_over > 1)
|
||||
{
|
||||
// pclog("DMA overrun while writing data!\n");
|
||||
d86f[drive].data_find.sync_marks = d86f[drive].data_find.bits_obtained = d86f[drive].data_find.bytes_obtained = 0;
|
||||
d86f[drive].error_condition = 0;
|
||||
d86f[drive].state = STATE_IDLE;
|
||||
fdc_finishread();
|
||||
fdc_overrun();
|
||||
|
||||
d86f[drive].data_find.bits_obtained++;
|
||||
return;
|
||||
}
|
||||
|
||||
/* We've written the data. */
|
||||
d86f[drive].data_find.sync_marks = d86f[drive].data_find.bits_obtained = d86f[drive].data_find.bytes_obtained = 0;
|
||||
d86f[drive].error_condition = 0;
|
||||
@@ -1669,15 +1604,24 @@ void d86f_advance_bit(int drive, int side)
|
||||
d86f[drive].track_pos++;
|
||||
d86f[drive].track_pos %= d86f_handler[drive].get_raw_size(drive, side);
|
||||
|
||||
if (d86f[drive].track_pos == d86f_handler[drive].index_hole_pos(drive, side)) d86f_handler[drive].read_revolution(drive);
|
||||
if (d86f[drive].track_pos == d86f_handler[drive].index_hole_pos(drive, side))
|
||||
{
|
||||
d86f_handler[drive].read_revolution(drive);
|
||||
|
||||
if ((d86f[drive].track_pos == d86f_handler[drive].index_hole_pos(drive, side)) && (d86f[drive].state != STATE_IDLE)) d86f[drive].index_count++;
|
||||
if (d86f[drive].state != STATE_IDLE)
|
||||
{
|
||||
d86f[drive].index_count++;
|
||||
// pclog("Index count now: %i\n", d86f[drive].index_count);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void d86f_advance_word(int drive, int side)
|
||||
{
|
||||
d86f[drive].track_pos += 16;
|
||||
d86f[drive].track_pos %= d86f_handler[drive].get_raw_size(drive, side);
|
||||
|
||||
if ((d86f[drive].track_pos == d86f_handler[drive].index_hole_pos(drive, side)) && (d86f[drive].state != STATE_IDLE)) d86f[drive].index_count++;
|
||||
}
|
||||
|
||||
void d86f_spin_to_index(int drive, int side)
|
||||
@@ -1765,6 +1709,24 @@ uint16_t endian_swap(uint16_t word)
|
||||
return temp;
|
||||
}
|
||||
|
||||
void d86f_format_finish(int drive, int side, int mfm, uint16_t sc, uint16_t gap_fill, int do_write)
|
||||
{
|
||||
if (mfm && do_write)
|
||||
{
|
||||
if (do_write && (d86f[drive].track_pos == d86f_handler[drive].index_hole_pos(drive, side)))
|
||||
{
|
||||
d86f_write_direct_common(drive, side, gap_fill, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
d86f[drive].state = STATE_IDLE;
|
||||
d86f_handler[drive].writeback(drive);
|
||||
// pclog("Format finished (%i) (%i)!\n", d86f[drive].track_pos, sc);
|
||||
d86f[drive].error_condition = 0;
|
||||
d86f[drive].datac = 0;
|
||||
fdc_sector_finishread();
|
||||
}
|
||||
|
||||
void d86f_format_track(int drive, int side)
|
||||
{
|
||||
int data;
|
||||
@@ -1791,7 +1753,7 @@ void d86f_format_track(int drive, int side)
|
||||
am_len = mfm ? 4 : 1;
|
||||
gap_sizes[0] = mfm ? 80 : 40;
|
||||
gap_sizes[1] = mfm ? 50 : 26;
|
||||
gap_sizes[2] = fdc_get_gap2(drive ^ fdd_swap);
|
||||
gap_sizes[2] = fdc_get_gap2(real_drive(drive));
|
||||
gap_sizes[3] = fdc_get_gap();
|
||||
sync_len = mfm ? 12 : 6;
|
||||
sc = fdc_get_format_sectors();
|
||||
@@ -1813,6 +1775,10 @@ void d86f_format_track(int drive, int side)
|
||||
if (d86f[drive].datac <= 3)
|
||||
{
|
||||
data = fdc_getdata(0);
|
||||
if (data != -1)
|
||||
{
|
||||
data &= 0xff;
|
||||
}
|
||||
if ((data == -1) && (d86f[drive].datac < 3))
|
||||
{
|
||||
data = 0;
|
||||
@@ -1822,7 +1788,7 @@ void d86f_format_track(int drive, int side)
|
||||
if (d86f[drive].datac == 3)
|
||||
{
|
||||
fdc_stop_id_request();
|
||||
// pclog("Formatting sector: %08X...\n", d86f[drive].format_sector_id.dword);
|
||||
// pclog("Formatting sector: %08X (%i) (%i)...\n", d86f[drive].format_sector_id.dword, d86f[drive].track_pos, sc);
|
||||
}
|
||||
}
|
||||
case FMT_PRETRK_SYNC:
|
||||
@@ -1913,20 +1879,10 @@ void d86f_format_track(int drive, int side)
|
||||
|
||||
d86f_advance_word(drive, side);
|
||||
|
||||
if (d86f[drive].track_pos == d86f_handler[drive].index_hole_pos(drive, side))
|
||||
if ((d86f[drive].index_count) && (d86f[drive].format_state < FMT_SECTOR_ID_SYNC) || (d86f[drive].format_state > FMT_SECTOR_GAP3))
|
||||
{
|
||||
/* Before we return, if the encoding is MFM, we have to make sure the clock bit of the first bit in the track is correct. */
|
||||
if (mfm && do_write)
|
||||
{
|
||||
if (do_write) d86f_write_direct_common(drive, side, gap_fill, 0, 0);
|
||||
}
|
||||
|
||||
d86f[drive].state = STATE_IDLE;
|
||||
d86f_handler[drive].writeback(drive);
|
||||
// pclog("Format finished!\n");
|
||||
d86f[drive].error_condition = 0;
|
||||
d86f[drive].datac = 0;
|
||||
fdc_sector_finishread();
|
||||
// pclog("Format finished regularly\n");
|
||||
d86f_format_finish(drive, side, mfm, sc, gap_fill, do_write);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1945,6 +1901,12 @@ void d86f_format_track(int drive, int side)
|
||||
d86f[drive].calc_crc.word = 0xffff;
|
||||
break;
|
||||
case FMT_POSTTRK_CHECK:
|
||||
if (d86f[drive].index_count)
|
||||
{
|
||||
// pclog("Format finished with delay\n");
|
||||
d86f_format_finish(drive, side, mfm, sc, gap_fill, do_write);
|
||||
return;
|
||||
}
|
||||
d86f[drive].sector_count++;
|
||||
if (d86f[drive].sector_count < sc)
|
||||
{
|
||||
@@ -1983,16 +1945,19 @@ void d86f_poll(int drive)
|
||||
{
|
||||
if (!d86f_can_read_address(drive))
|
||||
{
|
||||
/* if (fdc_get_bitcell_period() != d86f_get_bitcell_period(drive)) pclog("Bitcell period mismatch\n");
|
||||
if (!fdd_can_read_medium(drive ^ fdd_swap)) pclog("Drive can not read medium (hole = %01X)\n", d86f_hole(drive));
|
||||
if (fdc_is_mfm() != d86f_is_mfm(drive)) pclog("Encoding mismatch\n");
|
||||
if (d86f_get_encoding(drive) > 1) pclog("Image encoding (%s) not FM or MFM\n", (d86f_get_encoding(drive) == 2) ? "M2FM" : "GCR"); */
|
||||
/* if (fdc_get_bitcell_period() != d86f_get_bitcell_period(drive)) pclog("[%i, %i] Bitcell period mismatch (%i != %i)\n", drive, side, fdc_get_bitcell_period(), d86f_get_bitcell_period(drive));
|
||||
if (!fdd_can_read_medium(real_drive(drive))) pclog("[%i, %i] Drive can not read medium (hole = %01X)\n", drive, side, d86f_hole(drive));
|
||||
if (fdc_is_mfm() != d86f_is_mfm(drive)) pclog("[%i, %i] Encoding mismatch\n", drive, side);
|
||||
if (d86f_get_encoding(drive) > 1) pclog("[%i, %i] Image encoding (%s) not FM or MFM\n", drive, side, (d86f_get_encoding(drive) == 2) ? "M2FM" : "GCR"); */
|
||||
|
||||
d86f[drive].state = STATE_SECTOR_NOT_FOUND;
|
||||
}
|
||||
}
|
||||
|
||||
d86f_get_bit(drive, side ^ 1);
|
||||
if ((d86f[drive].state != STATE_02_SPIN_TO_INDEX) && (d86f[drive].state != STATE_0D_SPIN_TO_INDEX))
|
||||
{
|
||||
d86f_get_bit(drive, side ^ 1);
|
||||
}
|
||||
|
||||
switch(d86f[drive].state)
|
||||
{
|
||||
@@ -2114,11 +2079,77 @@ void d86f_poll(int drive)
|
||||
|
||||
d86f_advance_bit(drive, side);
|
||||
|
||||
if (d86f_wrong_densel(drive) && (d86f[drive].state != STATE_IDLE))
|
||||
{
|
||||
// pclog("[State: %02X] [Side %i] No ID address mark (%i != %i?) (%02X) (%08X) (%i)\n", d86f[drive].state, side, fdc_get_bitcell_period(), d86f_get_bitcell_period(drive), d86f_handler[drive].side_flags(drive), d86f[drive].req_sector.dword, d86f_handler[drive].get_raw_size(drive, side));
|
||||
d86f[drive].state = STATE_IDLE;
|
||||
fdc_noidam();
|
||||
return;
|
||||
}
|
||||
|
||||
if ((d86f[drive].index_count == 2) && (d86f[drive].state != STATE_IDLE))
|
||||
{
|
||||
// pclog("[State: %02X] [Side %i] Sector not found (%i != %i?) (%02X) (%08X) (%i)\n", d86f[drive].state, side, fdc_get_bitcell_period(), d86f_get_bitcell_period(drive), d86f_handler[drive].side_flags(drive), d86f[drive].req_sector.dword, d86f_handler[drive].get_raw_size(drive, side));
|
||||
d86f[drive].state = STATE_IDLE;
|
||||
fdc_notfound();
|
||||
switch(d86f[drive].state)
|
||||
{
|
||||
case STATE_0A_FIND_ID:
|
||||
case STATE_SECTOR_NOT_FOUND:
|
||||
// pclog("[State: %02X] [Side %i] No ID address mark (%i != %i?) (%02X) (%08X) (%i)\n", d86f[drive].state, side, fdc_get_bitcell_period(), d86f_get_bitcell_period(drive), d86f_handler[drive].side_flags(drive), d86f[drive].req_sector.dword, d86f_handler[drive].get_raw_size(drive, side));
|
||||
d86f[drive].state = STATE_IDLE;
|
||||
fdc_noidam();
|
||||
break;
|
||||
case STATE_02_FIND_DATA:
|
||||
case STATE_06_FIND_DATA:
|
||||
case STATE_11_FIND_DATA:
|
||||
case STATE_16_FIND_DATA:
|
||||
case STATE_05_FIND_DATA:
|
||||
case STATE_09_FIND_DATA:
|
||||
case STATE_0C_FIND_DATA:
|
||||
// pclog("[State: %02X] [Side %i] No data address mark (%i != %i?) (%02X) (%08X) (%i)\n", d86f[drive].state, side, fdc_get_bitcell_period(), d86f_get_bitcell_period(drive), d86f_handler[drive].side_flags(drive), d86f[drive].req_sector.dword, d86f_handler[drive].get_raw_size(drive, side));
|
||||
d86f[drive].state = STATE_IDLE;
|
||||
fdc_nodataam();
|
||||
break;
|
||||
case STATE_02_SPIN_TO_INDEX:
|
||||
case STATE_02_READ_DATA:
|
||||
case STATE_05_WRITE_DATA:
|
||||
case STATE_06_READ_DATA:
|
||||
case STATE_09_WRITE_DATA:
|
||||
case STATE_0C_READ_DATA:
|
||||
case STATE_0D_SPIN_TO_INDEX:
|
||||
case STATE_0D_FORMAT_TRACK:
|
||||
case STATE_11_SCAN_DATA:
|
||||
case STATE_16_VERIFY_DATA:
|
||||
/* In these states, we should *NEVER* care about how many index pulses there have been. */
|
||||
break;
|
||||
default:
|
||||
d86f[drive].state = STATE_IDLE;
|
||||
if (d86f[drive].id_found)
|
||||
{
|
||||
if (d86f[drive].error_condition & 0x18)
|
||||
{
|
||||
if ((d86f[drive].error_condition & 0x18) == 0x08)
|
||||
{
|
||||
// pclog("[State: %02X] [Side %i] Bad cylinder (%i != %i?) (%02X) (%08X) (%i)\n", d86f[drive].state, side, fdc_get_bitcell_period(), d86f_get_bitcell_period(drive), d86f_handler[drive].side_flags(drive), d86f[drive].req_sector.dword, d86f_handler[drive].get_raw_size(drive, side));
|
||||
fdc_badcylinder();
|
||||
}
|
||||
if ((d86f[drive].error_condition & 0x10) == 0x10)
|
||||
{
|
||||
// pclog("[State: %02X] [Side %i] Wrong cylinder (%i != %i?) (%02X) (%08X) (%i)\n", d86f[drive].state, side, fdc_get_bitcell_period(), d86f_get_bitcell_period(drive), d86f_handler[drive].side_flags(drive), d86f[drive].req_sector.dword, d86f_handler[drive].get_raw_size(drive, side));
|
||||
fdc_wrongcylinder();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// pclog("[State: %02X] [Side %i] Sector not found (%i != %i?) (%02X) (%08X) (%i)\n", d86f[drive].state, side, fdc_get_bitcell_period(), d86f_get_bitcell_period(drive), d86f_handler[drive].side_flags(drive), d86f[drive].req_sector.dword, d86f_handler[drive].get_raw_size(drive, side));
|
||||
fdc_nosector();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// pclog("[State: %02X] [Side %i] No ID address mark (%i != %i?) (%02X) (%08X) (%i)\n", d86f[drive].state, side, fdc_get_bitcell_period(), d86f_get_bitcell_period(drive), d86f_handler[drive].side_flags(drive), d86f[drive].req_sector.dword, d86f_handler[drive].get_raw_size(drive, side));
|
||||
fdc_noidam();
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2628,7 +2659,7 @@ void d86f_writeback(int drive)
|
||||
{
|
||||
logical_track = d86f[drive].cur_track + thin_track;
|
||||
}
|
||||
if (d86f[drive].track_offset[((d86f[drive].cur_track + thin_track) << 1) + side])
|
||||
if (d86f[drive].track_offset[logical_track])
|
||||
{
|
||||
fseek(d86f[drive].f, d86f[drive].track_offset[logical_track], SEEK_SET);
|
||||
d86f_write_track(drive, side, d86f[drive].thin_track_encoded_data[thin_track][side], d86f[drive].thin_track_surface_data[thin_track][side]);
|
||||
@@ -2648,7 +2679,7 @@ void d86f_writeback(int drive)
|
||||
{
|
||||
logical_track = d86f[drive].cur_track;
|
||||
}
|
||||
if (d86f[drive].track_offset[(d86f[drive].cur_track << 1) + side])
|
||||
if (d86f[drive].track_offset[logical_track])
|
||||
{
|
||||
// pclog("Writing track...\n");
|
||||
fseek(d86f[drive].f, d86f[drive].track_offset[logical_track], SEEK_SET);
|
||||
@@ -2751,16 +2782,28 @@ void d86f_stop(int drive)
|
||||
|
||||
int d86f_common_command(int drive, int sector, int track, int side, int rate, int sector_size)
|
||||
{
|
||||
// pclog("d86f_common_command: fdc_period=%i img_period=%i rate=%i sector=%i track=%i side=%i\n", fdc_get_bitcell_period(), d86f_get_bitcell_period(drive), rate, sector, track, side);
|
||||
// pclog("d86f_common_command (drive %i): fdc_period=%i img_period=%i rate=%i sector=%i track=%i side=%i\n", drive, fdc_get_bitcell_period(), d86f_get_bitcell_period(drive), rate, sector, track, side);
|
||||
|
||||
d86f[drive].req_sector.id.c = track;
|
||||
d86f[drive].req_sector.id.h = side;
|
||||
d86f[drive].req_sector.id.r = sector;
|
||||
if (sector == SECTOR_FIRST)
|
||||
{
|
||||
d86f[drive].req_sector.id.r = 1;
|
||||
}
|
||||
else if (sector == SECTOR_NEXT)
|
||||
{
|
||||
d86f[drive].req_sector.id.r++;
|
||||
}
|
||||
else
|
||||
{
|
||||
d86f[drive].req_sector.id.r = sector;
|
||||
}
|
||||
d86f[drive].req_sector.id.n = sector_size;
|
||||
|
||||
if (fdd_get_head(drive) && (d86f_get_sides(drive) == 1))
|
||||
{
|
||||
fdc_notfound();
|
||||
// pclog("Wrong side!\n");
|
||||
fdc_noidam();
|
||||
d86f[drive].state = STATE_IDLE;
|
||||
d86f[drive].index_count = 0;
|
||||
return 0;
|
||||
@@ -2769,6 +2812,8 @@ int d86f_common_command(int drive, int sector, int track, int side, int rate, in
|
||||
d86f[drive].id_find.sync_marks = d86f[drive].id_find.bits_obtained = d86f[drive].id_find.bytes_obtained = 0;
|
||||
d86f[drive].data_find.sync_marks = d86f[drive].data_find.bits_obtained = d86f[drive].data_find.bytes_obtained = 0;
|
||||
d86f[drive].index_count = d86f[drive].error_condition = d86f[drive].satisfying_bytes = 0;
|
||||
d86f[drive].id_found = 0;
|
||||
d86f[drive].dma_over = 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
@@ -2818,10 +2863,12 @@ void d86f_comparesector(int drive, int sector, int track, int side, int rate, in
|
||||
|
||||
void d86f_readaddress(int drive, int track, int side, int rate)
|
||||
{
|
||||
// pclog("Reading sector ID on drive %i...\n", drive);
|
||||
|
||||
if (fdd_get_head(drive) && (d86f_get_sides(drive) == 1))
|
||||
{
|
||||
pclog("Trying to access the second side of a single-sided disk\n");
|
||||
fdc_notfound();
|
||||
// pclog("Trying to access the second side of a single-sided disk\n");
|
||||
fdc_noidam();
|
||||
d86f[drive].state = STATE_IDLE;
|
||||
d86f[drive].index_count = 0;
|
||||
return;
|
||||
@@ -2830,6 +2877,8 @@ void d86f_readaddress(int drive, int track, int side, int rate)
|
||||
d86f[drive].id_find.sync_marks = d86f[drive].id_find.bits_obtained = d86f[drive].id_find.bytes_obtained = 0;
|
||||
d86f[drive].data_find.sync_marks = d86f[drive].data_find.bits_obtained = d86f[drive].data_find.bytes_obtained = 0;
|
||||
d86f[drive].index_count = d86f[drive].error_condition = d86f[drive].satisfying_bytes = 0;
|
||||
d86f[drive].id_found = 0;
|
||||
d86f[drive].dma_over = 0;
|
||||
|
||||
d86f[drive].state = STATE_0A_FIND_ID;
|
||||
}
|
||||
@@ -2888,7 +2937,7 @@ void d86f_common_format(int drive, int track, int side, int rate, uint8_t fill,
|
||||
|
||||
if ((side && (d86f_get_sides(drive) == 1)) || !(d86f_can_format(drive)))
|
||||
{
|
||||
fdc_notfound();
|
||||
fdc_cannotformat();
|
||||
d86f[drive].state = STATE_IDLE;
|
||||
d86f[drive].index_count = 0;
|
||||
return;
|
||||
@@ -2938,7 +2987,7 @@ void d86f_common_format(int drive, int track, int side, int rate, uint8_t fill,
|
||||
{
|
||||
// d86f[drive].side_flags[side] &= 0xc0;
|
||||
d86f[drive].side_flags[side] = 0;
|
||||
d86f[drive].side_flags[side] |= (fdd_getrpm(drive ^ fdd_swap) == 360) ? 0x20 : 0;
|
||||
d86f[drive].side_flags[side] |= (fdd_getrpm(real_drive(drive)) == 360) ? 0x20 : 0;
|
||||
d86f[drive].side_flags[side] |= fdc_get_bit_rate();
|
||||
d86f[drive].side_flags[side] |= fdc_is_mfm() ? 8 : 0;
|
||||
|
||||
@@ -2948,6 +2997,7 @@ void d86f_common_format(int drive, int track, int side, int rate, uint8_t fill,
|
||||
d86f[drive].id_find.sync_marks = d86f[drive].id_find.bits_obtained = d86f[drive].id_find.bytes_obtained = 0;
|
||||
d86f[drive].data_find.sync_marks = d86f[drive].data_find.bits_obtained = d86f[drive].data_find.bytes_obtained = 0;
|
||||
d86f[drive].index_count = d86f[drive].error_condition = d86f[drive].satisfying_bytes = d86f[drive].sector_count = 0;
|
||||
d86f[drive].dma_over = 0;
|
||||
|
||||
d86f[drive].state = STATE_0D_SPIN_TO_INDEX;
|
||||
}
|
||||
|
||||
@@ -38,7 +38,9 @@ void d86f_prepare_track_layout(int drive, int side);
|
||||
#define pre_data length_sync + length_am
|
||||
#define post_gap length_crc
|
||||
|
||||
#if 0
|
||||
extern int raw_tsize[2];
|
||||
extern int gap2_size[2];
|
||||
extern int gap3_size[2];
|
||||
extern int gap4_size[2];
|
||||
#endif
|
||||
|
||||
@@ -24,7 +24,7 @@ static struct
|
||||
int trackindex[2][4];
|
||||
|
||||
int lasttrack;
|
||||
} fdi[2];
|
||||
} fdi[FDD_NUM];
|
||||
|
||||
uint16_t fdi_disk_flags(int drive)
|
||||
{
|
||||
@@ -117,24 +117,28 @@ int32_t fdi_extra_bit_cells(int drive, int side)
|
||||
|
||||
int raw_size = 0;
|
||||
|
||||
int is_300_rpm = 0;
|
||||
|
||||
density = fdi_density();
|
||||
|
||||
is_300_rpm = (fdd_getrpm(real_drive(drive)) == 300);
|
||||
|
||||
switch (fdc_get_bit_rate())
|
||||
{
|
||||
case 0:
|
||||
raw_size = (fdd_getrpm(drive ^ fdd_swap) == 300) ? 200000 : 166666;
|
||||
raw_size = is_300_rpm ? 200000 : 166666;
|
||||
break;
|
||||
case 1:
|
||||
raw_size = (fdd_getrpm(drive ^ fdd_swap) == 300) ? 120000 : 100000;
|
||||
raw_size = is_300_rpm ? 120000 : 100000;
|
||||
break;
|
||||
case 2:
|
||||
raw_size = (fdd_getrpm(drive ^ fdd_swap) == 300) ? 100000 : 83333;
|
||||
raw_size = is_300_rpm ? 100000 : 83333;
|
||||
case 3:
|
||||
case 5:
|
||||
raw_size = (fdd_getrpm(drive ^ fdd_swap) == 300) ? 400000 : 333333;
|
||||
raw_size = is_300_rpm ? 400000 : 333333;
|
||||
break;
|
||||
default:
|
||||
raw_size = (fdd_getrpm(drive ^ fdd_swap) == 300) ? 100000 : 83333;
|
||||
raw_size = is_300_rpm ? 100000 : 83333;
|
||||
}
|
||||
|
||||
return (fdi[drive].tracklen[side][density] - raw_size);
|
||||
|
||||
@@ -40,7 +40,7 @@ static struct
|
||||
uint8_t interleave_ordered_pos[256][2];
|
||||
uint8_t *current_data[2];
|
||||
uint8_t track_buffer[2][25000];
|
||||
} imd[2];
|
||||
} imd[FDD_NUM];
|
||||
|
||||
void imd_init()
|
||||
{
|
||||
|
||||
@@ -27,7 +27,7 @@ static struct
|
||||
uint16_t sector_pos[2][256];
|
||||
uint8_t current_sector_pos_side;
|
||||
uint16_t current_sector_pos;
|
||||
} img[2];
|
||||
} img[FDD_NUM];
|
||||
|
||||
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 };
|
||||
@@ -193,6 +193,32 @@ void img_init()
|
||||
|
||||
void d86f_register_img(int drive);
|
||||
|
||||
int bps_is_valid(uint16_t bps)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i <= 8; i++)
|
||||
{
|
||||
if (bps == (128 << i))
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int first_byte_is_valid(uint8_t first_byte)
|
||||
{
|
||||
switch(first_byte)
|
||||
{
|
||||
case 0x60:
|
||||
case 0xE9:
|
||||
case 0xEB:
|
||||
return 1;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
void img_load(int drive, char *fn)
|
||||
{
|
||||
int size;
|
||||
@@ -208,6 +234,7 @@ void img_load(int drive, char *fn)
|
||||
char ext[4];
|
||||
int fdi;
|
||||
int i;
|
||||
uint8_t first_byte;
|
||||
|
||||
ext[0] = fn[strlen(fn) - 3] | 0x60;
|
||||
ext[1] = fn[strlen(fn) - 2] | 0x60;
|
||||
@@ -256,6 +283,8 @@ void img_load(int drive, char *fn)
|
||||
{
|
||||
/* Read the BPB */
|
||||
pclog("img_load(): File is a raw image...\n");
|
||||
fseek(img[drive].f, 0x00, SEEK_SET);
|
||||
first_byte = fgetc(img[drive].f);
|
||||
fseek(img[drive].f, 0x0B, SEEK_SET);
|
||||
fread(&bpb_bps, 1, 2, img[drive].f);
|
||||
fseek(img[drive].f, 0x13, SEEK_SET);
|
||||
@@ -281,7 +310,7 @@ void img_load(int drive, char *fn)
|
||||
|
||||
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)
|
||||
if (((bpb_sides < 1) || (bpb_sides > 2) || !bps_is_valid(bpb_bps) || !first_byte_is_valid(first_byte)) && !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. */
|
||||
|
||||
@@ -107,7 +107,7 @@ typedef struct
|
||||
uint8_t interleave_ordered_pos[256][2];
|
||||
} td0_t;
|
||||
|
||||
td0_t td0[2];
|
||||
td0_t td0[FDD_NUM];
|
||||
|
||||
|
||||
void floppy_image_read(int drive, char *buffer, uint32_t offset, uint32_t len)
|
||||
|
||||
450
src/dma.c
450
src/dma.c
@@ -86,7 +86,7 @@ void dma_write(uint16_t addr, uint8_t val, void *priv)
|
||||
dma.wp ^= 1;
|
||||
if (dma.wp) dma.ab[(addr >> 1) & 3] = (dma.ab[(addr >> 1) & 3] & 0xff00) | val;
|
||||
else dma.ab[(addr >> 1) & 3] = (dma.ab[(addr >> 1) & 3] & 0x00ff) | (val << 8);
|
||||
dma.ac[(addr >> 1) & 3] = dma.ab[(addr >> 1) & 3];
|
||||
dma.ac[(addr >> 1) & 3] = dma.ab[(addr >> 1) & 3] & 0xffff;
|
||||
dmaon[(addr >> 1) & 3] = 1;
|
||||
return;
|
||||
|
||||
@@ -94,7 +94,8 @@ void dma_write(uint16_t addr, uint8_t val, void *priv)
|
||||
dma.wp ^= 1;
|
||||
if (dma.wp) dma.cb[(addr >> 1) & 3] = (dma.cb[(addr >> 1) & 3] & 0xff00) | val;
|
||||
else dma.cb[(addr >> 1) & 3] = (dma.cb[(addr >> 1) & 3] & 0x00ff) | (val << 8);
|
||||
dma.cc[(addr >> 1) & 3] = dma.cb[(addr >> 1) & 3];
|
||||
dma.cc[(addr >> 1) & 3] = dma.cb[(addr >> 1) & 3] & 0xffff;
|
||||
// pclog("DMA count for channel %i now: %02X\n", (addr >> 1) & 3, dma.cc[(addr >> 1) & 3]);
|
||||
dmaon[(addr >> 1) & 3] = 1;
|
||||
return;
|
||||
|
||||
@@ -169,7 +170,7 @@ void dma16_write(uint16_t addr, uint8_t val, void *priv)
|
||||
dma16.wp ^= 1;
|
||||
if (dma16.wp) dma16.ab[(addr >> 1) & 3] = (dma16.ab[(addr >> 1) & 3] & 0xff00) | val;
|
||||
else dma16.ab[(addr >> 1) & 3] = (dma16.ab[(addr >> 1) & 3] & 0x00ff) | (val << 8);
|
||||
dma16.ac[(addr >> 1) & 3] = dma16.ab[(addr >> 1) & 3];
|
||||
dma16.ac[(addr >> 1) & 3] = dma16.ab[(addr >> 1) & 3] & 0xffff;
|
||||
dma16on[(addr >> 1) & 3] = 1;
|
||||
return;
|
||||
|
||||
@@ -177,7 +178,7 @@ void dma16_write(uint16_t addr, uint8_t val, void *priv)
|
||||
dma16.wp ^= 1;
|
||||
if (dma16.wp) dma16.cb[(addr >> 1) & 3] = (dma16.cb[(addr >> 1) & 3] & 0xff00) | val;
|
||||
else dma16.cb[(addr >> 1) & 3] = (dma16.cb[(addr >> 1) & 3] & 0x00ff) | (val << 8);
|
||||
dma16.cc[(addr >> 1) & 3] = dma16.cb[(addr >> 1) & 3];
|
||||
dma16.cc[(addr >> 1) & 3] = dma16.cb[(addr >> 1) & 3] & 0xffff;
|
||||
dma16on[(addr >> 1) & 3] = 1;
|
||||
return;
|
||||
|
||||
@@ -263,6 +264,24 @@ void dma16_init()
|
||||
io_sethandler(0x0088, 0x0008, dma_page_read, NULL, NULL, dma_page_write, NULL, NULL, NULL);
|
||||
}
|
||||
|
||||
void dma_alias_set()
|
||||
{
|
||||
io_sethandler(0x0090, 0x0010, dma_page_read, NULL, NULL, dma_page_write, NULL, NULL, NULL);
|
||||
}
|
||||
|
||||
void dma_alias_remove()
|
||||
{
|
||||
io_removehandler(0x0090, 0x0010, dma_page_read, NULL, NULL, dma_page_write, NULL, NULL, NULL);
|
||||
}
|
||||
|
||||
void dma_alias_remove_piix()
|
||||
{
|
||||
io_removehandler(0x0090, 0x0001, dma_page_read, NULL, NULL, dma_page_write, NULL, NULL, NULL);
|
||||
io_removehandler(0x0094, 0x0003, dma_page_read, NULL, NULL, dma_page_write, NULL, NULL, NULL);
|
||||
io_removehandler(0x0098, 0x0001, dma_page_read, NULL, NULL, dma_page_write, NULL, NULL, NULL);
|
||||
io_removehandler(0x009C, 0x0003, dma_page_read, NULL, NULL, dma_page_write, NULL, NULL, NULL);
|
||||
}
|
||||
|
||||
|
||||
uint8_t _dma_read(uint32_t addr)
|
||||
{
|
||||
@@ -286,184 +305,309 @@ void _dma_writew(uint32_t addr, uint16_t val)
|
||||
mem_invalidate_range(addr, addr + 1);
|
||||
}
|
||||
|
||||
int dma_is_masked(int channel)
|
||||
{
|
||||
if (channel < 4)
|
||||
{
|
||||
if (dma.m & (1 << channel))
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
if (AT)
|
||||
{
|
||||
if (dma16.m & 1)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
channel &= 3;
|
||||
if (dma16.m & (1 << channel))
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int dma_channel_mode(int channel)
|
||||
{
|
||||
if (channel < 4)
|
||||
{
|
||||
return (dma.mode[channel] & 0xC) >> 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
channel &= 3;
|
||||
return (dma16.mode[channel] & 0xC) >> 2;
|
||||
}
|
||||
}
|
||||
|
||||
DMA * get_dma_controller(int channel)
|
||||
{
|
||||
if (channel < 4)
|
||||
{
|
||||
return &dma;
|
||||
}
|
||||
else
|
||||
{
|
||||
return &dma16;
|
||||
}
|
||||
}
|
||||
|
||||
int dma_channel_read(int channel)
|
||||
{
|
||||
uint16_t temp;
|
||||
int tc = 0;
|
||||
|
||||
if (dma.command & 0x04)
|
||||
|
||||
int cmode = 0;
|
||||
int real_channel = channel & 3;
|
||||
|
||||
int mem_over = 0;
|
||||
|
||||
DMA *dma_controller;
|
||||
|
||||
cmode = dma_channel_mode(channel);
|
||||
|
||||
channel &= 7;
|
||||
|
||||
if ((channel >= 4) && !AT)
|
||||
{
|
||||
// pclog ("DMA read - channel is 4 or higher on a non-AT machine\n");
|
||||
return DMA_NODATA;
|
||||
|
||||
}
|
||||
|
||||
dma_controller = get_dma_controller(channel);
|
||||
|
||||
if (dma_controller->command & 0x04)
|
||||
{
|
||||
// pclog ("DMA read - channel bit 2 of control bit is set\n");
|
||||
return DMA_NODATA;
|
||||
}
|
||||
|
||||
if (!AT)
|
||||
refreshread();
|
||||
|
||||
if (channel < 4)
|
||||
{
|
||||
if (dma.m & (1 << channel))
|
||||
return DMA_NODATA;
|
||||
if ((dma.mode[channel] & 0xC) != 8)
|
||||
return DMA_NODATA;
|
||||
|
||||
temp = _dma_read(dma.ac[channel] + (dma.page[channel] << 16)); //ram[(dma.ac[2]+(dma.page[2]<<16))&rammask];
|
||||
|
||||
if (dma.mode[channel] & 0x20) dma.ac[channel]--;
|
||||
else dma.ac[channel]++;
|
||||
dma.cc[channel]--;
|
||||
if (dma.cc[channel] < 0)
|
||||
{
|
||||
tc = 1;
|
||||
if (dma.mode[channel] & 0x10) /*Auto-init*/
|
||||
{
|
||||
dma.cc[channel] = dma.cb[channel];
|
||||
dma.ac[channel] = dma.ab[channel];
|
||||
}
|
||||
else
|
||||
dma.m |= (1 << channel);
|
||||
dma.stat |= (1 << channel);
|
||||
}
|
||||
|
||||
if (tc)
|
||||
return temp | DMA_OVER;
|
||||
return temp;
|
||||
}
|
||||
else
|
||||
{
|
||||
channel &= 3;
|
||||
if ((dma16.m & (1 << channel)) || (dma16.m & 1))
|
||||
return DMA_NODATA;
|
||||
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]++;
|
||||
dma16.cc[channel]--;
|
||||
if (dma16.cc[channel] < 0)
|
||||
{
|
||||
tc = 1;
|
||||
if (dma16.mode[channel] & 0x10) /*Auto-init*/
|
||||
{
|
||||
dma16.cc[channel] = dma16.cb[channel];
|
||||
dma16.ac[channel] = dma16.ab[channel];
|
||||
}
|
||||
else
|
||||
{
|
||||
dma16.m |= (1 << channel);
|
||||
if (!channel)
|
||||
{
|
||||
dma16.m |= 0xf;
|
||||
}
|
||||
}
|
||||
dma16.stat |= (1 << channel);
|
||||
}
|
||||
|
||||
if (tc)
|
||||
return temp | DMA_OVER;
|
||||
return temp;
|
||||
}
|
||||
}
|
||||
|
||||
void dma_channel_dump()
|
||||
{
|
||||
int i = 0;
|
||||
FILE *f;
|
||||
f = fopen("dma.dmp", "wb");
|
||||
for (i = 0; i < (21 * 512); i++)
|
||||
if ((channel == 4) || dma_is_masked(channel))
|
||||
{
|
||||
fputc(mem_readb_phys((dma.page[2] << 16) + dma16.ac[2] + i), f);
|
||||
// pclog ("DMA read - channel is 4 or masked\n");
|
||||
return DMA_NODATA;
|
||||
}
|
||||
fclose(f);
|
||||
|
||||
if (cmode)
|
||||
{
|
||||
if (cmode != 2)
|
||||
{
|
||||
// pclog ("DMA read - transfer mode (%i) is 1 or 3\n", cmode);
|
||||
return DMA_NODATA;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (channel < 4)
|
||||
{
|
||||
temp = _dma_read(dma_controller->ac[real_channel] + (dma_controller->page[real_channel] << 16));
|
||||
}
|
||||
else
|
||||
{
|
||||
temp = _dma_readw((dma_controller->ac[real_channel] << 1) + ((dma_controller->page[real_channel] & ~1) << 16));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (dma_controller->mode[real_channel] & 0x20)
|
||||
{
|
||||
if (dma_controller->ac[real_channel] == 0)
|
||||
{
|
||||
mem_over = 1;
|
||||
}
|
||||
dma_controller->ac[real_channel]--;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (dma_controller->ac[real_channel] == 0xFFFF)
|
||||
{
|
||||
mem_over = 1;
|
||||
}
|
||||
dma_controller->ac[real_channel]++;
|
||||
}
|
||||
dma_controller->ac[real_channel] &= 0xffff;
|
||||
|
||||
dma_controller->cc[real_channel]--;
|
||||
if ((dma_controller->cc[real_channel] < 0) || mem_over)
|
||||
{
|
||||
tc = 1;
|
||||
if (dma_controller->mode[real_channel] & 0x10) /*Auto-init*/
|
||||
{
|
||||
// pclog("DMA read auto-init\n");
|
||||
dma_controller->cc[real_channel] = dma_controller->cb[real_channel] & 0xffff;
|
||||
dma_controller->ac[real_channel] = dma_controller->ab[real_channel] & 0xffff;
|
||||
}
|
||||
else
|
||||
{
|
||||
dma_controller->cc[real_channel] &= 0xffff;
|
||||
dma_controller->m |= (1 << real_channel);
|
||||
}
|
||||
dma_controller->stat |= (1 << real_channel);
|
||||
}
|
||||
|
||||
if (tc)
|
||||
{
|
||||
// pclog("DMA read over in transfer mode %i (value %04X)!\n", cmode, temp);
|
||||
return temp | DMA_OVER;
|
||||
}
|
||||
|
||||
// pclog("DMA read success (value %04X)\n", temp);
|
||||
return temp;
|
||||
}
|
||||
|
||||
int dma_channel_write(int channel, uint16_t val)
|
||||
{
|
||||
if (dma.command & 0x04)
|
||||
int tc = 0;
|
||||
|
||||
int cmode = 0;
|
||||
int real_channel = channel & 3;
|
||||
|
||||
int mem_over = 0;
|
||||
|
||||
DMA *dma_controller;
|
||||
|
||||
cmode = dma_channel_mode(channel);
|
||||
|
||||
channel &= 7;
|
||||
|
||||
if ((channel >= 4) && !AT)
|
||||
{
|
||||
// pclog ("DMA write - channel is 4 or higher on a non-AT machine\n");
|
||||
return DMA_NODATA;
|
||||
}
|
||||
|
||||
dma_controller = get_dma_controller(channel);
|
||||
|
||||
if (dma_controller->command & 0x04)
|
||||
{
|
||||
// pclog ("DMA write - channel bit 2 of control bit is set\n");
|
||||
return DMA_NODATA;
|
||||
}
|
||||
|
||||
if (!AT)
|
||||
refreshread();
|
||||
|
||||
if (channel < 4)
|
||||
{
|
||||
if (dma.m & (1 << channel))
|
||||
return DMA_NODATA;
|
||||
if ((dma.mode[channel] & 0xC) != 4)
|
||||
if ((channel == 4) || dma_is_masked(channel))
|
||||
{
|
||||
// pclog ("DMA write - channel is 4 or masked\n");
|
||||
return DMA_NODATA;
|
||||
}
|
||||
|
||||
if (cmode)
|
||||
{
|
||||
if (cmode != 1)
|
||||
{
|
||||
// pclog ("DMA write - transfer mode (%i) is 2 or 3\n", cmode);
|
||||
return DMA_NODATA;
|
||||
}
|
||||
|
||||
_dma_write(dma.ac[channel] + (dma.page[channel] << 16), val);
|
||||
if (channel < 4)
|
||||
{
|
||||
_dma_write(dma_controller->ac[real_channel] + (dma_controller->page[real_channel] << 16), val);
|
||||
}
|
||||
else
|
||||
{
|
||||
_dma_writew((dma_controller->ac[real_channel] << 1) + ((dma_controller->page[real_channel] & ~1) << 16), val);
|
||||
}
|
||||
}
|
||||
|
||||
if (dma.mode[channel]&0x20) dma.ac[channel]--;
|
||||
else dma.ac[channel]++;
|
||||
dma.cc[channel]--;
|
||||
if (dma.cc[channel] < 0)
|
||||
{
|
||||
if (dma.mode[channel] & 0x10) /*Auto-init*/
|
||||
{
|
||||
dma.cc[channel] = dma.cb[channel];
|
||||
dma.ac[channel] = dma.ab[channel];
|
||||
}
|
||||
else
|
||||
dma.m |= (1 << channel);
|
||||
dma.stat |= (1 << channel);
|
||||
}
|
||||
if (dma_controller->mode[real_channel] & 0x20)
|
||||
{
|
||||
if (dma_controller->ac[real_channel] == 0)
|
||||
{
|
||||
mem_over = 1;
|
||||
}
|
||||
dma_controller->ac[real_channel]--;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (dma_controller->ac[real_channel] == 0xFFFF)
|
||||
{
|
||||
mem_over = 1;
|
||||
}
|
||||
dma_controller->ac[real_channel]++;
|
||||
}
|
||||
dma_controller->ac[real_channel] &= 0xffff;
|
||||
|
||||
if (dma.m & (1 << channel))
|
||||
return DMA_OVER;
|
||||
}
|
||||
else
|
||||
{
|
||||
channel &= 3;
|
||||
if ((dma16.m & (1 << channel)) || (dma16.m & 1))
|
||||
return DMA_NODATA;
|
||||
if ((dma16.mode[channel] & 0xC) != 4)
|
||||
return DMA_NODATA;
|
||||
dma_controller->cc[real_channel]--;
|
||||
if ((dma_controller->cc[real_channel] < 0) || mem_over)
|
||||
{
|
||||
tc = 1;
|
||||
if (dma_controller->mode[real_channel] & 0x10) /*Auto-init*/
|
||||
{
|
||||
// pclog("DMA write auto-init\n");
|
||||
dma_controller->cc[real_channel] = dma_controller->cb[real_channel] & 0xffff;
|
||||
dma_controller->ac[real_channel] = dma_controller->ab[real_channel] & 0xffff;
|
||||
}
|
||||
else
|
||||
{
|
||||
dma_controller->cc[real_channel] &= 0xffff;
|
||||
dma_controller->m |= (1 << real_channel);
|
||||
}
|
||||
dma_controller->stat |= (1 << real_channel);
|
||||
}
|
||||
|
||||
#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
|
||||
// if (dma_is_masked(channel))
|
||||
if (tc)
|
||||
{
|
||||
// pclog("DMA write over in transfer mode %i (value %04X)\n", cmode, val);
|
||||
return DMA_OVER;
|
||||
}
|
||||
|
||||
_dma_writew((dma16.ac[channel] << 1) + ((dma16.page[channel] & ~1) << 16), val);
|
||||
|
||||
if (dma16.mode[channel]&0x20) dma16.ac[channel]--;
|
||||
else dma16.ac[channel]++;
|
||||
dma16.cc[channel]--;
|
||||
if (dma16.cc[channel] < 0)
|
||||
{
|
||||
if (dma16.mode[channel] & 0x10) /*Auto-init*/
|
||||
{
|
||||
dma16.cc[channel] = dma16.cb[channel] + 1;
|
||||
dma16.ac[channel] = dma16.ab[channel];
|
||||
}
|
||||
dma16.m |= (1 << channel);
|
||||
if (!channel)
|
||||
{
|
||||
dma16.m |= 0xf;
|
||||
}
|
||||
dma16.stat |= (1 << channel);
|
||||
}
|
||||
|
||||
if ((dma.m & (1 << channel)) || (dma.m & 1))
|
||||
return DMA_OVER;
|
||||
}
|
||||
return 0;
|
||||
// pclog("DMA write success (value %04X)\n", val);
|
||||
return 0;
|
||||
}
|
||||
|
||||
size_t PageLengthReadWrite(uint32_t Address, size_t TotalSize)
|
||||
static size_t PageLengthReadWrite(uint32_t PhysAddress, size_t TotalSize)
|
||||
{
|
||||
size_t l;
|
||||
size_t LengthSize;
|
||||
uint32_t Page;
|
||||
|
||||
Page = Address & 4095;
|
||||
l = (Page + 4096) - Address;
|
||||
if (l > TotalSize)
|
||||
l = TotalSize;
|
||||
Page = PhysAddress & 4095;
|
||||
LengthSize = (Page + 4096) - PhysAddress;
|
||||
if (LengthSize > TotalSize)
|
||||
LengthSize = TotalSize;
|
||||
|
||||
return l;
|
||||
return LengthSize;
|
||||
}
|
||||
|
||||
//DMA Bus Master Page Read/Write
|
||||
void DMAPageRead(uint32_t PhysAddress, void *DataRead, size_t TotalSize)
|
||||
{
|
||||
uint32_t PageLen = PageLengthReadWrite(PhysAddress, TotalSize);
|
||||
memcpy(DataRead, &ram[PhysAddress], PageLen);
|
||||
DataRead -= PageLen;
|
||||
PageLen -= TotalSize;
|
||||
}
|
||||
|
||||
void DMAPageWrite(uint32_t PhysAddress, const void *DataWrite, size_t TotalSize)
|
||||
{
|
||||
uint32_t PageLen = PageLengthReadWrite(PhysAddress, TotalSize);
|
||||
memcpy(&ram[PhysAddress], DataWrite, PageLen);
|
||||
DataWrite -= PageLen;
|
||||
PageLen -= TotalSize;
|
||||
}
|
||||
|
||||
int dma_mode(int channel)
|
||||
{
|
||||
if (channel < 4)
|
||||
{
|
||||
return dma.mode[channel];
|
||||
}
|
||||
else
|
||||
{
|
||||
return dma16.mode[channel & 3];
|
||||
}
|
||||
}
|
||||
|
||||
/* void dma_c2_mode()
|
||||
{
|
||||
printf("DMA Channel 2 mode: %02X\n", dma.mode[2]);
|
||||
} */
|
||||
|
||||
@@ -7,6 +7,7 @@ void dma_reset();
|
||||
|
||||
#define DMA_NODATA -1
|
||||
#define DMA_OVER 0x10000
|
||||
#define DMA_VERIFY 0x20000
|
||||
|
||||
void readdma0();
|
||||
int readdma1();
|
||||
@@ -18,4 +19,5 @@ void writedma2(uint8_t temp);
|
||||
int dma_channel_read(int channel);
|
||||
int dma_channel_write(int channel, uint16_t val);
|
||||
|
||||
size_t PageLengthReadWrite(uint32_t Address, size_t TotalSize);
|
||||
void DMAPageRead(uint32_t PhysAddress, void *DataRead, size_t TotalSize);
|
||||
void DMAPageWrite(uint32_t PhysAddress, const void *DataWrite, size_t TotalSize);
|
||||
@@ -1,7 +1,5 @@
|
||||
/* Authors: Andrew Jenner
|
||||
Extra contributors: Tenshi
|
||||
Distributed as is with the Unlicense (PD), see "UNLICENSE"
|
||||
*/
|
||||
/* Code borrowed from DOSBox and adapted by OBattler.
|
||||
Original author: reenigne. */
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
@@ -69,38 +67,30 @@ static Bit8u byte_clamp_other(int v) { return v < 0 ? 0 : (v > 255 ? 255 : v); }
|
||||
|
||||
FILE *df;
|
||||
|
||||
void update_cga16_color(cga_t *cga) {
|
||||
void update_cga16_color(uint8_t cgamode) {
|
||||
int x;
|
||||
Bit32u x2;
|
||||
double i0, i3, mode_saturation, c, i, v, r, g, b, q, a, s, iq_adjust_i, iq_adjust_q;
|
||||
|
||||
static const double ri = 0.9563;
|
||||
static const double rq = 0.6210;
|
||||
static const double gi = -0.2721;
|
||||
static const double gq = -0.6474;
|
||||
static const double bi = -1.1069;
|
||||
static const double bq = 1.7046;
|
||||
|
||||
if (!new_cga) {
|
||||
min_v = chroma_multiplexer[0] + intensity[0];
|
||||
max_v = chroma_multiplexer[255] + intensity[3];
|
||||
}
|
||||
else {
|
||||
i0 = intensity[0];
|
||||
i3 = intensity[3];
|
||||
double i0 = intensity[0];
|
||||
double i3 = intensity[3];
|
||||
min_v = NEW_CGA(chroma_multiplexer[0], i0, i0, i0, i0);
|
||||
max_v = NEW_CGA(chroma_multiplexer[255], i3, i3, i3, i3);
|
||||
}
|
||||
mode_contrast = 256/(max_v - min_v);
|
||||
mode_brightness = -min_v*mode_contrast;
|
||||
if ((cga->cgamode & 3) == 1)
|
||||
if ((cgamode & 3) == 1)
|
||||
mode_hue = 14;
|
||||
else
|
||||
mode_hue = 4;
|
||||
|
||||
mode_contrast *= contrast * (new_cga ? 1.2 : 1)/100; // new CGA: 120%
|
||||
mode_brightness += (new_cga ? brightness-10 : brightness)*5; // new CGA: -10
|
||||
mode_saturation = (new_cga ? 4.35 : 2.9)*saturation/100; // new CGA: 150%
|
||||
double mode_saturation = (new_cga ? 4.35 : 2.9)*saturation/100; // new CGA: 150%
|
||||
|
||||
for (x = 0; x < 1024; ++x) {
|
||||
int phase = x & 3;
|
||||
@@ -108,33 +98,42 @@ void update_cga16_color(cga_t *cga) {
|
||||
int left = (x >> 6) & 15;
|
||||
int rc = right;
|
||||
int lc = left;
|
||||
if ((cga->cgamode & 4) != 0) {
|
||||
if ((cgamode & 4) != 0) {
|
||||
rc = (right & 8) | ((right & 7) != 0 ? 7 : 0);
|
||||
lc = (left & 8) | ((left & 7) != 0 ? 7 : 0);
|
||||
}
|
||||
c = chroma_multiplexer[((lc & 7) << 5) | ((rc & 7) << 2) | phase];
|
||||
i = intensity[(left >> 3) | ((right >> 2) & 2)];
|
||||
double c =
|
||||
chroma_multiplexer[((lc & 7) << 5) | ((rc & 7) << 2) | phase];
|
||||
double i = intensity[(left >> 3) | ((right >> 2) & 2)];
|
||||
double v;
|
||||
if (!new_cga)
|
||||
v = c + i;
|
||||
else {
|
||||
r = intensity[((left >> 2) & 1) | ((right >> 1) & 2)];
|
||||
g = intensity[((left >> 1) & 1) | (right & 2)];
|
||||
b = intensity[(left & 1) | ((right << 1) & 2)];
|
||||
double r = intensity[((left >> 2) & 1) | ((right >> 1) & 2)];
|
||||
double g = intensity[((left >> 1) & 1) | (right & 2)];
|
||||
double b = intensity[(left & 1) | ((right << 1) & 2)];
|
||||
v = NEW_CGA(c, i, r, g, b);
|
||||
}
|
||||
CGA_Composite_Table[x] = (int) (v*mode_contrast + mode_brightness);
|
||||
}
|
||||
|
||||
i = CGA_Composite_Table[6*68] - CGA_Composite_Table[6*68 + 2];
|
||||
q = CGA_Composite_Table[6*68 + 1] - CGA_Composite_Table[6*68 + 3];
|
||||
double i = CGA_Composite_Table[6*68] - CGA_Composite_Table[6*68 + 2];
|
||||
double q = CGA_Composite_Table[6*68 + 1] - CGA_Composite_Table[6*68 + 3];
|
||||
|
||||
a = tau*(33 + 90 + hue_offset + mode_hue)/360.0;
|
||||
c = cos(a);
|
||||
s = sin(a);
|
||||
r = 256*mode_saturation/sqrt(i*i+q*q);
|
||||
double a = tau*(33 + 90 + hue_offset + mode_hue)/360.0;
|
||||
double c = cos(a);
|
||||
double s = sin(a);
|
||||
double r = 256*mode_saturation/sqrt(i*i+q*q);
|
||||
|
||||
iq_adjust_i = -(i*c + q*s)*r;
|
||||
iq_adjust_q = (q*c - i*s)*r;
|
||||
double iq_adjust_i = -(i*c + q*s)*r;
|
||||
double iq_adjust_q = (q*c - i*s)*r;
|
||||
|
||||
static const double ri = 0.9563;
|
||||
static const double rq = 0.6210;
|
||||
static const double gi = -0.2721;
|
||||
static const double gq = -0.6474;
|
||||
static const double bi = -1.1069;
|
||||
static const double bq = 1.7046;
|
||||
|
||||
video_ri = (int) (ri*iq_adjust_i + rq*iq_adjust_q);
|
||||
video_rq = (int) (-ri*iq_adjust_q + rq*iq_adjust_i);
|
||||
@@ -157,7 +156,7 @@ static int temp[SCALER_MAXWIDTH + 10]={0};
|
||||
static int atemp[SCALER_MAXWIDTH + 2]={0};
|
||||
static int btemp[SCALER_MAXWIDTH + 2]={0};
|
||||
|
||||
Bit8u * Composite_Process(cga_t *cga, Bit8u border, Bit32u blocks/*, bool doublewidth*/, Bit8u *TempLine)
|
||||
Bit8u * Composite_Process(uint8_t cgamode, Bit8u border, Bit32u blocks/*, bool doublewidth*/, Bit8u *TempLine)
|
||||
{
|
||||
int x;
|
||||
Bit32u x2;
|
||||
@@ -187,8 +186,6 @@ Bit8u * Composite_Process(cga_t *cga, Bit8u border, Bit32u blocks/*, bool double
|
||||
int* o = temp;
|
||||
Bit8u* rgbi = TempLine;
|
||||
int* b = &CGA_Composite_Table[border*68];
|
||||
int *i, *ap, *bp;
|
||||
Bit32u* srgb;
|
||||
for (x = 0; x < 4; ++x)
|
||||
OUT(b[(x+3)&3]);
|
||||
OUT(CGA_Composite_Table[(border<<6) | ((*rgbi)<<2) | 3]);
|
||||
@@ -200,10 +197,10 @@ Bit8u * Composite_Process(cga_t *cga, Bit8u border, Bit32u blocks/*, bool double
|
||||
for (x = 0; x < 5; ++x)
|
||||
OUT(b[x&3]);
|
||||
|
||||
if ((cga->cgamode & 4) != 0) {
|
||||
if ((cgamode & 4) != 0) {
|
||||
// Decode
|
||||
i = temp + 5;
|
||||
srgb = (Bit32u *)TempLine;
|
||||
int* i = temp + 5;
|
||||
Bit32u* srgb = (Bit32u *)TempLine;
|
||||
for (x2 = 0; x2 < blocks*4; ++x2) {
|
||||
int c = (i[0]+i[0])<<3;
|
||||
int d = (i[-1]+i[1])<<3;
|
||||
@@ -215,9 +212,9 @@ Bit8u * Composite_Process(cga_t *cga, Bit8u border, Bit32u blocks/*, bool double
|
||||
}
|
||||
else {
|
||||
// Store chroma
|
||||
i = temp + 4;
|
||||
ap = atemp + 1;
|
||||
bp = btemp + 1;
|
||||
int* i = temp + 4;
|
||||
int* ap = atemp + 1;
|
||||
int* bp = btemp + 1;
|
||||
for (x = -1; x < w + 1; ++x) {
|
||||
ap[x] = i[-4]-((i[-2]-i[0]+i[2])<<1)+i[4];
|
||||
bp[x] = (i[-3]-i[-1]+i[1]-i[3])<<1;
|
||||
@@ -228,7 +225,7 @@ Bit8u * Composite_Process(cga_t *cga, Bit8u border, Bit32u blocks/*, bool double
|
||||
i = temp + 5;
|
||||
i[-1] = (i[-1]<<3) - ap[-1];
|
||||
i[0] = (i[0]<<3) - ap[0];
|
||||
srgb = (Bit32u *)TempLine;
|
||||
Bit32u* srgb = (Bit32u *)TempLine;
|
||||
for (x2 = 0; x2 < blocks; ++x2) {
|
||||
int y,a,b,c,d,rr,gg,bb;
|
||||
COMPOSITE_CONVERT(a, b);
|
||||
@@ -243,79 +240,79 @@ Bit8u * Composite_Process(cga_t *cga, Bit8u border, Bit32u blocks/*, bool double
|
||||
return TempLine;
|
||||
}
|
||||
|
||||
void IncreaseHue(cga_t *cga)
|
||||
void IncreaseHue(uint8_t cgamode)
|
||||
{
|
||||
hue_offset += 5.0;
|
||||
|
||||
update_cga16_color(cga);
|
||||
update_cga16_color(cgamode);
|
||||
}
|
||||
|
||||
void DecreaseHue(cga_t *cga)
|
||||
void DecreaseHue(uint8_t cgamode)
|
||||
{
|
||||
hue_offset -= 5.0;
|
||||
|
||||
update_cga16_color(cga);
|
||||
update_cga16_color(cgamode);
|
||||
}
|
||||
|
||||
void IncreaseSaturation(cga_t *cga)
|
||||
void IncreaseSaturation(uint8_t cgamode)
|
||||
{
|
||||
saturation += 5;
|
||||
|
||||
update_cga16_color(cga);
|
||||
update_cga16_color(cgamode);
|
||||
}
|
||||
|
||||
void DecreaseSaturation(cga_t *cga)
|
||||
void DecreaseSaturation(uint8_t cgamode)
|
||||
{
|
||||
saturation -= 5;
|
||||
|
||||
update_cga16_color(cga);
|
||||
update_cga16_color(cgamode);
|
||||
}
|
||||
|
||||
void IncreaseContrast(cga_t *cga)
|
||||
void IncreaseContrast(uint8_t cgamode)
|
||||
{
|
||||
contrast += 5;
|
||||
|
||||
update_cga16_color(cga);
|
||||
update_cga16_color(cgamode);
|
||||
}
|
||||
|
||||
void DecreaseContrast(cga_t *cga)
|
||||
void DecreaseContrast(uint8_t cgamode)
|
||||
{
|
||||
contrast -= 5;
|
||||
|
||||
update_cga16_color(cga);
|
||||
update_cga16_color(cgamode);
|
||||
}
|
||||
|
||||
void IncreaseBrightness(cga_t *cga)
|
||||
void IncreaseBrightness(uint8_t cgamode)
|
||||
{
|
||||
brightness += 5;
|
||||
|
||||
update_cga16_color(cga);
|
||||
update_cga16_color(cgamode);
|
||||
}
|
||||
|
||||
void DecreaseBrightness(cga_t *cga)
|
||||
void DecreaseBrightness(uint8_t cgamode)
|
||||
{
|
||||
brightness -= 5;
|
||||
|
||||
update_cga16_color(cga);
|
||||
update_cga16_color(cgamode);
|
||||
}
|
||||
|
||||
void IncreaseSharpness(cga_t *cga)
|
||||
void IncreaseSharpness(uint8_t cgamode)
|
||||
{
|
||||
sharpness += 10;
|
||||
|
||||
update_cga16_color(cga);
|
||||
update_cga16_color(cgamode);
|
||||
}
|
||||
|
||||
void DecreaseSharpness(cga_t *cga)
|
||||
void DecreaseSharpness(uint8_t cgamode)
|
||||
{
|
||||
sharpness -= 10;
|
||||
|
||||
update_cga16_color(cga);
|
||||
update_cga16_color(cgamode);
|
||||
}
|
||||
|
||||
void cga_comp_init(cga_t *cga)
|
||||
void cga_comp_init(int revision)
|
||||
{
|
||||
new_cga = cga->revision;
|
||||
new_cga = revision;
|
||||
|
||||
/* Making sure this gets reset after reset. */
|
||||
brightness = 0;
|
||||
@@ -324,5 +321,5 @@ void cga_comp_init(cga_t *cga)
|
||||
sharpness = 0;
|
||||
hue_offset = 0;
|
||||
|
||||
update_cga16_color(cga);
|
||||
update_cga16_color(0);
|
||||
}
|
||||
|
||||
@@ -1,12 +1,8 @@
|
||||
/* Authors: Andrew Jenner
|
||||
Extra contributors: Tenshi
|
||||
Distributed as is with the Unlicense (PD), see "UNLICENSE"
|
||||
*/
|
||||
#define Bit8u uint8_t
|
||||
#define Bit32u uint32_t
|
||||
#define Bitu unsigned int
|
||||
#define bool uint8_t
|
||||
|
||||
void update_cga16_color(cga_t *cga);
|
||||
void cga_comp_init(cga_t *cga);
|
||||
Bit8u * Composite_Process(cga_t *cga, Bit8u border, Bit32u blocks/*, bool doublewidth*/, Bit8u *TempLine);
|
||||
void update_cga16_color(uint8_t cgamode);
|
||||
void cga_comp_init(int revision);
|
||||
Bit8u * Composite_Process(uint8_t cgamode, Bit8u border, Bit32u blocks/*, bool doublewidth*/, Bit8u *TempLine);
|
||||
|
||||
@@ -31,6 +31,13 @@ void fdc_update_densel_force(int densel_force);
|
||||
void fdc_update_drvrate(int drive, int drvrate);
|
||||
void fdc_update_drv2en(int drv2en);
|
||||
|
||||
void fdc_noidam();
|
||||
void fdc_nosector();
|
||||
void fdc_nodataam();
|
||||
void fdc_cannotformat();
|
||||
void fdc_wrongcylinder();
|
||||
void fdc_badcylinder();
|
||||
|
||||
sector_id_t fdc_get_read_track_sector();
|
||||
int fdc_get_compare_condition();
|
||||
int fdc_is_deleted();
|
||||
@@ -55,3 +62,5 @@ void fdc_sector_finishcompare(int satisfying);
|
||||
void fdc_sector_finishread();
|
||||
void fdc_track_finishread(int condition);
|
||||
int fdc_is_verify();
|
||||
|
||||
int real_drive(int drive);
|
||||
|
||||
@@ -28,7 +28,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)
|
||||
@@ -130,7 +130,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)
|
||||
|
||||
@@ -14,7 +14,6 @@
|
||||
#include "ide.h"
|
||||
#include "io.h"
|
||||
#include "lpt.h"
|
||||
#include "mouse_serial.h"
|
||||
#include "serial.h"
|
||||
#include "fdc37c932fr.h"
|
||||
|
||||
@@ -245,6 +244,8 @@ process_value:
|
||||
if (valxor & 0xC) fdc_update_densel_force((val & 0xC) >> 2);
|
||||
break;
|
||||
case 0xF2:
|
||||
if (valxor & 0xC0) fdc_update_rwc(3, (valxor & 0xC0) >> 6);
|
||||
if (valxor & 0x30) fdc_update_rwc(2, (valxor & 0x30) >> 4);
|
||||
if (valxor & 0x0C) fdc_update_rwc(1, (valxor & 0x0C) >> 2);
|
||||
if (valxor & 0x03) fdc_update_rwc(0, (valxor & 0x03));
|
||||
break;
|
||||
@@ -254,6 +255,12 @@ process_value:
|
||||
case 0xF5:
|
||||
if (valxor & 0x18) fdc_update_drvrate(1, (val & 0x18) >> 3);
|
||||
break;
|
||||
case 0xF6:
|
||||
if (valxor & 0x18) fdc_update_drvrate(2, (val & 0x18) >> 3);
|
||||
break;
|
||||
case 0xF7:
|
||||
if (valxor & 0x18) fdc_update_drvrate(3, (val & 0x18) >> 3);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
@@ -471,8 +478,12 @@ void fdc37c932fr_init()
|
||||
fdd_swap = 0;
|
||||
fdc_update_rwc(0, 0);
|
||||
fdc_update_rwc(1, 0);
|
||||
fdc_update_rwc(2, 0);
|
||||
fdc_update_rwc(3, 0);
|
||||
fdc_update_drvrate(0, 0);
|
||||
fdc_update_drvrate(1, 0);
|
||||
fdc_update_drvrate(2, 0);
|
||||
fdc_update_drvrate(3, 0);
|
||||
fdc_update_max_track(79);
|
||||
io_sethandler(0xe0, 0x0006, fdc37c932fr_gpio_read, NULL, NULL, fdc37c932fr_gpio_write, NULL, NULL, NULL);
|
||||
io_sethandler(0xea, 0x0002, fdc37c932fr_gpio_read, NULL, NULL, fdc37c932fr_gpio_write, NULL, NULL, NULL);
|
||||
|
||||
73
src/fdd.c
73
src/fdd.c
@@ -15,7 +15,7 @@ static struct
|
||||
int densel;
|
||||
|
||||
int head;
|
||||
} fdd[2];
|
||||
} fdd[FDD_NUM];
|
||||
|
||||
/* Flags:
|
||||
Bit 0: 300 rpm supported;
|
||||
@@ -25,6 +25,9 @@ static struct
|
||||
Bit 4: high density supported;
|
||||
Bit 5: extended density supported;
|
||||
Bit 6: double step for 40-track media;
|
||||
Bit 7: invert DENSEL polarity;
|
||||
Bit 8: ignore DENSEL;
|
||||
Bit 9: drive is a PS/2 drive;
|
||||
*/
|
||||
#define FLAG_RPM_300 1
|
||||
#define FLAG_RPM_360 2
|
||||
@@ -33,6 +36,9 @@ static struct
|
||||
#define FLAG_HOLE1 16
|
||||
#define FLAG_HOLE2 32
|
||||
#define FLAG_DOUBLE_STEP 64
|
||||
#define FLAG_INVERT_DENSEL 128
|
||||
#define FLAG_IGNORE_DENSEL 256
|
||||
#define FLAG_PS2 512
|
||||
|
||||
static struct
|
||||
{
|
||||
@@ -60,10 +66,18 @@ static struct
|
||||
.max_track = 86,
|
||||
.flags = FLAG_RPM_300 | FLAG_HOLE0 | FLAG_DOUBLE_STEP
|
||||
},
|
||||
{ /*3.5" HD PS/2*/
|
||||
.max_track = 86,
|
||||
.flags = FLAG_RPM_300 | FLAG_HOLE0 | FLAG_HOLE1 | FLAG_DOUBLE_STEP | FLAG_INVERT_DENSEL | FLAG_PS2
|
||||
},
|
||||
{ /*3.5" HD*/
|
||||
.max_track = 86,
|
||||
.flags = FLAG_RPM_300 | FLAG_HOLE0 | FLAG_HOLE1 | FLAG_DOUBLE_STEP
|
||||
},
|
||||
{ /*3.5" HD PC-98*/
|
||||
.max_track = 86,
|
||||
.flags = FLAG_RPM_300 | FLAG_RPM_360 | FLAG_HOLE0 | FLAG_HOLE1 | FLAG_DOUBLE_STEP | FLAG_INVERT_DENSEL
|
||||
},
|
||||
{ /*3.5" HD 3-Mode*/
|
||||
.max_track = 86,
|
||||
.flags = FLAG_RPM_300 | FLAG_RPM_360 | FLAG_HOLE0 | FLAG_HOLE1 | FLAG_DOUBLE_STEP
|
||||
@@ -78,7 +92,7 @@ int fdd_swap = 0;
|
||||
|
||||
void fdd_forced_seek(int drive, int track_diff)
|
||||
{
|
||||
drive ^= fdd_swap;
|
||||
drive = real_drive(drive);
|
||||
|
||||
fdd[drive].track += track_diff;
|
||||
|
||||
@@ -96,7 +110,7 @@ void fdd_forced_seek(int drive, int track_diff)
|
||||
|
||||
void fdd_seek(int drive, int track_diff)
|
||||
{
|
||||
drive ^= fdd_swap;
|
||||
drive = real_drive(drive);
|
||||
|
||||
if (!track_diff)
|
||||
{
|
||||
@@ -121,7 +135,7 @@ void fdd_seek(int drive, int track_diff)
|
||||
|
||||
int fdd_track0(int drive)
|
||||
{
|
||||
drive ^= fdd_swap;
|
||||
drive = real_drive(drive);
|
||||
|
||||
/* If drive is disabled, TRK0 never gets set. */
|
||||
if (!drive_types[fdd[drive].type].max_track) return 0;
|
||||
@@ -131,29 +145,49 @@ int fdd_track0(int drive)
|
||||
|
||||
void fdd_set_densel(int densel)
|
||||
{
|
||||
fdd[0].densel = densel;
|
||||
fdd[1].densel = densel;
|
||||
int i = 0;
|
||||
|
||||
for (i = 0; i < 4; i++)
|
||||
{
|
||||
if (drive_types[fdd[i].type].flags & FLAG_INVERT_DENSEL)
|
||||
{
|
||||
fdd[i].densel = densel ^ 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
fdd[i].densel = densel;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int fdd_getrpm(int drive)
|
||||
{
|
||||
int hole = disc_hole(drive);
|
||||
|
||||
drive ^= fdd_swap;
|
||||
int densel = 0;
|
||||
|
||||
drive = real_drive(drive);
|
||||
|
||||
densel = fdd[drive].densel;
|
||||
|
||||
if (drive_types[fdd[drive].type].flags & FLAG_INVERT_DENSEL)
|
||||
{
|
||||
densel ^= 1;
|
||||
}
|
||||
|
||||
if (!(drive_types[fdd[drive].type].flags & FLAG_RPM_360)) return 300;
|
||||
if (!(drive_types[fdd[drive].type].flags & FLAG_RPM_300)) return 360;
|
||||
|
||||
if (drive_types[fdd[drive].type].flags & FLAG_525)
|
||||
{
|
||||
return fdd[drive].densel ? 360 : 300;
|
||||
return densel ? 360 : 300;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* disc_hole(drive) returns 0 for double density media, 1 for high density, and 2 for extended density. */
|
||||
if (hole == 1)
|
||||
{
|
||||
return fdd[drive].densel ? 300 : 360;
|
||||
return densel ? 300 : 360;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -171,7 +205,7 @@ int fdd_can_read_medium(int drive)
|
||||
{
|
||||
int hole = disc_hole(drive);
|
||||
|
||||
drive ^= fdd_swap;
|
||||
drive = real_drive(drive);
|
||||
|
||||
hole = 1 << (hole + 3);
|
||||
|
||||
@@ -186,7 +220,12 @@ int fdd_doublestep_40(int drive)
|
||||
|
||||
void fdd_set_type(int drive, int type)
|
||||
{
|
||||
int old_type = fdd[drive].type;
|
||||
fdd[drive].type = type;
|
||||
if ((drive_types[old_type].flags ^ drive_types[type].flags) & FLAG_INVERT_DENSEL)
|
||||
{
|
||||
fdd[drive].densel ^= 1;
|
||||
}
|
||||
}
|
||||
|
||||
int fdd_get_type(int drive)
|
||||
@@ -211,7 +250,7 @@ int fdd_is_ed(int drive)
|
||||
|
||||
void fdd_set_head(int drive, int head)
|
||||
{
|
||||
drive ^= fdd_swap;
|
||||
drive = real_drive(drive);
|
||||
fdd[drive].head = head;
|
||||
}
|
||||
|
||||
@@ -220,6 +259,18 @@ int fdd_get_head(int drive)
|
||||
return fdd[drive].head;
|
||||
}
|
||||
|
||||
int fdd_get_densel(int drive)
|
||||
{
|
||||
if (drive_types[fdd[drive].type].flags & FLAG_INVERT_DENSEL)
|
||||
{
|
||||
return fdd[drive].densel ^ 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
return fdd[drive].densel;
|
||||
}
|
||||
}
|
||||
|
||||
void fdd_init()
|
||||
{
|
||||
}
|
||||
|
||||
@@ -197,9 +197,12 @@ void gameport_update_joystick_type()
|
||||
{
|
||||
gameport_t *gameport = gameport_global;
|
||||
|
||||
gameport->joystick->close(gameport->joystick_dat);
|
||||
gameport->joystick = joystick_list[joystick_type];
|
||||
gameport->joystick_dat = gameport->joystick->init();
|
||||
if (gameport)
|
||||
{
|
||||
gameport->joystick->close(gameport->joystick_dat);
|
||||
gameport->joystick = joystick_list[joystick_type];
|
||||
gameport->joystick_dat = gameport->joystick->init();
|
||||
}
|
||||
}
|
||||
|
||||
void *gameport_init()
|
||||
|
||||
81
src/ibm.h
81
src/ibm.h
@@ -7,7 +7,7 @@
|
||||
#define printf pclog
|
||||
|
||||
/*Memory*/
|
||||
uint8_t *ram,*vram;
|
||||
uint8_t *ram;
|
||||
|
||||
uint32_t rammask;
|
||||
|
||||
@@ -60,10 +60,8 @@ void outl(uint16_t port, uint32_t val);
|
||||
|
||||
FILE *romfopen(char *fn, char *mode);
|
||||
extern int shadowbios,shadowbios_write;
|
||||
extern int cache;
|
||||
extern int mem_size;
|
||||
extern int readlnum,writelnum;
|
||||
extern int memwaitstate;
|
||||
|
||||
|
||||
/*Processor*/
|
||||
@@ -182,8 +180,7 @@ COMPILE_TIME_ASSERT(sizeof(cpu_state) <= 128);
|
||||
/*x86reg regs[8];*/
|
||||
|
||||
uint16_t flags,eflags;
|
||||
uint32_t /*cs,ds,es,ss,*/oldds,oldss,olddslimit,oldsslimit,olddslimitw,oldsslimitw;
|
||||
//uint16_t msw;
|
||||
uint32_t oldds,oldss,olddslimit,oldsslimit,olddslimitw,oldsslimitw;
|
||||
|
||||
extern int ins,output;
|
||||
extern int cycdiff;
|
||||
@@ -198,7 +195,6 @@ uint8_t *pccache2;
|
||||
_cs,_ds,_es,_ss are the segment structures
|
||||
CS,DS,ES,SS is the 16-bit data
|
||||
cs,ds,es,ss are defines to the bases*/
|
||||
//uint16_t CS,DS,ES,SS;
|
||||
#define CS _cs.seg
|
||||
#define DS _ds.seg
|
||||
#define ES _es.seg
|
||||
@@ -252,6 +248,7 @@ uint32_t dr[8];
|
||||
extern int cycles_lost;
|
||||
extern int israpidcad;
|
||||
extern int is486;
|
||||
extern int is_pentium;
|
||||
extern uint8_t opcode;
|
||||
extern int insc;
|
||||
extern int fpucount;
|
||||
@@ -291,7 +288,6 @@ typedef struct PIT
|
||||
|
||||
PIT pit;
|
||||
void setpitclock(float clock);
|
||||
int pitcount;
|
||||
|
||||
float pit_timer0_freq();
|
||||
|
||||
@@ -325,7 +321,6 @@ typedef struct PPI
|
||||
} PPI;
|
||||
|
||||
PPI ppi;
|
||||
extern int key_inhibit;
|
||||
|
||||
|
||||
/*PIC*/
|
||||
@@ -339,17 +334,16 @@ typedef struct PIC
|
||||
|
||||
PIC pic,pic2;
|
||||
extern int pic_intpending;
|
||||
int intcount;
|
||||
|
||||
|
||||
int disctime;
|
||||
char discfns[2][256];
|
||||
int driveempty[2];
|
||||
char discfns[4][256];
|
||||
int driveempty[4];
|
||||
|
||||
#define MDA ((gfxcard==GFX_MDA || gfxcard==GFX_HERCULES || gfxcard==GFX_INCOLOR) && (romset<ROM_TANDY || romset>=ROM_IBMAT))
|
||||
#define VGA ((gfxcard>=GFX_TVGA || romset==ROM_ACER386) && gfxcard!=GFX_COLORPLUS && gfxcard!=GFX_INCOLOR && gfxcard!=GFX_COMPAQ_EGA && gfxcard!=GFX_SUPER_EGA && romset!=ROM_PC1640 && romset!=ROM_PC1512 && romset!=ROM_TANDY && romset!=ROM_PC200)
|
||||
#define MDA ((gfxcard==GFX_MDA || gfxcard==GFX_HERCULES || gfxcard==GFX_HERCULESPLUS || gfxcard==GFX_INCOLOR) && (romset<ROM_TANDY || romset>=ROM_IBMAT))
|
||||
#define VGA ((gfxcard>=GFX_TVGA || romset==ROM_ACER386) && gfxcard!=GFX_COLORPLUS && gfxcard!=GFX_INCOLOR && gfxcard!=GFX_WY700 && gfxcard!=GFX_COMPAQ_EGA && gfxcard!=GFX_SUPER_EGA && gfxcard!=GFX_HERCULESPLUS && romset!=ROM_PC1640 && romset!=ROM_PC1512 && romset!=ROM_TANDY && romset!=ROM_PC200)
|
||||
#define PCJR (romset == ROM_IBMPCJR)
|
||||
#define AMIBIOS (romset==ROM_AMI386 || romset==ROM_AMI486 || romset == ROM_WIN486)
|
||||
#define AMIBIOS (romset==ROM_AMI386SX || romset==ROM_AMI486 || romset == ROM_WIN486)
|
||||
|
||||
int GAMEBLASTER, GUS, SSI2001, voodoo_enabled, aha154x_enabled;
|
||||
extern int AMSTRAD, AT, is286, is386, PCI, TANDY;
|
||||
@@ -387,7 +381,7 @@ enum
|
||||
ROM_IBMAT386,
|
||||
ROM_ACER386,
|
||||
ROM_MEGAPC,
|
||||
ROM_AMI386,
|
||||
ROM_AMI386SX,
|
||||
ROM_AMI486,
|
||||
ROM_WIN486,
|
||||
ROM_PCI486,
|
||||
@@ -399,6 +393,9 @@ enum
|
||||
ROM_DESKPRO_386,
|
||||
ROM_IBMPS1_2121,
|
||||
|
||||
ROM_AMI386DX_OPTI495,
|
||||
ROM_MR386DX_OPTI495,
|
||||
|
||||
ROM_DTK486, /*DTK PKM-0038S E-2 / SiS 471 / Award BIOS / SiS 85C471*/
|
||||
ROM_VLI486SV2G, /*ASUS VL/I-486SV2G / SiS 471 / Award BIOS / SiS 85C471*/
|
||||
ROM_R418, /*Rise Computer R418 / SiS 496/497 / Award BIOS / SMC FDC37C665*/
|
||||
@@ -416,6 +413,8 @@ enum
|
||||
|
||||
ROM_MARL, /*Intel Advanced/ML / 430HX / AMI BIOS / National Semiconductors PC87306*/
|
||||
ROM_THOR, /*Intel Advanced/ATX / 430FX / AMI BIOS / National Semiconductors PC87306*/
|
||||
ROM_MRTHOR, /*Intel Advanced/ATX / 430FX / MR.BIOS / National Semiconductors PC87306*/
|
||||
ROM_POWERMATE_V,/*NEC PowerMate V / 430FX / Phoenix BIOS / SMC FDC37C665*/
|
||||
|
||||
ROM_MAX
|
||||
};
|
||||
@@ -449,6 +448,7 @@ enum
|
||||
GFX_PHOENIX_TRIO64, /*S3 764/Trio64 (Phoenix)*/
|
||||
GFX_INCOLOR, /* Hercules InColor */
|
||||
GFX_COLORPLUS, /* Plantronics ColorPlus */
|
||||
GFX_WY700, /* Wyse 700 */
|
||||
GFX_COMPAQ_EGA, /*Compaq EGA*/
|
||||
GFX_SUPER_EGA, /*Using Chips & Technologies SuperEGA BIOS*/
|
||||
GFX_COMPAQ_VGA, /*Compaq/Paradise VGA*/
|
||||
@@ -463,6 +463,8 @@ enum
|
||||
GFX_RIVATNT,
|
||||
GFX_RIVA128,
|
||||
GFX_HERCULESPLUS,
|
||||
GFX_RIVATNT2,
|
||||
|
||||
GFX_MAX
|
||||
};
|
||||
|
||||
@@ -474,44 +476,15 @@ int cpuspeed;
|
||||
|
||||
|
||||
/*Video*/
|
||||
void (*pollvideo)();
|
||||
void pollega();
|
||||
int readflash;
|
||||
uint8_t hercctrl;
|
||||
int slowega,egacycles,egacycles2;
|
||||
extern uint8_t gdcreg[16];
|
||||
extern int egareads,egawrites;
|
||||
extern int cga_comp;
|
||||
extern int vid_resize;
|
||||
extern int vid_api;
|
||||
extern int winsizex,winsizey;
|
||||
extern int chain4;
|
||||
|
||||
uint8_t readvram(uint16_t addr);
|
||||
void writevram(uint16_t addr, uint8_t val);
|
||||
void writevramgen(uint16_t addr, uint8_t val);
|
||||
|
||||
uint8_t readtandyvram(uint16_t addr);
|
||||
void writetandy(uint16_t addr, uint8_t val);
|
||||
void writetandyvram(uint16_t addr, uint8_t val);
|
||||
|
||||
extern int et4k_b8000;
|
||||
extern int changeframecount;
|
||||
extern uint8_t changedvram[(8192*1024)/1024];
|
||||
|
||||
void writeega_chain4(uint32_t addr, uint8_t val);
|
||||
extern uint32_t svgarbank,svgawbank;
|
||||
|
||||
/*Serial*/
|
||||
extern int mousedelay;
|
||||
|
||||
|
||||
/*Sound*/
|
||||
uint8_t spkstat;
|
||||
|
||||
float spktime;
|
||||
int rtctime;
|
||||
int soundtime,gustime,gustime2,vidtime;
|
||||
int ppispeakon;
|
||||
float CGACONST;
|
||||
float MDACONST;
|
||||
@@ -523,10 +496,6 @@ int gated,speakval,speakon;
|
||||
|
||||
|
||||
/*Sound Blaster*/
|
||||
/*int sbenable,sblatchi,sblatcho,sbcount,sb_enable_i,sb_count_i;
|
||||
int16_t sbdat;*/
|
||||
void setsbclock(float clock);
|
||||
|
||||
#define SADLIB 1 /*No DSP*/
|
||||
#define SB1 2 /*DSP v1.05*/
|
||||
#define SB15 3 /*DSP v2.00*/
|
||||
@@ -538,11 +507,6 @@ void setsbclock(float clock);
|
||||
#define SND_WSS 9 /*Windows Sound System*/
|
||||
#define SND_PAS16 10 /*Pro Audio Spectrum 16*/
|
||||
|
||||
int sbtype;
|
||||
|
||||
int clocks[3][12][4];
|
||||
int at70hz;
|
||||
|
||||
char pcempath[512];
|
||||
|
||||
|
||||
@@ -557,7 +521,7 @@ typedef struct
|
||||
uint32_t base;
|
||||
} hard_disk_t;
|
||||
|
||||
hard_disk_t hdc[4];
|
||||
hard_disk_t hdc[6];
|
||||
|
||||
uint64_t hdt[128][3];
|
||||
|
||||
@@ -588,20 +552,14 @@ extern int ide_ter_enabled;
|
||||
#define MIN(a, b) ((a) < (b) ? (a) : (b))
|
||||
#define ELEMENTS(Array) (sizeof(Array) / sizeof((Array)[0]))
|
||||
|
||||
extern int ui_writeprot[2];
|
||||
extern int ui_writeprot[4];
|
||||
|
||||
void pclog(const char *format, ...);
|
||||
extern int nmi;
|
||||
|
||||
extern int times;
|
||||
|
||||
|
||||
extern float isa_timing, bus_timing;
|
||||
|
||||
extern int frame;
|
||||
|
||||
|
||||
uint8_t *vramp;
|
||||
|
||||
uint64_t timer_read();
|
||||
extern uint64_t timer_freq;
|
||||
@@ -617,7 +575,6 @@ void resetpc_cad();
|
||||
|
||||
extern int start_in_fullscreen;
|
||||
extern int window_w, window_h, window_x, window_y, window_remember;
|
||||
extern int mouse_always_serial;
|
||||
|
||||
extern uint64_t pmc[2];
|
||||
|
||||
|
||||
554
src/ide.c
554
src/ide.c
@@ -145,7 +145,7 @@ IDE ide_drives[6];
|
||||
|
||||
IDE *ext_ide;
|
||||
|
||||
char ide_fn[4][512];
|
||||
char ide_fn[6][512];
|
||||
|
||||
int (*ide_bus_master_read_sector)(int channel, uint8_t *data);
|
||||
int (*ide_bus_master_write_sector)(int channel, uint8_t *data);
|
||||
@@ -298,6 +298,7 @@ static inline void ide_irq_lower(IDE *ide)
|
||||
#endif
|
||||
// }
|
||||
ide->irqstat=0;
|
||||
// ide->service=0;
|
||||
}
|
||||
|
||||
int get_irq(uint8_t board)
|
||||
@@ -307,6 +308,13 @@ int get_irq(uint8_t board)
|
||||
else if (board == 2) return 1 << 10;
|
||||
}
|
||||
|
||||
int get_pic_mask(uint8_t board)
|
||||
{
|
||||
if (board == 0) return 1 << 6;
|
||||
else if (board == 1) return 1 << 7;
|
||||
else if (board == 2) return 1 << 2;
|
||||
}
|
||||
|
||||
void ide_irq_update(IDE *ide)
|
||||
{
|
||||
#ifdef RPCEMU_IDE
|
||||
@@ -326,9 +334,9 @@ void ide_irq_update(IDE *ide)
|
||||
else if ((pic2.pend|pic2.ins)&0x40)
|
||||
picintc((ide->board)?(1<<15):(1<<14));
|
||||
#else
|
||||
if (ide->irqstat && !((pic2.pend|pic2.ins)&0x40) && !(ide->fdisk & 2))
|
||||
if (ide->irqstat && !((pic2.pend|pic2.ins)&get_pic_mask(ide->board)) && !(ide->fdisk & 2))
|
||||
picint(get_irq(ide->board));
|
||||
else if ((pic2.pend|pic2.ins)&0x40)
|
||||
else if ((pic2.pend|pic2.ins)&get_pic_mask(ide->board))
|
||||
picintc(get_irq(ide->board));
|
||||
#endif
|
||||
#endif
|
||||
@@ -385,9 +393,15 @@ ide_padstr8(uint8_t *buf, int buf_size, const char *src)
|
||||
*/
|
||||
static void ide_identify(IDE *ide)
|
||||
{
|
||||
int c, h, s;
|
||||
|
||||
memset(ide->buffer, 0, 512);
|
||||
|
||||
//ide->buffer[1] = 101; /* Cylinders */
|
||||
|
||||
c = hdc[cur_ide[ide->board]].tracks; /* Cylinders */
|
||||
h = hdc[cur_ide[ide->board]].hpc; /* Heads */
|
||||
s = hdc[cur_ide[ide->board]].spt; /* Sectors */
|
||||
|
||||
ide->buffer[1] = hdc[cur_ide[ide->board]].tracks; /* Cylinders */
|
||||
ide->buffer[3] = hdc[cur_ide[ide->board]].hpc; /* Heads */
|
||||
@@ -399,7 +413,11 @@ static void ide_identify(IDE *ide)
|
||||
ide->buffer[21] = 512; /*Buffer size*/
|
||||
ide->buffer[47] = 16; /*Max sectors on multiple transfer command*/
|
||||
ide->buffer[48] = 1; /*Dword transfers supported*/
|
||||
ide->buffer[49] = (1 << 9) | (1 << 8); /* LBA and DMA supported */
|
||||
ide->buffer[49] = (1 << 8); /* LBA and DMA supported */
|
||||
if ((c > 1024) || (h > 16) || (s > 63))
|
||||
{
|
||||
ide->buffer[49] |= (1 << 9);
|
||||
}
|
||||
ide->buffer[50] = 0x4000; /* Capabilities */
|
||||
ide->buffer[51] = 2 << 8; /*PIO timing mode*/
|
||||
ide->buffer[52] = 2 << 8; /*DMA timing mode*/
|
||||
@@ -670,7 +688,13 @@ void resetide(void)
|
||||
|
||||
idecallback[0]=idecallback[1]=0;
|
||||
|
||||
for (d = 0; d < 4; d++)
|
||||
#ifdef MAINLINE
|
||||
#define IDE_DRIVES 4
|
||||
#else
|
||||
#define IDE_DRIVES 6
|
||||
#endif
|
||||
|
||||
for (d = 0; d < IDE_DRIVES; d++)
|
||||
{
|
||||
ide_drives[d].packetstatus = 0xFF;
|
||||
|
||||
@@ -691,30 +715,10 @@ void resetide(void)
|
||||
ide_drives[d].dma_identify_data[1] = 7 | (1 << 15);
|
||||
ide_drives[d].dma_identify_data[2] = 0x3f;
|
||||
}
|
||||
|
||||
ide_drives[d].error = 1;
|
||||
}
|
||||
|
||||
/* REMOVE WHEN SUBMITTING TO MAINLINE - START */
|
||||
for (d = 4; d < 6; d++)
|
||||
{
|
||||
ide_drives[d].packetstatus = 0xFF;
|
||||
|
||||
if ((atapi_cdrom_channel == d) && cdrom_enabled && !scsi_cdrom_enabled)
|
||||
{
|
||||
ide_drives[d].type = IDE_CDROM;
|
||||
}
|
||||
else
|
||||
{
|
||||
ide_drives[d].type = IDE_NONE;
|
||||
}
|
||||
|
||||
ide_set_signature(&ide_drives[d]);
|
||||
|
||||
ide_drives[d].dma_identify_data[0] = 7;
|
||||
ide_drives[d].dma_identify_data[1] = 7 | (1 << 15);
|
||||
ide_drives[d].dma_identify_data[2] = 0x3f;
|
||||
}
|
||||
/* REMOVE WHEN SUBMITTING TO MAINLINE - END */
|
||||
|
||||
cur_ide[0] = 0;
|
||||
cur_ide[1] = 2;
|
||||
|
||||
@@ -804,13 +808,13 @@ void writeide(int ide_board, uint16_t addr, uint8_t val)
|
||||
IDE *ide_other = &ide_drives[cur_ide[ide_board] ^ 1];
|
||||
|
||||
// if ((cr0&1) && !(eflags&VM_FLAG))
|
||||
// pclog("WriteIDE %04X %02X from %04X(%08X):%08X %i\n", addr, val, CS, cs, pc, ins);
|
||||
// return;
|
||||
// pclog("WriteIDE %04X %02X from %04X(%08X):%08X %i\n", addr, val, CS, cs, cpu_state.pc, ins);
|
||||
// return;
|
||||
addr|=0x80;
|
||||
/* ONLY FOR EXPERIMENTAL */
|
||||
addr|=0x10; /* 1F0 | 10 = 1F0, 1E8 | 10 = 1F8 */
|
||||
addr&=0xFFF7; /* 1F0 & FFF7 = 1F0, 1F8 | FFF7 = 1F0 */
|
||||
// if (ide_board) pclog("Write IDEb %04X %02X %04X(%08X):%04X %i %02X %02X\n",addr,val,CS,cs,pc,ins,ide->atastat,ide_drives[0].atastat);
|
||||
// if (ide_board) pclog("Write IDEb %04X %02X %04X(%08X):%04X %i %02X %02X\n",addr,val,CS,cs,pc,ins,ide->atastat,ide_drives[0].atastat);
|
||||
/*if (idedebug) */
|
||||
// pclog("Write IDE %08X %02X %04X:%08X\n",addr,val,CS,pc);
|
||||
// int c;
|
||||
@@ -898,11 +902,15 @@ void writeide(int ide_board, uint16_t addr, uint8_t val)
|
||||
ide->lba_addr = (ide->lba_addr & 0x0FFFFFF) | ((val & 0xF) << 24);
|
||||
ide_other->lba_addr = (ide_other->lba_addr & 0x0FFFFFF)|((val & 0xF) << 24);
|
||||
|
||||
ide_irq_update(ide);
|
||||
ide_irq_update(ide);
|
||||
return;
|
||||
|
||||
case 0x1F7: /* Command register */
|
||||
if (ide->type == IDE_NONE) return;
|
||||
if (ide->type == IDE_NONE)
|
||||
{
|
||||
ide->error=1;
|
||||
return;
|
||||
}
|
||||
// pclog("IDE command %02X drive %i\n",val,ide.drive);
|
||||
ide_irq_lower(ide);
|
||||
ide->command=val;
|
||||
@@ -1076,7 +1084,14 @@ void writeide(int ide_board, uint16_t addr, uint8_t val)
|
||||
timer_process();
|
||||
idecallback[ide_board]=500*IDE_TIME;
|
||||
timer_update_outstanding();
|
||||
ide->reset = ide_other->reset = 1;
|
||||
if (ide->type != IDE_NONE)
|
||||
{
|
||||
ide->reset = 1;
|
||||
}
|
||||
if (ide_other->type != IDE_NONE)
|
||||
{
|
||||
ide->reset = 1;
|
||||
}
|
||||
ide->atastat = ide_other->atastat = BUSY_STAT;
|
||||
// pclog("IDE Reset %i\n", ide_board);
|
||||
}
|
||||
@@ -1102,7 +1117,16 @@ uint8_t readide(int ide_board, uint16_t addr)
|
||||
// pclog("ReadIDE %04X from %04X(%08X):%08X\n", addr, CS, cs, pc);
|
||||
// return 0xFF;
|
||||
|
||||
if (ide->type == IDE_NONE && (addr == 0x1f0 || addr == 0x1f7)) return 0;
|
||||
if (ide->type == IDE_NONE && (addr == 0x1f0 || addr == 0x1f7))
|
||||
{
|
||||
// pclog("Reading empty IDE channel (%04X)\n", addr);
|
||||
if (addr == 0x1f7)
|
||||
{
|
||||
/* This is apparently required for an empty ID channel. */
|
||||
return 0x20;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
// /*if (addr!=0x1F7 && addr!=0x3F6) */pclog("Read IDEb %04X %02X %02X %i %04X:%04X %i %04X\n",addr,ide->atastat,(ide->atastat & ~DSC_STAT) | (ide->service ? SERVICE_STAT : 0),cur_ide[ide_board],CS,pc,ide_board, BX);
|
||||
//rpclog("Read IDE %08X %08X %02X\n",addr,PC,iomd.irqb.mask);
|
||||
switch (addr)
|
||||
@@ -1115,39 +1139,83 @@ uint8_t readide(int ide_board, uint16_t addr)
|
||||
|
||||
case 0x1F1: /* Error */
|
||||
// pclog("Read error %02X\n",ide.error);
|
||||
temp = ide->error;
|
||||
if (ide->type == IDE_NONE)
|
||||
{
|
||||
temp = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
temp = ide->error;
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x1F2: /* Sector count */
|
||||
// pclog("Read sector count %02X\n",ide->secount);
|
||||
temp = (uint8_t)ide->secount;
|
||||
if (ide->type == IDE_NONE)
|
||||
{
|
||||
temp = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
temp = (uint8_t)ide->secount;
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x1F3: /* Sector */
|
||||
temp = (uint8_t)ide->sector;
|
||||
if (ide->type == IDE_NONE)
|
||||
{
|
||||
temp = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
temp = (uint8_t)ide->sector;
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x1F4: /* Cylinder low */
|
||||
// pclog("Read cyl low %02X\n",ide.cylinder&0xFF);
|
||||
temp = (uint8_t)(ide->cylinder&0xFF);
|
||||
if (ide->type == IDE_NONE)
|
||||
{
|
||||
temp = 0xFF;
|
||||
}
|
||||
else
|
||||
{
|
||||
temp = (uint8_t)(ide->cylinder&0xFF);
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x1F5: /* Cylinder high */
|
||||
// pclog("Read cyl low %02X\n",ide.cylinder>>8);
|
||||
temp = (uint8_t)(ide->cylinder>>8);
|
||||
if (ide->type == IDE_NONE)
|
||||
{
|
||||
temp = 0xFF;
|
||||
}
|
||||
else
|
||||
{
|
||||
temp = (uint8_t)(ide->cylinder>>8);
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x1F6: /* Drive/Head */
|
||||
temp = (uint8_t)(ide->head | ((cur_ide[ide_board] & 1) ? 0x10 : 0) | (ide->lba ? 0x40 : 0) | 0xa0);
|
||||
if (ide->type == IDE_NONE)
|
||||
{
|
||||
temp = (uint8_t)(((cur_ide[ide_board] & 1) ? 0x10 : 0) | 0xa0);
|
||||
}
|
||||
else
|
||||
{
|
||||
temp = (uint8_t)(ide->head | ((cur_ide[ide_board] & 1) ? 0x10 : 0) | (ide->lba ? 0x40 : 0) | 0xa0);
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x1F7: /* Status */
|
||||
if (ide->type == IDE_NONE)
|
||||
#if 0
|
||||
if (ide->type == IDE_NONE)
|
||||
{
|
||||
// pclog("Return status 00\n");
|
||||
temp = 0;
|
||||
temp = DSC_STAT;
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
ide_irq_lower(ide);
|
||||
if (ide->type == IDE_CDROM)
|
||||
{
|
||||
@@ -1168,7 +1236,7 @@ uint8_t readide(int ide_board, uint16_t addr)
|
||||
if (ide->type == IDE_NONE)
|
||||
{
|
||||
// pclog("Return status 00\n");
|
||||
temp = 0;
|
||||
temp = DSC_STAT;
|
||||
break;
|
||||
}
|
||||
if (ide->type == IDE_CDROM)
|
||||
@@ -1184,8 +1252,8 @@ uint8_t readide(int ide_board, uint16_t addr)
|
||||
}
|
||||
break;
|
||||
}
|
||||
// if (ide_board) pclog("Read IDEb %04X %02X %02X %02X %i %04X:%04X %i\n", addr, temp, ide->atastat,(ide->atastat & ~DSC_STAT) | (ide->service ? SERVICE_STAT : 0),cur_ide[ide_board],CS,pc,ide_board);
|
||||
return temp;
|
||||
///* if (ide_board) */ pclog("Read IDEb %04X %02X %02X %02X %i %04X:%04X %i\n", addr, temp, ide->atastat,(ide->atastat & ~DSC_STAT) | (ide->service ? SERVICE_STAT : 0),cur_ide[ide_board],CS,cpu_state.pc,ide_board);
|
||||
return temp;
|
||||
// fatal("Bad IDE read %04X\n", addr);
|
||||
}
|
||||
|
||||
@@ -1267,8 +1335,8 @@ void callbackide(int ide_board)
|
||||
if (ide->command==0x30) times30++;
|
||||
// if (times30==2240) output=1;
|
||||
//if (times30==2471 && ide->command==0xA0) output=1;
|
||||
///*if (ide_board) */pclog("CALLBACK %02X %i %i %i\n",ide->command,times30,ide->reset,cur_ide[ide_board]);
|
||||
// if (times30==1294)
|
||||
///*if (ide_board) */pclog("CALLBACK %02X %i %i %i\n",ide->command,times30,ide->reset,cur_ide[ide_board]);
|
||||
// if (times30==1294)
|
||||
// output=1;
|
||||
if (ide->reset)
|
||||
{
|
||||
@@ -1654,6 +1722,7 @@ void callbackide(int ide_board)
|
||||
case WIN_IDENTIFY: /* Identify Device */
|
||||
if (ide->type == IDE_NONE)
|
||||
{
|
||||
ide_set_signature(ide);
|
||||
goto abort_cmd;
|
||||
}
|
||||
if (IDE_DRIVE_IS_CDROM(ide))
|
||||
@@ -1854,7 +1923,7 @@ static int cdrom_add_error_and_subchannel(uint8_t *b, int real_sector_type)
|
||||
}
|
||||
else if ((cdrom_sector_flags & 0x06) == 0x06)
|
||||
{
|
||||
pclog("Invalid error flags\n");
|
||||
// pclog("Invalid error flags\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1877,7 +1946,7 @@ static int cdrom_add_error_and_subchannel(uint8_t *b, int real_sector_type)
|
||||
}
|
||||
else if (((cdrom_sector_flags & 0x700) == 0x300) || ((cdrom_sector_flags & 0x700) > 0x400))
|
||||
{
|
||||
pclog("Invalid subchannel data flags\n");
|
||||
// pclog("Invalid subchannel data flags\n");
|
||||
return 0;
|
||||
}
|
||||
// }
|
||||
@@ -1892,7 +1961,7 @@ static int cdrom_LBAtoMSF_accurate(IDE *ide)
|
||||
int temp_pos;
|
||||
int m, s, f;
|
||||
|
||||
temp_pos = ide->cdpos;
|
||||
temp_pos = ide->cdpos + 150;
|
||||
f = temp_pos % 75;
|
||||
temp_pos -= f;
|
||||
temp_pos /= 75;
|
||||
@@ -1925,27 +1994,37 @@ static int cdrom_read_data(IDE *ide, uint8_t *buffer)
|
||||
|
||||
memset(cdrom_sector_buffer.buffer, 0, 2856);
|
||||
|
||||
cdrom->readsector_raw(cdrom_sector_buffer.buffer, real_pos, cdrom_sector_ismsf);
|
||||
is_audio = cdrom->is_track_audio(real_pos, cdrom_sector_ismsf);
|
||||
// is_audio = cdrom->is_track_audio(real_pos, cdrom_sector_ismsf);
|
||||
real_sector_type = cdrom->sector_data_type(real_pos, cdrom_sector_ismsf);
|
||||
// pclog("Sector type: %i\n", real_sector_type);
|
||||
|
||||
if ((cdrom_sector_type > 0) && (cdrom_sector_type < 6))
|
||||
{
|
||||
if (real_sector_type != cdrom_sector_type)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else if (cdrom_sector_type == 6)
|
||||
{
|
||||
/* READ (6), READ (10), READ (12) */
|
||||
if ((real_sector_type != 2) && (real_sector_type != 4))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (!(cdrom_sector_flags & 0xf0)) /* 0x00 and 0x08 are illegal modes */
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
cdrom->readsector_raw(cdrom_sector_buffer.buffer, real_pos, cdrom_sector_ismsf);
|
||||
|
||||
if (cdrom->is_track_audio(ide->cdpos, 0))
|
||||
if (real_sector_type == 1)
|
||||
{
|
||||
real_sector_type = 1;
|
||||
|
||||
if (cdrom_sector_type > 1)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
memcpy(b, cdrom_sector_buffer.buffer, 2352);
|
||||
cdrom_sector_size = 2352;
|
||||
}
|
||||
memcpy(b, cdrom_sector_buffer.buffer, 2352);
|
||||
cdrom_sector_size = 2352;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1969,140 +2048,114 @@ static int cdrom_read_data(IDE *ide, uint8_t *buffer)
|
||||
temp_b += 4;
|
||||
}
|
||||
|
||||
switch(cdrom_sector_buffer.cdrom_sector.header[3])
|
||||
{
|
||||
case 1:
|
||||
real_sector_type = 2; /* Mode 1 */
|
||||
break;
|
||||
case 2:
|
||||
real_sector_type = 3; /* Mode 2 */
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (real_sector_type == 2)
|
||||
{
|
||||
if ((cdrom_sector_type == 0) || (cdrom_sector_type == 2))
|
||||
/* Mode 1 sector, expected type is 1 type. */
|
||||
if (cdrom_sector_flags & 0x40) /* Sub-header */
|
||||
{
|
||||
/* Mode 1 sector, expected type is 1 type. */
|
||||
if (cdrom_sector_flags & 0x40) /* Sub-header */
|
||||
if (!(cdrom_sector_flags & 0x10)) /* No user data */
|
||||
{
|
||||
if (!(cdrom_sector_flags & 0x10)) /* No user data */
|
||||
{
|
||||
memcpy(temp_b, cdrom_sector_buffer.cdrom_sector.data.m1_data.user_data, 8);
|
||||
cdrom_sector_size += 8;
|
||||
temp_b += 8;
|
||||
}
|
||||
}
|
||||
if (cdrom_sector_flags & 0x10) /* User data */
|
||||
{
|
||||
memcpy(temp_b, cdrom_sector_buffer.cdrom_sector.data.m1_data.user_data, 2048);
|
||||
cdrom_sector_size += 2048;
|
||||
temp_b += 2048;
|
||||
}
|
||||
if (cdrom_sector_flags & 0x08) /* EDC/ECC */
|
||||
{
|
||||
memcpy(temp_b, cdrom_sector_buffer.cdrom_sector.data.m1_data.ecc, 288);
|
||||
cdrom_sector_size += 288;
|
||||
temp_b += 288;
|
||||
memcpy(temp_b, cdrom_sector_buffer.cdrom_sector.data.m1_data.user_data, 8);
|
||||
cdrom_sector_size += 8;
|
||||
temp_b += 8;
|
||||
}
|
||||
}
|
||||
else
|
||||
if (cdrom_sector_flags & 0x10) /* User data */
|
||||
{
|
||||
return 0;
|
||||
memcpy(temp_b, cdrom_sector_buffer.cdrom_sector.data.m1_data.user_data, 2048);
|
||||
cdrom_sector_size += 2048;
|
||||
temp_b += 2048;
|
||||
}
|
||||
if (cdrom_sector_flags & 0x08) /* EDC/ECC */
|
||||
{
|
||||
memcpy(temp_b, cdrom_sector_buffer.cdrom_sector.data.m1_data.ecc, 288);
|
||||
cdrom_sector_size += 288;
|
||||
temp_b += 288;
|
||||
}
|
||||
}
|
||||
else if (real_sector_type == 3)
|
||||
{
|
||||
if ((cdrom_sector_type == 0) || (cdrom_sector_type == 3))
|
||||
/* Mode 2 sector, non-XA mode. */
|
||||
if (cdrom_sector_flags & 0x40) /* Sub-header */
|
||||
{
|
||||
/* Mode 2 sector, non-XA mode. */
|
||||
if (cdrom_sector_flags & 0x40) /* Sub-header */
|
||||
{
|
||||
if (!(cdrom_sector_flags & 0x10)) /* No user data */
|
||||
{
|
||||
memcpy(temp_b, cdrom_sector_buffer.cdrom_sector.data.m2_data.sub_header, 8);
|
||||
cdrom_sector_size += 8;
|
||||
temp_b += 8;
|
||||
}
|
||||
}
|
||||
if (cdrom_sector_flags & 0x10) /* User data */
|
||||
{
|
||||
memcpy(temp_b, cdrom_sector_buffer.cdrom_sector.data.m2_data.sub_header, 2328);
|
||||
cdrom_sector_size += 8;
|
||||
temp_b += 8;
|
||||
memcpy(temp_b, cdrom_sector_buffer.cdrom_sector.data.m2_data.user_data, 2328);
|
||||
cdrom_sector_size += 2328;
|
||||
temp_b += 2328;
|
||||
}
|
||||
}
|
||||
else if (cdrom_sector_type == 4)
|
||||
{
|
||||
/* Mode 2 sector, XA Form 1 mode */
|
||||
if ((cdrom_sector_flags & 0xf0) == 0x30)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
if (((cdrom_sector_flags & 0xf8) >= 0xa8) || ((cdrom_sector_flags & 0xf8) <= 0xd8))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
if (cdrom_sector_flags & 0x40) /* Sub-header */
|
||||
if (!(cdrom_sector_flags & 0x10)) /* No user data */
|
||||
{
|
||||
memcpy(temp_b, cdrom_sector_buffer.cdrom_sector.data.m2_data.sub_header, 8);
|
||||
cdrom_sector_size += 8;
|
||||
temp_b += 8;
|
||||
}
|
||||
if (cdrom_sector_flags & 0x10) /* User data */
|
||||
{
|
||||
if ((cdrom_sector_flags & 0xf0) == 0x10)
|
||||
{
|
||||
/* The data is alone, include sub-header. */
|
||||
memcpy(temp_b, cdrom_sector_buffer.cdrom_sector.data.m2_data.sub_header, 8);
|
||||
cdrom_sector_size += 8;
|
||||
temp_b += 8;
|
||||
}
|
||||
memcpy(temp_b, cdrom_sector_buffer.cdrom_sector.data.m2_data.user_data, 2040);
|
||||
cdrom_sector_size += 2040;
|
||||
temp_b += 2040;
|
||||
}
|
||||
if (cdrom_sector_flags & 0x08) /* EDC/ECC */
|
||||
{
|
||||
memcpy(temp_b, cdrom_sector_buffer.cdrom_sector.data.m2_data.user_data + 2040, 288);
|
||||
cdrom_sector_size += 288;
|
||||
temp_b += 288;
|
||||
}
|
||||
}
|
||||
else if (cdrom_sector_type == 5)
|
||||
if (cdrom_sector_flags & 0x10) /* User data */
|
||||
{
|
||||
/* Mode 2 sector, XA Form 2 mode */
|
||||
if ((cdrom_sector_flags & 0xf0) == 0x30)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
if (((cdrom_sector_flags & 0xf8) >= 0xa8) || ((cdrom_sector_flags & 0xf8) <= 0xd8))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
/* Mode 2 sector, XA Form 1 mode */
|
||||
if (cdrom_sector_flags & 0x40) /* Sub-header */
|
||||
{
|
||||
memcpy(temp_b, cdrom_sector_buffer.cdrom_sector.data.m2_data.sub_header, 8);
|
||||
cdrom_sector_size += 8;
|
||||
temp_b += 8;
|
||||
}
|
||||
if (cdrom_sector_flags & 0x10) /* User data */
|
||||
{
|
||||
memcpy(temp_b, cdrom_sector_buffer.cdrom_sector.data.m2_data.user_data, 2328);
|
||||
cdrom_sector_size += 2328;
|
||||
temp_b += 2328;
|
||||
}
|
||||
memcpy(temp_b, cdrom_sector_buffer.cdrom_sector.data.m2_data.sub_header, 2328);
|
||||
cdrom_sector_size += 8;
|
||||
temp_b += 8;
|
||||
memcpy(temp_b, cdrom_sector_buffer.cdrom_sector.data.m2_data.user_data, 2328);
|
||||
cdrom_sector_size += 2328;
|
||||
temp_b += 2328;
|
||||
}
|
||||
else
|
||||
}
|
||||
else if (real_sector_type == 4)
|
||||
{
|
||||
/* Mode 2 sector, XA Form 1 mode */
|
||||
if ((cdrom_sector_flags & 0xf0) == 0x30)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
if (((cdrom_sector_flags & 0xf8) >= 0xa8) && ((cdrom_sector_flags & 0xf8) <= 0xd8))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
if (cdrom_sector_flags & 0x40) /* Sub-header */
|
||||
{
|
||||
memcpy(temp_b, cdrom_sector_buffer.cdrom_sector.data.m2_data.sub_header, 8);
|
||||
cdrom_sector_size += 8;
|
||||
temp_b += 8;
|
||||
}
|
||||
if (cdrom_sector_flags & 0x10) /* User data */
|
||||
{
|
||||
if ((cdrom_sector_flags & 0xf0) == 0x10)
|
||||
{
|
||||
/* The data is alone, include sub-header. */
|
||||
memcpy(temp_b, cdrom_sector_buffer.cdrom_sector.data.m2_data.sub_header, 8);
|
||||
cdrom_sector_size += 8;
|
||||
temp_b += 8;
|
||||
}
|
||||
memcpy(temp_b, cdrom_sector_buffer.cdrom_sector.data.m2_data.user_data, 2040);
|
||||
cdrom_sector_size += 2040;
|
||||
temp_b += 2040;
|
||||
}
|
||||
if (cdrom_sector_flags & 0x08) /* EDC/ECC */
|
||||
{
|
||||
memcpy(temp_b, cdrom_sector_buffer.cdrom_sector.data.m2_data.user_data + 2040, 288);
|
||||
cdrom_sector_size += 288;
|
||||
temp_b += 288;
|
||||
}
|
||||
}
|
||||
else if (real_sector_type == 5)
|
||||
{
|
||||
/* Mode 2 sector, XA Form 2 mode */
|
||||
if ((cdrom_sector_flags & 0xf0) == 0x30)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
if (((cdrom_sector_flags & 0xf8) >= 0xa8) || ((cdrom_sector_flags & 0xf8) <= 0xd8))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
/* Mode 2 sector, XA Form 1 mode */
|
||||
if (cdrom_sector_flags & 0x40) /* Sub-header */
|
||||
{
|
||||
memcpy(temp_b, cdrom_sector_buffer.cdrom_sector.data.m2_data.sub_header, 8);
|
||||
cdrom_sector_size += 8;
|
||||
temp_b += 8;
|
||||
}
|
||||
if (cdrom_sector_flags & 0x10) /* User data */
|
||||
{
|
||||
memcpy(temp_b, cdrom_sector_buffer.cdrom_sector.data.m2_data.user_data, 2328);
|
||||
cdrom_sector_size += 2328;
|
||||
temp_b += 2328;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -2138,6 +2191,7 @@ static void atapicommand(int ide_board)
|
||||
int media;
|
||||
int format;
|
||||
int ret;
|
||||
int real_pos;
|
||||
|
||||
#if 0
|
||||
pclog("ATAPI command 0x%02X, Sense Key %02X, Asc %02X, Ascq %02X, %i, Unit attention: %i\n",idebufferb[0],SCSISense.SenseKey,SCSISense.Asc,SCSISense.Ascq,ins,SCSISense.UnitAttention);
|
||||
@@ -2152,6 +2206,7 @@ static void atapicommand(int ide_board)
|
||||
|
||||
if (cdrom->medium_changed())
|
||||
{
|
||||
// pclog("Medium has changed...\n");
|
||||
SCSICDROM_Insert();
|
||||
}
|
||||
|
||||
@@ -2240,14 +2295,16 @@ static void atapicommand(int ide_board)
|
||||
idebufferb[13]=SCSISense.Ascq;
|
||||
}
|
||||
}
|
||||
else if ((SCSISense.SenseKey == 0) && (cd_status >= CD_STATUS_PLAYING))
|
||||
else if ((SCSISense.SenseKey == 0) && (cd_status >= CD_STATUS_PLAYING) && (cd_status != CD_STATUS_STOPPED))
|
||||
{
|
||||
// pclog("CD-ROM drive is in audio phase\n");
|
||||
idebufferb[2]=SENSE_ILLEGAL_REQUEST;
|
||||
idebufferb[12]=ASC_AUDIO_PLAY_OPERATION;
|
||||
idebufferb[13]=(cd_status == CD_STATUS_PLAYING) ? ASCQ_AUDIO_PLAY_OPERATION_IN_PROGRESS : ASCQ_AUDIO_PLAY_OPERATION_PAUSED;
|
||||
}
|
||||
else
|
||||
{
|
||||
// pclog("Returning Unit Attention\n");
|
||||
if (SCSISense.UnitAttention)
|
||||
{
|
||||
idebufferb[2]=SENSE_UNIT_ATTENTION;
|
||||
@@ -2265,6 +2322,7 @@ static void atapicommand(int ide_board)
|
||||
{
|
||||
/* If the last remaining sense is unit attention, clear
|
||||
that condition. */
|
||||
// pclog("Unit attention cleared");
|
||||
SCSISense.UnitAttention = 0;
|
||||
}
|
||||
|
||||
@@ -2373,10 +2431,9 @@ static void atapicommand(int ide_board)
|
||||
cdrom_sector_type = (idebufferb[1] >> 2) & 7;
|
||||
cdrom_sector_flags = idebufferb[9] || (((uint32_t) idebufferb[10]) << 8);
|
||||
|
||||
ret = cdrom_read_data(ide, idebufferb);
|
||||
|
||||
if (!ret)
|
||||
if (ide->cdpos > (cdrom->size() - 1))
|
||||
{
|
||||
pclog("Trying to read beyond the end of disc\n");
|
||||
ide->atastat = READY_STAT | ERR_STAT; /*CHECK CONDITION*/
|
||||
ide->error = (SENSE_ILLEGAL_REQUEST << 4) | ABRT_ERR;
|
||||
if (SCSISense.SenseKey == SENSE_UNIT_ATTENTION)
|
||||
@@ -2387,6 +2444,18 @@ static void atapicommand(int ide_board)
|
||||
ide->packetstatus = ATAPI_STATUS_ERROR;
|
||||
idecallback[ide_board]=50*IDE_TIME;
|
||||
break;
|
||||
}
|
||||
|
||||
ret = cdrom_read_data(ide, idebufferb);
|
||||
|
||||
if (!ret)
|
||||
{
|
||||
ide->atastat = READY_STAT | ERR_STAT; /*CHECK CONDITION*/
|
||||
ide->error = (SENSE_ILLEGAL_REQUEST << 4) | ABRT_ERR;
|
||||
SCSISense.Asc = ASC_ILLEGAL_OPCODE;
|
||||
ide->packetstatus = ATAPI_STATUS_ERROR;
|
||||
idecallback[ide_board]=50*IDE_TIME;
|
||||
break;
|
||||
// pclog("Bad flags bits %02X\n",idebufferb[9]);
|
||||
// exit(-1);
|
||||
}
|
||||
@@ -2432,6 +2501,21 @@ static void atapicommand(int ide_board)
|
||||
ide->cdpos=(((uint32_t) idebufferb[2])<<24)|(((uint32_t) idebufferb[3])<<16)|(((uint32_t) idebufferb[4])<<8)|((uint32_t) idebufferb[5]);
|
||||
}
|
||||
|
||||
if (ide->cdpos > (cdrom->size() - 1))
|
||||
{
|
||||
pclog("Trying to read beyond the end of disc\n");
|
||||
ide->atastat = READY_STAT | ERR_STAT; /*CHECK CONDITION*/
|
||||
ide->error = (SENSE_ILLEGAL_REQUEST << 4) | ABRT_ERR;
|
||||
if (SCSISense.SenseKey == SENSE_UNIT_ATTENTION)
|
||||
{
|
||||
ide->error |= MCR_ERR;
|
||||
}
|
||||
SCSISense.Asc = ASC_ILLEGAL_OPCODE;
|
||||
ide->packetstatus = ATAPI_STATUS_ERROR;
|
||||
idecallback[ide_board]=50*IDE_TIME;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!ide->cdlen)
|
||||
{
|
||||
// pclog("All done - callback set\n");
|
||||
@@ -2440,11 +2524,23 @@ static void atapicommand(int ide_board)
|
||||
break;
|
||||
}
|
||||
|
||||
cdrom_sector_type = 0;
|
||||
cdrom_sector_type = 6;
|
||||
cdrom_sector_flags = 0x10;
|
||||
|
||||
ret = cdrom_read_data(ide, idebufferb);
|
||||
|
||||
if (!ret)
|
||||
{
|
||||
ide->atastat = READY_STAT | ERR_STAT; /*CHECK CONDITION*/
|
||||
ide->error = (SENSE_ILLEGAL_REQUEST << 4) | ABRT_ERR;
|
||||
SCSISense.Asc = ASC_ILLEGAL_OPCODE;
|
||||
ide->packetstatus = ATAPI_STATUS_ERROR;
|
||||
idecallback[ide_board]=50*IDE_TIME;
|
||||
break;
|
||||
// pclog("Bad flags bits %02X\n",idebufferb[9]);
|
||||
// exit(-1);
|
||||
}
|
||||
|
||||
#ifndef RPCEMU_IDE
|
||||
readflash=1;
|
||||
#endif
|
||||
@@ -2462,23 +2558,31 @@ static void atapicommand(int ide_board)
|
||||
return;
|
||||
|
||||
case GPCMD_READ_HEADER:
|
||||
if (msf)
|
||||
{
|
||||
ide->atastat = READY_STAT | ERR_STAT; /*CHECK CONDITION*/
|
||||
ide->error = (SENSE_ILLEGAL_REQUEST << 4) | ABRT_ERR;
|
||||
if (SCSISense.SenseKey == SENSE_UNIT_ATTENTION)
|
||||
ide->error |= MCR_ERR;
|
||||
SCSISense.SenseKey = ASC_ILLEGAL_OPCODE;
|
||||
ide->packetstatus = ATAPI_STATUS_ERROR;
|
||||
idecallback[ide_board]=50*IDE_TIME;
|
||||
break;
|
||||
// pclog("Read Header MSF!\n");
|
||||
// exit(-1);
|
||||
}
|
||||
for (c=0;c<4;c++) idebufferb[c+4]=idebufferb[c+2];
|
||||
idebufferb[0]=1; /*2048 bytes user data*/
|
||||
idebufferb[1]=idebufferb[2]=idebufferb[3]=0;
|
||||
if (cdrom->read_header)
|
||||
{
|
||||
cdrom->read_header(idebufferb, idebufferb);
|
||||
}
|
||||
else
|
||||
{
|
||||
ide->cdlen=(idebufferb[7]<<8)|idebufferb[8];
|
||||
ide->cdpos=(idebufferb[2]<<24)|(idebufferb[3]<<16)|(idebufferb[4]<<8)|idebufferb[5];
|
||||
if (msf)
|
||||
{
|
||||
real_pos = cdrom_LBAtoMSF_accurate(ide);
|
||||
}
|
||||
else
|
||||
{
|
||||
real_pos = ide->cdpos;
|
||||
}
|
||||
idebufferb[4] = (real_pos >> 24);
|
||||
idebufferb[5] = ((real_pos >> 16) & 0xff);
|
||||
idebufferb[6] = ((real_pos >> 8) & 0xff);
|
||||
idebufferb[7] = real_pos & 0xff;
|
||||
idebufferb[0]=1; /*2048 bytes user data*/
|
||||
idebufferb[1]=idebufferb[2]=idebufferb[3]=0;
|
||||
}
|
||||
|
||||
len = 8;
|
||||
ide->packetstatus = ATAPI_STATUS_DATA;
|
||||
ide->cylinder=8;
|
||||
ide->secount=2;
|
||||
@@ -2722,14 +2826,21 @@ static void atapicommand(int ide_board)
|
||||
break;
|
||||
|
||||
case GPCMD_READ_DISC_INFORMATION:
|
||||
idebufferb[1] = 32;
|
||||
idebufferb[2] = 0xe; /* last session complete, disc finalized */
|
||||
idebufferb[3] = 1; /* first track on disc */
|
||||
idebufferb[4] = 1; /* # of sessions */
|
||||
idebufferb[5] = 1; /* first track of last session */
|
||||
idebufferb[6] = 1; /* last track of last session */
|
||||
idebufferb[7] = 0x20; /* unrestricted use */
|
||||
idebufferb[8] = 0x00; /* CD-ROM */
|
||||
if (cdrom->read_disc_information)
|
||||
{
|
||||
cdrom->read_disc_information(idebufferb);
|
||||
}
|
||||
else
|
||||
{
|
||||
idebufferb[1] = 32;
|
||||
idebufferb[2] = 0xe; /* last session complete, disc finalized */
|
||||
idebufferb[3] = 1; /* first track on disc */
|
||||
idebufferb[4] = 1; /* # of sessions */
|
||||
idebufferb[5] = 1; /* first track of last session */
|
||||
idebufferb[6] = 1; /* last track of last session */
|
||||
idebufferb[7] = 0x20; /* unrestricted use */
|
||||
idebufferb[8] = 0x00; /* CD-ROM */
|
||||
}
|
||||
|
||||
len=34;
|
||||
ide->packetstatus = ATAPI_STATUS_DATA;
|
||||
@@ -2743,8 +2854,6 @@ static void atapicommand(int ide_board)
|
||||
case GPCMD_PLAY_AUDIO_10:
|
||||
case GPCMD_PLAY_AUDIO_12:
|
||||
case GPCMD_PLAY_AUDIO_MSF:
|
||||
/*This is apparently deprecated in the ATAPI spec, and apparently
|
||||
has been since 1995 (!). Hence I'm having to guess most of it*/
|
||||
if (idebufferb[0] == GPCMD_PLAY_AUDIO_10)
|
||||
{
|
||||
pos=(idebufferb[2]<<24)|(idebufferb[3]<<16)|(idebufferb[4]<<8)|idebufferb[5];
|
||||
@@ -2752,6 +2861,8 @@ static void atapicommand(int ide_board)
|
||||
}
|
||||
else if (idebufferb[0] == GPCMD_PLAY_AUDIO_MSF)
|
||||
{
|
||||
/*This is apparently deprecated in the ATAPI spec, and apparently
|
||||
has been since 1995 (!). Hence I'm having to guess most of it*/
|
||||
pos=(idebufferb[3]<<16)|(idebufferb[4]<<8)|idebufferb[5];
|
||||
len=(idebufferb[6]<<16)|(idebufferb[7]<<8)|idebufferb[8];
|
||||
}
|
||||
@@ -3019,19 +3130,24 @@ atapi_out:
|
||||
break;
|
||||
|
||||
case GPCMD_READ_CDROM_CAPACITY:
|
||||
atapi_command_send_init(ide, temp_command, 8, 8);
|
||||
size = cdrom->size();
|
||||
idebufferb[0] = (size >> 24) & 0xff;
|
||||
idebufferb[1] = (size >> 16) & 0xff;
|
||||
idebufferb[2] = (size >> 8) & 0xff;
|
||||
idebufferb[3] = size & 0xff;
|
||||
idebufferb[4] = (2048 >> 24) & 0xff;
|
||||
idebufferb[5] = (2048 >> 16) & 0xff;
|
||||
idebufferb[6] = (2048 >> 8) & 0xff;
|
||||
idebufferb[7] = 2048 & 0xff;
|
||||
len=8;
|
||||
atapi_command_ready(ide_board, len);
|
||||
break;
|
||||
atapi_command_send_init(ide, temp_command, 8, 8);
|
||||
if (cdrom->read_capacity)
|
||||
{
|
||||
cdrom->read_capacity(idebufferb);
|
||||
}
|
||||
else
|
||||
{
|
||||
size = cdrom->size() - 1; /* IMPORTANT: What's returned is the last LBA block. */
|
||||
memset(idebufferb, 0, 8);
|
||||
idebufferb[0] = (size >> 24) & 0xff;
|
||||
idebufferb[1] = (size >> 16) & 0xff;
|
||||
idebufferb[2] = (size >> 8) & 0xff;
|
||||
idebufferb[3] = size & 0xff;
|
||||
idebufferb[6] = 8; /* 2048 = 0x0800 */
|
||||
}
|
||||
len=8;
|
||||
atapi_command_ready(ide_board, len);
|
||||
break;
|
||||
|
||||
case GPCMD_SEND_DVD_STRUCTURE:
|
||||
default:
|
||||
|
||||
@@ -26,7 +26,7 @@ extern int ideboard;
|
||||
|
||||
extern int idecallback[3];
|
||||
|
||||
extern char ide_fn[4][512];
|
||||
extern char ide_fn[6][512];
|
||||
|
||||
extern int atapi_cdrom_channel;
|
||||
|
||||
|
||||
@@ -67,6 +67,7 @@ void intel_batman_init()
|
||||
}
|
||||
|
||||
|
||||
#if 0
|
||||
uint8_t endeavor_brdconfig(uint16_t port, void *p)
|
||||
{
|
||||
// pclog("endeavor_brdconfig read port=%04x\n", port);
|
||||
@@ -82,3 +83,4 @@ void intel_endeavor_init()
|
||||
{
|
||||
io_sethandler(0x0079, 0x0001, endeavor_brdconfig, NULL, NULL, NULL, NULL, NULL, NULL);
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -176,6 +176,12 @@ void *intel_flash_init(uint8_t type)
|
||||
case ROM_MB500N:
|
||||
strcpy(flash_path, "roms/mb500n/");
|
||||
break;
|
||||
case ROM_POWERMATE_V:
|
||||
strcpy(flash_path, "roms/powermate_v/");
|
||||
break;
|
||||
case ROM_P54TP4XE:
|
||||
strcpy(flash_path, "roms/p54tp4xe/");
|
||||
break;
|
||||
case ROM_ACERM3A:
|
||||
strcpy(flash_path, "roms/acerm3a/");
|
||||
break;
|
||||
@@ -188,6 +194,12 @@ void *intel_flash_init(uint8_t type)
|
||||
case ROM_P55VA:
|
||||
strcpy(flash_path, "roms/p55va/");
|
||||
break;
|
||||
case ROM_P55T2P4:
|
||||
strcpy(flash_path, "roms/p55t2p4/");
|
||||
break;
|
||||
case ROM_P55TVP4:
|
||||
strcpy(flash_path, "roms/p55tvp4/");
|
||||
break;
|
||||
case ROM_440FX:
|
||||
strcpy(flash_path, "roms/440fx/");
|
||||
break;
|
||||
@@ -197,6 +209,9 @@ void *intel_flash_init(uint8_t type)
|
||||
case ROM_THOR:
|
||||
strcpy(flash_path, "roms/thor/");
|
||||
break;
|
||||
case ROM_MRTHOR:
|
||||
strcpy(flash_path, "roms/mrthor/");
|
||||
break;
|
||||
default:
|
||||
fatal("intel_flash_init on unsupported ROM set %i\n", romset);
|
||||
}
|
||||
|
||||
@@ -55,6 +55,9 @@ struct
|
||||
int key_wantdata;
|
||||
|
||||
int last_irq;
|
||||
|
||||
void (*mouse_write)(uint8_t val, void *p);
|
||||
void *mouse_p;
|
||||
} keyboard_at;
|
||||
|
||||
static uint8_t key_ctrl_queue[16];
|
||||
@@ -304,8 +307,8 @@ void keyboard_at_write(uint16_t port, uint8_t val, void *priv)
|
||||
break;
|
||||
|
||||
case 0xd4: /*Write to mouse*/
|
||||
if (mouse_write)
|
||||
mouse_write(val);
|
||||
if (keyboard_at.mouse_write)
|
||||
keyboard_at.mouse_write(val, keyboard_at.mouse_p);
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -587,6 +590,7 @@ void keyboard_at_write(uint16_t port, uint8_t val, void *priv)
|
||||
|
||||
case 0xfe: /*Pulse output port - pin 0 selected - x86 reset*/
|
||||
softresetx86(); /*Pulse reset!*/
|
||||
cpu_set_edx();
|
||||
break;
|
||||
|
||||
case 0xff: /*Pulse output port - but no pins selected - sent by MegaPC BIOS*/
|
||||
@@ -611,6 +615,12 @@ uint8_t keyboard_at_read(uint16_t port, void *priv)
|
||||
temp = keyboard_at.out;
|
||||
keyboard_at.status &= ~(STAT_OFULL/* | STAT_MFULL*/);
|
||||
picintc(keyboard_at.last_irq);
|
||||
if (PCI)
|
||||
{
|
||||
/* The PIIX/PIIX3 datasheet mandates that both of these interrupts are cleared on any read of port 0x60. */
|
||||
picintc(1 << 1);
|
||||
picintc(1 << 12);
|
||||
}
|
||||
keyboard_at.last_irq = 0;
|
||||
break;
|
||||
|
||||
@@ -657,8 +667,15 @@ void keyboard_at_init()
|
||||
keyboard_at_reset();
|
||||
keyboard_send = keyboard_at_adddata_keyboard;
|
||||
keyboard_poll = keyboard_at_poll;
|
||||
mouse_write = NULL;
|
||||
keyboard_at.mouse_write = NULL;
|
||||
keyboard_at.mouse_p = NULL;
|
||||
dtrans = 0;
|
||||
|
||||
timer_add(keyboard_at_poll, &keybsenddelay, TIMER_ALWAYS_ENABLED, NULL);
|
||||
}
|
||||
|
||||
void keyboard_at_set_mouse(void (*mouse_write)(uint8_t val, void *p), void *p)
|
||||
{
|
||||
keyboard_at.mouse_write = mouse_write;
|
||||
keyboard_at.mouse_p = p;
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@ void keyboard_at_init();
|
||||
void keyboard_at_reset();
|
||||
void keyboard_at_poll();
|
||||
void keyboard_at_adddata_keyboard_raw(uint8_t val);
|
||||
void keyboard_at_set_mouse(void (*mouse_write)(uint8_t val, void *p), void *p);
|
||||
|
||||
void (*mouse_write)(uint8_t val);
|
||||
extern int mouse_queue_start, mouse_queue_end;
|
||||
extern int mouse_scan;
|
||||
|
||||
@@ -1,8 +1,3 @@
|
||||
/* Copyright holders: Sarah Walker
|
||||
see COPYING for more details
|
||||
*/
|
||||
#include <stdint.h>
|
||||
|
||||
#include "ibm.h"
|
||||
#include "io.h"
|
||||
#include "mem.h"
|
||||
@@ -152,7 +147,7 @@ void keyboard_olim24_write(uint16_t port, uint8_t val, void *priv)
|
||||
timer_process();
|
||||
timer_update_outstanding();
|
||||
|
||||
speaker_update();
|
||||
speaker_update();
|
||||
speaker_gated = val & 1;
|
||||
speaker_enable = val & 2;
|
||||
if (speaker_enable)
|
||||
@@ -221,85 +216,124 @@ void keyboard_olim24_reset()
|
||||
mouse_scancodes[6] = 0x50;
|
||||
}
|
||||
|
||||
static int mouse_x = 0, mouse_y = 0, mouse_b = 0;
|
||||
void mouse_olim24_poll(int x, int y, int b)
|
||||
typedef struct mouse_olim24_t
|
||||
{
|
||||
mouse_x += x;
|
||||
mouse_y += y;
|
||||
int x, y, b;
|
||||
} mouse_olim24_t;
|
||||
|
||||
pclog("mouse_poll - %i, %i %i, %i\n", x, y, mouse_x, mouse_y);
|
||||
void mouse_olim24_poll(int x, int y, int z, int b, void *p)
|
||||
{
|
||||
mouse_olim24_t *mouse = (mouse_olim24_t *)p;
|
||||
|
||||
if (((key_queue_end - key_queue_start) & 0xf) > 14) return;
|
||||
if ((b & 1) && !(mouse_b & 1))
|
||||
keyboard_olim24_adddata(mouse_scancodes[0]);
|
||||
if (!(b & 1) && (mouse_b & 1))
|
||||
keyboard_olim24_adddata(mouse_scancodes[0] | 0x80);
|
||||
mouse_b = (mouse_b & ~1) | (b & 1);
|
||||
mouse->x += x;
|
||||
mouse->y += y;
|
||||
|
||||
// pclog("mouse_poll - %i, %i %i, %i\n", x, y, mouse->x, mouse->y);
|
||||
|
||||
if (((key_queue_end - key_queue_start) & 0xf) > 14) return;
|
||||
if ((b & 2) && !(mouse_b & 2))
|
||||
keyboard_olim24_adddata(mouse_scancodes[2]);
|
||||
if (!(b & 2) && (mouse_b & 2))
|
||||
keyboard_olim24_adddata(mouse_scancodes[2] | 0x80);
|
||||
mouse_b = (mouse_b & ~2) | (b & 2);
|
||||
if (((key_queue_end - key_queue_start) & 0xf) > 14)
|
||||
return;
|
||||
if ((b & 1) && !(mouse->b & 1))
|
||||
keyboard_olim24_adddata(mouse_scancodes[0]);
|
||||
if (!(b & 1) && (mouse->b & 1))
|
||||
keyboard_olim24_adddata(mouse_scancodes[0] | 0x80);
|
||||
mouse->b = (mouse->b & ~1) | (b & 1);
|
||||
|
||||
if (((key_queue_end - key_queue_start) & 0xf) > 14) return;
|
||||
if ((b & 4) && !(mouse_b & 4))
|
||||
keyboard_olim24_adddata(mouse_scancodes[1]);
|
||||
if (!(b & 4) && (mouse_b & 4))
|
||||
keyboard_olim24_adddata(mouse_scancodes[1] | 0x80);
|
||||
mouse_b = (mouse_b & ~4) | (b & 4);
|
||||
if (((key_queue_end - key_queue_start) & 0xf) > 14)
|
||||
return;
|
||||
if ((b & 2) && !(mouse->b & 2))
|
||||
keyboard_olim24_adddata(mouse_scancodes[2]);
|
||||
if (!(b & 2) && (mouse->b & 2))
|
||||
keyboard_olim24_adddata(mouse_scancodes[2] | 0x80);
|
||||
mouse->b = (mouse->b & ~2) | (b & 2);
|
||||
|
||||
if (((key_queue_end - key_queue_start) & 0xf) > 14)
|
||||
return;
|
||||
if ((b & 4) && !(mouse->b & 4))
|
||||
keyboard_olim24_adddata(mouse_scancodes[1]);
|
||||
if (!(b & 4) && (mouse->b & 4))
|
||||
keyboard_olim24_adddata(mouse_scancodes[1] | 0x80);
|
||||
mouse->b = (mouse->b & ~4) | (b & 4);
|
||||
|
||||
if (keyboard_olim24.mouse_mode)
|
||||
{
|
||||
if (((key_queue_end - key_queue_start) & 0xf) > 12) return;
|
||||
if (!mouse_x && !mouse_y) return;
|
||||
if (((key_queue_end - key_queue_start) & 0xf) > 12)
|
||||
return;
|
||||
if (!mouse->x && !mouse->y)
|
||||
return;
|
||||
|
||||
mouse_y = -mouse_y;
|
||||
mouse->y = -mouse->y;
|
||||
|
||||
if (mouse_x < -127) mouse_x = -127;
|
||||
if (mouse_x > 127) mouse_x = 127;
|
||||
if (mouse_x < -127) mouse_x = 0x80 | ((-mouse_x) & 0x7f);
|
||||
if (mouse->x < -127) mouse->x = -127;
|
||||
if (mouse->x > 127) mouse->x = 127;
|
||||
if (mouse->x < -127) mouse->x = 0x80 | ((-mouse->x) & 0x7f);
|
||||
|
||||
if (mouse_y < -127) mouse_y = -127;
|
||||
if (mouse_y > 127) mouse_y = 127;
|
||||
if (mouse_y < -127) mouse_y = 0x80 | ((-mouse_y) & 0x7f);
|
||||
if (mouse->y < -127) mouse->y = -127;
|
||||
if (mouse->y > 127) mouse->y = 127;
|
||||
if (mouse->y < -127) mouse->y = 0x80 | ((-mouse->y) & 0x7f);
|
||||
|
||||
keyboard_olim24_adddata(0xfe);
|
||||
keyboard_olim24_adddata(mouse_x);
|
||||
keyboard_olim24_adddata(mouse_y);
|
||||
keyboard_olim24_adddata(mouse->x);
|
||||
keyboard_olim24_adddata(mouse->y);
|
||||
|
||||
mouse_x = mouse_y = 0;
|
||||
mouse->x = mouse->y = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
while (mouse_x < -4)
|
||||
while (mouse->x < -4)
|
||||
{
|
||||
if (((key_queue_end - key_queue_start) & 0xf) > 14) return;
|
||||
mouse_x+=4;
|
||||
if (((key_queue_end - key_queue_start) & 0xf) > 14)
|
||||
return;
|
||||
mouse->x += 4;
|
||||
keyboard_olim24_adddata(mouse_scancodes[3]);
|
||||
}
|
||||
while (mouse_x > 4)
|
||||
while (mouse->x > 4)
|
||||
{
|
||||
if (((key_queue_end - key_queue_start) & 0xf) > 14) return;
|
||||
mouse_x-=4;
|
||||
if (((key_queue_end - key_queue_start) & 0xf) > 14)
|
||||
return;
|
||||
mouse->x -= 4;
|
||||
keyboard_olim24_adddata(mouse_scancodes[4]);
|
||||
}
|
||||
while (mouse_y < -4)
|
||||
while (mouse->y < -4)
|
||||
{
|
||||
if (((key_queue_end - key_queue_start) & 0xf) > 14) return;
|
||||
mouse_y+=4;
|
||||
if (((key_queue_end - key_queue_start) & 0xf) > 14)
|
||||
return;
|
||||
mouse->y += 4;
|
||||
keyboard_olim24_adddata(mouse_scancodes[5]);
|
||||
}
|
||||
while (mouse_y > 4)
|
||||
while (mouse->y > 4)
|
||||
{
|
||||
if (((key_queue_end - key_queue_start) & 0xf) > 14) return;
|
||||
mouse_y-=4;
|
||||
if (((key_queue_end - key_queue_start) & 0xf) > 14)
|
||||
return;
|
||||
mouse->y -= 4;
|
||||
keyboard_olim24_adddata(mouse_scancodes[6]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void *mouse_olim24_init()
|
||||
{
|
||||
mouse_olim24_t *mouse = (mouse_olim24_t *)malloc(sizeof(mouse_olim24_t));
|
||||
memset(mouse, 0, sizeof(mouse_olim24_t));
|
||||
|
||||
return mouse;
|
||||
}
|
||||
|
||||
static void mouse_olim24_close(void *p)
|
||||
{
|
||||
mouse_olim24_t *mouse = (mouse_olim24_t *)p;
|
||||
|
||||
free(mouse);
|
||||
}
|
||||
|
||||
mouse_t mouse_olim24 =
|
||||
{
|
||||
"Olivetti M24 mouse",
|
||||
mouse_olim24_init,
|
||||
mouse_olim24_close,
|
||||
mouse_olim24_poll,
|
||||
MOUSE_TYPE_OLIM24
|
||||
};
|
||||
|
||||
void keyboard_olim24_init()
|
||||
{
|
||||
//return;
|
||||
@@ -308,7 +342,6 @@ void keyboard_olim24_init()
|
||||
keyboard_olim24_reset();
|
||||
keyboard_send = keyboard_olim24_adddata;
|
||||
keyboard_poll = keyboard_olim24_poll;
|
||||
mouse_poll = mouse_olim24_poll;
|
||||
|
||||
timer_add(keyboard_olim24_poll, &keybsenddelay, TIMER_ALWAYS_ENABLED, NULL);
|
||||
}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
/* Copyright holders: Sarah Walker
|
||||
see COPYING for more details
|
||||
*/
|
||||
void keyboard_olim24_init();
|
||||
void keyboard_olim24_reset();
|
||||
void keyboard_olim24_poll();
|
||||
|
||||
extern mouse_t mouse_olim24;
|
||||
|
||||
190
src/mem.c
190
src/mem.c
@@ -53,12 +53,11 @@ static unsigned char isram[0x10000];
|
||||
static uint8_t ff_array[0x1000];
|
||||
|
||||
int mem_size;
|
||||
int cache=4;
|
||||
uint32_t biosmask;
|
||||
int readlnum=0,writelnum=0;
|
||||
int cachesize=256;
|
||||
|
||||
uint8_t *ram,*rom,*vram;
|
||||
uint8_t *ram,*rom;
|
||||
uint8_t romext[32768];
|
||||
|
||||
static void mem_load_xtide_bios()
|
||||
@@ -109,9 +108,10 @@ int loadbios()
|
||||
int c;
|
||||
|
||||
loadfont("roms/mda.rom", 0);
|
||||
|
||||
loadfont("roms/wy700.rom", 3);
|
||||
|
||||
biosmask = 0xffff;
|
||||
|
||||
|
||||
memset(romext,0xff,0x8000);
|
||||
memset(rom, 0xff, 0x20000);
|
||||
|
||||
@@ -344,7 +344,7 @@ int loadbios()
|
||||
fread(rom,65536,1,f);
|
||||
fclose(f);
|
||||
return 1;*/
|
||||
case ROM_AMI386: /*This uses the OPTi 82C495 chipset*/
|
||||
case ROM_AMI386SX:
|
||||
// f=romfopen("roms/at386/at386.bin","rb");
|
||||
f=romfopen("roms/ami386/ami386.bin","rb");
|
||||
if (!f) break;
|
||||
@@ -352,6 +352,18 @@ int loadbios()
|
||||
fclose(f);
|
||||
return 1;
|
||||
|
||||
case ROM_AMI386DX_OPTI495: /*This uses the OPTi 82C495 chipset*/
|
||||
f=romfopen("roms/ami386dx/OPT495SX.AMI","rb");
|
||||
if (!f) break;
|
||||
fread(rom,65536,1,f);
|
||||
fclose(f);
|
||||
return 1;
|
||||
case ROM_MR386DX_OPTI495: /*This uses the OPTi 82C495 chipset*/
|
||||
f=romfopen("roms/mr386dx/OPT495SX.MR","rb");
|
||||
if (!f) break;
|
||||
fread(rom,65536,1,f);
|
||||
fclose(f);
|
||||
return 1;
|
||||
|
||||
case ROM_ACER386:
|
||||
f=romfopen("roms/acer386/acer386.bin","rb");
|
||||
@@ -665,6 +677,24 @@ int loadbios()
|
||||
biosmask = 0x1ffff;
|
||||
return 1;
|
||||
|
||||
#if 0
|
||||
case ROM_POWERMATE_V:
|
||||
f = romfopen("roms/powermate_v/BIOS.ROM", "rb"); /* Works */
|
||||
if (!f) break;
|
||||
fread(rom, 0x20000, 1, f);
|
||||
fclose(f);
|
||||
biosmask = 0x1ffff;
|
||||
return 1;
|
||||
#endif
|
||||
|
||||
case ROM_P54TP4XE:
|
||||
f = romfopen("roms/p54tp4xe/T15I0302.AWD", "rb");
|
||||
if (!f) break;
|
||||
fread(rom, 0x20000, 1, f);
|
||||
fclose(f);
|
||||
biosmask = 0x1ffff;
|
||||
return 1;
|
||||
|
||||
case ROM_ACERM3A:
|
||||
f = romfopen("roms/acerm3a/r01-b3.bin", "rb");
|
||||
if (!f) break;
|
||||
@@ -689,6 +719,22 @@ int loadbios()
|
||||
biosmask = 0x1ffff;
|
||||
return 1;
|
||||
|
||||
case ROM_P55T2P4:
|
||||
f = romfopen("roms/p55t2p4/0207_J2.BIN", "rb");
|
||||
if (!f) break;
|
||||
fread(rom, 0x20000, 1, f);
|
||||
fclose(f);
|
||||
biosmask = 0x1ffff;
|
||||
return 1;
|
||||
|
||||
case ROM_P55TVP4:
|
||||
f = romfopen("roms/p55tvp4/TV5I0204.AWD", "rb");
|
||||
if (!f) break;
|
||||
fread(rom, 0x20000, 1, f);
|
||||
fclose(f);
|
||||
biosmask = 0x1ffff;
|
||||
return 1;
|
||||
|
||||
case ROM_440FX:
|
||||
f = romfopen("roms/440fx/NTMAW501.BIN", "rb"); /* Working Tyan BIOS. */
|
||||
if (!f) break;
|
||||
@@ -726,6 +772,14 @@ int loadbios()
|
||||
biosmask = 0x1ffff;
|
||||
//is486=1;
|
||||
return 1;
|
||||
|
||||
case ROM_MRTHOR:
|
||||
f = romfopen("roms/mrthor/MR_ATX.BIO", "rb");
|
||||
if (!f) break;
|
||||
fread(rom, 0x20000, 1, f);
|
||||
fclose(f);
|
||||
biosmask = 0x1ffff;
|
||||
return 1;
|
||||
}
|
||||
printf("Failed to load ROM!\n");
|
||||
if (f) fclose(f);
|
||||
@@ -991,13 +1045,6 @@ void mmu_invalidate(uint32_t addr)
|
||||
flushmmucache_cr3();
|
||||
}
|
||||
|
||||
int memspeed[11]={256,320,384,512,640,768,1024,1152,1280,1536,1920};
|
||||
int memwaitstate;
|
||||
|
||||
static int cachelookup[256];
|
||||
static uint8_t *cachelookup2;
|
||||
static int cachelnext;
|
||||
|
||||
void addreadlookup(uint32_t virt, uint32_t phys)
|
||||
{
|
||||
// return;
|
||||
@@ -1017,17 +1064,6 @@ void addreadlookup(uint32_t virt, uint32_t phys)
|
||||
}
|
||||
|
||||
|
||||
if (!cachelookup2[phys >> 12])
|
||||
{
|
||||
readlnum++;
|
||||
cycles-=memwaitstate;
|
||||
if (cachelookup[cachelnext] != 0xffffffff)
|
||||
cachelookup2[cachelookup[cachelnext]] = 0;
|
||||
cachelookup[cachelnext] = phys >> 12;
|
||||
cachelookup2[phys >> 12] = 1;
|
||||
cachelnext = (cachelnext + 1) & (cachesize - 1);
|
||||
}
|
||||
|
||||
if (readlookup[readlnext]!=0xFFFFFFFF)
|
||||
{
|
||||
readlookup2[readlookup[readlnext]] = -1;
|
||||
@@ -1059,18 +1095,6 @@ void addwritelookup(uint32_t virt, uint32_t phys)
|
||||
return;
|
||||
}
|
||||
|
||||
if (!cachelookup2[phys >> 12])
|
||||
{
|
||||
writelnum++;
|
||||
cycles-=memwaitstate;
|
||||
if (cachelookup[cachelnext] != 0xffffffff)
|
||||
cachelookup2[cachelookup[cachelnext]] = 0;
|
||||
cachelookup[cachelnext] = phys >> 12;
|
||||
cachelookup2[phys >> 12] = 1;
|
||||
cachelnext = (cachelnext + 1) & (cachesize - 1);
|
||||
}
|
||||
|
||||
cycles-=memwaitstate;
|
||||
if (writelookup[writelnext] != -1)
|
||||
{
|
||||
page_lookup[writelookup[writelnext]] = NULL;
|
||||
@@ -1662,29 +1686,6 @@ void mem_write_nulll(uint32_t addr, uint32_t val, void *p)
|
||||
{
|
||||
}
|
||||
|
||||
void mem_updatecache()
|
||||
{
|
||||
flushmmucache();
|
||||
if (!is386 || israpidcad)
|
||||
{
|
||||
cachesize=256;
|
||||
memwaitstate=0;
|
||||
return;
|
||||
}
|
||||
if (cpu_16bitbus)
|
||||
memwaitstate = 512 * ((cpu_multi >= 2) ? 2 : cpu_multi);
|
||||
else
|
||||
memwaitstate = 384 * ((cpu_multi >= 2) ? 2 : cpu_multi); //memspeed[cpuspeed];
|
||||
switch (cache)
|
||||
{
|
||||
case 0: cachesize=32; break;
|
||||
case 1: cachesize=64; break;
|
||||
case 2: cachesize=128; break;
|
||||
case 3: cachesize=256; break;
|
||||
case 4: cachesize=256; memwaitstate=0; break;
|
||||
}
|
||||
}
|
||||
|
||||
void mem_invalidate_range(uint32_t start_addr, uint32_t end_addr)
|
||||
{
|
||||
start_addr &= ~PAGE_MASK_MASK;
|
||||
@@ -1937,10 +1938,8 @@ void mem_init()
|
||||
|
||||
ram = malloc((mem_size + 384) * 1024);
|
||||
rom = malloc(0x20000);
|
||||
vram = malloc(0x800000);
|
||||
readlookup2 = malloc(1024 * 1024 * sizeof(uintptr_t));
|
||||
writelookup2 = malloc(1024 * 1024 * sizeof(uintptr_t));
|
||||
cachelookup2 = malloc(1024 * 1024);
|
||||
biosmask = 0xffff;
|
||||
pages = malloc((((mem_size + 384) * 1024) >> 12) * sizeof(page_t));
|
||||
page_lookup = malloc((1 << 20) * sizeof(page_t *));
|
||||
@@ -1988,7 +1987,7 @@ void mem_init()
|
||||
if (mem_size > 1024)
|
||||
mem_mapping_add(&ram_high_mapping, 0x100000, ((mem_size - 1024) * 1024), mem_read_ram, mem_read_ramw, mem_read_raml, mem_write_ram, mem_write_ramw, mem_write_raml, ram + 0x100000, MEM_MAPPING_INTERNAL, NULL);
|
||||
if (mem_size > 768)
|
||||
mem_mapping_add(&ram_mid_mapping, 0xc0000, 0x40000, mem_read_ram, mem_read_ramw, mem_read_raml, mem_write_ram, mem_write_ramw, mem_write_raml, ram + 0xc0000, MEM_MAPPING_INTERNAL, NULL);
|
||||
mem_mapping_add(&ram_mid_mapping, 0xc0000, 0x40000, mem_read_ram, mem_read_ramw, mem_read_raml, mem_write_ram, mem_write_ramw, mem_write_raml, ram + 0xc0000, MEM_MAPPING_INTERNAL, NULL);
|
||||
|
||||
mem_mapping_add(&romext_mapping, 0xc8000, 0x08000, mem_read_romext, mem_read_romextw, mem_read_romextl, NULL, NULL, NULL, romext, 0, NULL);
|
||||
// pclog("Mem resize %i %i\n",mem_size,c);
|
||||
@@ -2064,7 +2063,7 @@ void mem_resize()
|
||||
if (mem_size > 1024)
|
||||
mem_mapping_add(&ram_high_mapping, 0x100000, (mem_size - 1024) * 1024, mem_read_ram, mem_read_ramw, mem_read_raml, mem_write_ram, mem_write_ramw, mem_write_raml, ram + 0x100000, MEM_MAPPING_INTERNAL, NULL);
|
||||
if (mem_size > 768)
|
||||
mem_mapping_add(&ram_mid_mapping, 0xc0000, 0x40000, mem_read_ram, mem_read_ramw, mem_read_raml, mem_write_ram, mem_write_ramw, mem_write_raml, ram + 0xc0000, MEM_MAPPING_INTERNAL, NULL);
|
||||
mem_mapping_add(&ram_mid_mapping, 0xc0000, 0x40000, mem_read_ram, mem_read_ramw, mem_read_raml, mem_write_ram, mem_write_ramw, mem_write_raml, ram + 0xc0000, MEM_MAPPING_INTERNAL, NULL);
|
||||
|
||||
mem_mapping_add(&romext_mapping, 0xc8000, 0x08000, mem_read_romext, mem_read_romextw, mem_read_romextl, NULL, NULL, NULL, romext, 0, NULL);
|
||||
|
||||
@@ -2087,6 +2086,30 @@ void mem_reset_page_blocks()
|
||||
}
|
||||
}
|
||||
|
||||
void mem_reset()
|
||||
{
|
||||
int c;
|
||||
|
||||
mem_reset_page_blocks();
|
||||
|
||||
memset(isram, 0, sizeof(isram));
|
||||
for (c = 0; c < (mem_size / 256); c++)
|
||||
{
|
||||
isram[c] = 1;
|
||||
if (c >= 0xa && c <= 0xf)
|
||||
isram[c] = 0;
|
||||
}
|
||||
|
||||
mem_set_mem_state(0x000000, (mem_size > 640) ? 0xa0000 : mem_size * 1024, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL);
|
||||
mem_set_mem_state(0x0c0000, 0x40000, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL);
|
||||
mem_set_mem_state(0x100000, (mem_size - 1024) * 1024, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL);
|
||||
|
||||
mem_a20_key = 2;
|
||||
mem_a20_recalc();
|
||||
}
|
||||
|
||||
static int port_92_reg = 0;
|
||||
|
||||
void mem_a20_recalc()
|
||||
{
|
||||
int state = mem_a20_key | mem_a20_alt;
|
||||
@@ -2105,4 +2128,47 @@ void mem_a20_recalc()
|
||||
mem_a20_state = state;
|
||||
}
|
||||
|
||||
static uint8_t port_92_read(uint16_t port, void *priv)
|
||||
{
|
||||
return (port_92_reg & 3) | 0x24;
|
||||
}
|
||||
|
||||
static void port_92_write(uint16_t port, uint8_t val, void *priv)
|
||||
{
|
||||
mem_a20_alt = val & 2;
|
||||
mem_a20_recalc();
|
||||
|
||||
if (!(port_92_reg & 1) && (val & 1))
|
||||
{
|
||||
// pclog("Port 92: Soft reset\n");
|
||||
softresetx86();
|
||||
}
|
||||
|
||||
port_92_reg = val & 3;
|
||||
|
||||
mem_a20_recalc();
|
||||
}
|
||||
|
||||
void port_92_clear_reset()
|
||||
{
|
||||
port_92_reg &= 2;
|
||||
}
|
||||
|
||||
void port_92_add()
|
||||
{
|
||||
io_sethandler(0x0092, 0x0001, port_92_read, NULL, NULL, port_92_write, NULL, NULL, NULL);
|
||||
}
|
||||
|
||||
void port_92_remove()
|
||||
{
|
||||
io_removehandler(0x0092, 0x0001, port_92_read, NULL, NULL, port_92_write, NULL, NULL, NULL);
|
||||
}
|
||||
|
||||
void port_92_reset()
|
||||
{
|
||||
port_92_reg = 0;
|
||||
mem_a20_alt = 0;
|
||||
mem_a20_recalc();
|
||||
}
|
||||
|
||||
uint32_t get_phys_virt,get_phys_phys;
|
||||
|
||||
@@ -37,8 +37,7 @@ extern uint8_t romext[32768];
|
||||
extern int readlnum,writelnum;
|
||||
extern int memspeed[11];
|
||||
extern int nopageerrors;
|
||||
extern int cache;
|
||||
extern int memwaitstate;
|
||||
extern uint32_t biosmask;
|
||||
|
||||
void mem_mapping_add(mem_mapping_t *mapping,
|
||||
uint32_t base,
|
||||
|
||||
243
src/model.c
243
src/model.c
@@ -5,6 +5,7 @@
|
||||
#include "cpu.h"
|
||||
#include "mem.h"
|
||||
#include "model.h"
|
||||
#include "mouse.h"
|
||||
#include "io.h"
|
||||
#include "rom.h"
|
||||
|
||||
@@ -38,13 +39,11 @@
|
||||
#include "keyboard_xt.h"
|
||||
#include "lpt.h"
|
||||
#include "memregs.h"
|
||||
#include "mouse_amstrad.h"
|
||||
#include "mouse_ps2.h"
|
||||
#include "mouse_serial.h"
|
||||
#include "neat.h"
|
||||
#include "nmi.h"
|
||||
#include "nvr.h"
|
||||
#include "olivetti_m24.h"
|
||||
#include "opti495.h"
|
||||
#include "pc87306.h"
|
||||
#include "pci.h"
|
||||
#include "pic.h"
|
||||
@@ -63,6 +62,8 @@
|
||||
#include "tandy_rom.h"
|
||||
#include "um8669f.h"
|
||||
// #include "um8881f.h"
|
||||
#include "vid_pcjr.h"
|
||||
#include "vid_tandy.h"
|
||||
#include "w83877f.h"
|
||||
#include "wd76c10.h"
|
||||
#include "xtide.h"
|
||||
@@ -84,6 +85,7 @@ void at_acer386sx_init();
|
||||
void at_wd76c10_init();
|
||||
void at_ali1429_init();
|
||||
void at_headland_init();
|
||||
void at_opti495_init();
|
||||
// void at_um8881f_init();
|
||||
void at_sis496_init();
|
||||
void at_i430vx_init();
|
||||
@@ -95,11 +97,14 @@ void at_r418_init();
|
||||
void at_586mc1_init();
|
||||
void at_plato_init();
|
||||
void at_mb500n_init();
|
||||
// void at_p54tp4xe_init();
|
||||
#if 0
|
||||
void at_powermate_v_init();
|
||||
#endif
|
||||
void at_p54tp4xe_init();
|
||||
void at_acerm3a_init();
|
||||
void at_acerv35n_init();
|
||||
// void at_p55t2p4_init();
|
||||
// void at_p55tvp4_init();
|
||||
void at_p55t2p4_init();
|
||||
void at_p55tvp4_init();
|
||||
void at_marl_init();
|
||||
void at_p55va_init();
|
||||
void at_i440fx_init();
|
||||
@@ -108,65 +113,69 @@ int model;
|
||||
|
||||
int AMSTRAD, AT, PCI, TANDY;
|
||||
|
||||
int mouse_always_serial;
|
||||
|
||||
MODEL models[] =
|
||||
{
|
||||
{"IBM PC", ROM_IBMPC, { "", cpus_8088, "", NULL, "", NULL}, 0, 0, 64, 640, 64, xt_init},
|
||||
{"IBM XT", ROM_IBMXT, { "", cpus_8088, "", NULL, "", NULL}, 0, 0, 128, 640, 64, xt_init},
|
||||
{"IBM PCjr", ROM_IBMPCJR, { "", cpus_pcjr, "", NULL, "", NULL}, 1, 0, 128, 640, 128, pcjr_init},
|
||||
{"Generic XT clone", ROM_GENXT, { "", cpus_8088, "", NULL, "", NULL}, 0, 0, 128, 640, 64, xt_init},
|
||||
{"AMI XT clone", ROM_AMIXT, { "", cpus_8088, "", NULL, "", NULL}, 0, 0, 128, 640, 64, xt_init},
|
||||
{"DTK XT clone", ROM_DTKXT, { "", cpus_8088, "", NULL, "", NULL}, 0, 0, 128, 640, 64, xt_init},
|
||||
{"VTech Laser Turbo XT",ROM_LTXT, { "", cpus_8088, "", NULL, "", NULL}, 0, 0, 128, 640, 64, xt_init},
|
||||
{"VTech Laser XT3", ROM_LXT3, { "", cpus_8088, "", NULL, "", NULL}, 0, 0, 128, 640, 64, xt_init},
|
||||
{"Phoenix XT clone", ROM_PXXT, { "", cpus_8088, "", NULL, "", NULL}, 0, 0, 128, 640, 64, xt_init},
|
||||
{"Juko XT clone", ROM_JUKOPC, { "", cpus_8088, "", NULL, "", NULL}, 0, 0, 128, 640, 64, xt_init},
|
||||
{"Tandy 1000", ROM_TANDY, { "", cpus_8088, "", NULL, "", NULL}, 1, 0, 128, 640, 128, tandy1k_init},
|
||||
{"Tandy 1000 HX", ROM_TANDY1000HX, { "", cpus_8088, "", NULL, "", NULL}, 1, 0, 256, 640, 128, tandy1k_init},
|
||||
{"Tandy 1000 SL/2", ROM_TANDY1000SL2,{ "", cpus_8086, "", NULL, "", NULL}, 1, 0, 512, 768, 128, tandy1ksl2_init},
|
||||
{"Amstrad PC1512", ROM_PC1512, { "", cpus_pc1512, "", NULL, "", NULL}, 1, 0, 512, 640, 128, ams_init},
|
||||
{"Sinclair PC200", ROM_PC200, { "", cpus_8086, "", NULL, "", NULL}, 1, 0, 512, 640, 128, ams_init},
|
||||
{"Euro PC", ROM_EUROPC, { "", cpus_8086, "", NULL, "", NULL}, 0, 0, 512, 640, 128, europc_init},
|
||||
{"Olivetti M24", ROM_OLIM24, { "", cpus_8086, "", NULL, "", NULL}, 1, 0, 128, 640, 128, olim24_init},
|
||||
{"Amstrad PC1640", ROM_PC1640, { "", cpus_8086, "", NULL, "", NULL}, 1, 0, 640, 640, 0, ams_init},
|
||||
{"Amstrad PC2086", ROM_PC2086, { "", cpus_8086, "", NULL, "", NULL}, 1, 0, 640, 640, 0, ams_init},
|
||||
{"Amstrad PC3086", ROM_PC3086, { "", cpus_8086, "", NULL, "", NULL}, 1, 0, 640, 640, 0, ams_init},
|
||||
{"IBM AT", ROM_IBMAT, { "", cpus_ibmat, "", NULL, "", NULL}, 0, 1, 1, 16, 1, at_init},
|
||||
{"Commodore PC 30 III", ROM_CMDPC30, { "", cpus_286, "", NULL, "", NULL}, 0, 1, 1, 16, 1, at_init},
|
||||
{"AMI 286 clone", ROM_AMI286, { "", cpus_286, "", NULL, "", NULL}, 0, 1, 1, 16, 1, at_neat_init},
|
||||
{"Award 286 clone", ROM_AWARD286, { "", cpus_286, "", NULL, "", NULL}, 0, 1, 1, 16, 1, at_scat_init},
|
||||
{"DELL System 200", ROM_DELL200, { "", cpus_286, "", NULL, "", NULL}, 0, 1, 1, 16, 1, at_init},
|
||||
{"IBM PS/1 model 2011", ROM_IBMPS1_2011, { "", cpus_ps1_m2011,"", NULL, "", NULL}, 1, 1, 1, 16, 1, ps1_m2011_init},
|
||||
{"IBM PS/1 model 2121", ROM_IBMPS1_2121, { "Intel", cpus_i386, "", NULL, "", NULL}, 1, 1, 1, 16, 1, ps1_m2121_init},
|
||||
{"Compaq Deskpro 386", ROM_DESKPRO_386, { "Intel", cpus_i386, "AMD", cpus_Am386, "Cyrix", cpus_486SDLC}, 0, 1, 1, 15, 1, deskpro386_init},
|
||||
{"Acer 386SX25/N", ROM_ACER386, { "Intel", cpus_acer, "", NULL, "", NULL}, 1, 1, 1, 16, 1, at_acer386sx_init},
|
||||
{"DTK 386SX clone", ROM_DTK386, { "Intel", cpus_i386, "AMD", cpus_Am386, "Cyrix", cpus_486SDLC}, 0, 1, 1, 16, 1, at_neat_init},
|
||||
{"Phoenix 386 clone", ROM_PX386, { "Intel", cpus_i386, "AMD", cpus_Am386, "Cyrix", cpus_486SDLC}, 0, 1, 1, 16, 1, at_init},
|
||||
{"Amstrad MegaPC", ROM_MEGAPC, { "Intel", cpus_i386, "AMD", cpus_Am386, "Cyrix", cpus_486SDLC}, 1, 1, 1, 16, 1, at_wd76c10_init},
|
||||
{"AMI 386 clone", ROM_AMI386, { "Intel", cpus_i386, "AMD", cpus_Am386, "Cyrix", cpus_486SDLC}, 0, 1, 1, 256, 1, at_headland_init},
|
||||
{"AMI 486 clone", ROM_AMI486, { "Intel", cpus_i486, "AMD", cpus_Am486, "Cyrix", cpus_Cx486}, 0, 1, 1, 256, 1, at_ali1429_init},
|
||||
{"AMI WinBIOS 486", ROM_WIN486, { "Intel", cpus_i486, "AMD", cpus_Am486, "Cyrix", cpus_Cx486}, 0, 1, 1, 256, 1, at_ali1429_init},
|
||||
/* {"AMI WinBIOS 486 PCI", ROM_PCI486, { "Intel", cpus_i486, "AMD", cpus_Am486, "Cyrix", cpus_Cx486}, 0, 1, 1, 256, 1, at_um8881f_init},*/
|
||||
{"DTK PKM-0038S E-2", ROM_DTK486, { "Intel", cpus_i486, "AMD", cpus_Am486, "Cyrix", cpus_Cx486}, 0, 1, 1, 256, 1, at_dtk486_init},
|
||||
{"Award SiS 496/497", ROM_SIS496, { "Intel", cpus_i486, "AMD", cpus_Am486, "Cyrix", cpus_Cx486}, 0, 1, 1, 256, 1, at_sis496_init},
|
||||
{"Rise Computer R418", ROM_R418, { "Intel", cpus_i486, "AMD", cpus_Am486, "Cyrix", cpus_Cx486}, 0, 1, 1, 256, 1, at_r418_init},
|
||||
{"Intel Premiere/PCI", ROM_REVENGE, { "Intel", cpus_Pentium5V, "", NULL, "", NULL}, 0, 1, 1, 128, 1, at_batman_init},
|
||||
{"Micro Star 586MC1", ROM_586MC1, { "Intel", cpus_Pentium5V50, "",NULL, "", NULL}, 0, 1, 1, 128, 1, at_586mc1_init},
|
||||
{"Intel Premiere/PCI II",ROM_PLATO, { "Intel", cpus_PentiumS5,"IDT", cpus_WinChip, "AMD", cpus_K5, "", NULL}, 0, 1, 1, 128, 1, at_plato_init},
|
||||
{"Intel Advanced/EV", ROM_ENDEAVOR, { "Intel", cpus_PentiumS5,"IDT", cpus_WinChip, "AMD", cpus_K5, "", NULL}, 0, 1, 1, 128, 1, at_endeavor_init},
|
||||
{"PC Partner MB500N", ROM_MB500N, { "Intel", cpus_PentiumS5,"IDT", cpus_WinChip, "AMD", cpus_K5, "", NULL}, 0, 1, 1, 128, 1, at_mb500n_init},
|
||||
{"Intel Advanced/ATX", ROM_THOR, { "Intel", cpus_Pentium, "IDT", cpus_WinChip, "Cyrix", cpus_6x86, "AMD", cpus_K56, "", NULL}, 0, 1, 1, 256, 1, at_endeavor_init},
|
||||
// {"ASUS P/I-P54TP4XE", ROM_P54TP4XE, { "Intel", cpus_PentiumS5, "IDT", cpus_WinChip, "AMD", cpus_K5, "", NULL}, 0, 1, 1, 512, 1, at_p54tp4xe_init},
|
||||
// {"Intel Advanced/ML", ROM_MARL, { "Intel", cpus_Pentium, "IDT", cpus_WinChip, "Cyrix", cpus_6x86, "AMD", cpus_K56, "", NULL}, 0, 1, 1, 512, 1, at_marl_init},
|
||||
{"Acer M3a", ROM_ACERM3A, { "Intel", cpus_Pentium, "IDT", cpus_WinChip, "Cyrix", cpus_6x86, "AMD", cpus_K56, "", NULL}, 0, 1, 1, 512, 1, at_acerm3a_init},
|
||||
{"Acer V35N", ROM_ACERV35N, { "Intel", cpus_Pentium, "IDT", cpus_WinChip, "Cyrix", cpus_6x86, "AMD", cpus_K56, "", NULL}, 0, 1, 1, 512, 1, at_acerv35n_init},
|
||||
// {"ASUS P/I-P55T2P4", ROM_P55T2P4, { "Intel", cpus_Pentium, "IDT", cpus_WinChip, "Cyrix", cpus_6x86, "AMD", cpus_K56, "", NULL}, 0, 1, 1, 512, 1, at_p55t2p4_init},
|
||||
{"Award 430VX PCI", ROM_430VX, { "Intel", cpus_Pentium, "IDT", cpus_WinChip, "Cyrix", cpus_6x86, "AMD", cpus_K56, "", NULL}, 0, 1, 1, 256, 1, at_i430vx_init},
|
||||
{"Epox P55-VA", ROM_P55VA, { "Intel", cpus_Pentium, "IDT", cpus_WinChip, "Cyrix", cpus_6x86, "AMD", cpus_K56, "", NULL}, 0, 1, 1, 256, 1, at_p55va_init},
|
||||
/* {"ASUS P/I-P55TVP4", ROM_P55TVP4, { "Intel", cpus_Pentium, "IDT", cpus_WinChip, "Cyrix", cpus_6x86, "AMD", cpus_K56, "", NULL}, 0, 1, 1, 256, 1, at_p55tvp4_init}, */
|
||||
{"Award 440FX PCI", ROM_440FX, { "Intel", cpus_PentiumPro, "", NULL, "", NULL}, 0, 1, 1, 1024, 1, at_i440fx_init},
|
||||
// {"Award 440FX PCI", ROM_440FX, { "Intel", cpus_PentiumPro,"Klamath", cpus_Pentium2, "Deschutes", cpus_Pentium2D}, 0, 1, 1, 1024, 1, at_i440fx_init},
|
||||
{"IBM PC", ROM_IBMPC, { "", cpus_8088, "", NULL, "", NULL}, 0, 0, 64, 640, 64, xt_init, NULL},
|
||||
{"IBM XT", ROM_IBMXT, { "", cpus_8088, "", NULL, "", NULL}, 0, 0, 128, 640, 64, xt_init, NULL},
|
||||
{"IBM PCjr", ROM_IBMPCJR, { "", cpus_pcjr, "", NULL, "", NULL}, 1, 0, 128, 640, 128, pcjr_init, &pcjr_device},
|
||||
{"Generic XT clone", ROM_GENXT, { "", cpus_8088, "", NULL, "", NULL}, 0, 0, 128, 640, 64, xt_init, NULL},
|
||||
{"AMI XT clone", ROM_AMIXT, { "", cpus_8088, "", NULL, "", NULL}, 0, 0, 128, 640, 64, xt_init, NULL},
|
||||
{"DTK XT clone", ROM_DTKXT, { "", cpus_8088, "", NULL, "", NULL}, 0, 0, 128, 640, 64, xt_init, NULL},
|
||||
{"VTech Laser Turbo XT",ROM_LTXT, { "", cpus_8088, "", NULL, "", NULL}, 0, 0, 128, 640, 64, xt_init, NULL},
|
||||
{"VTech Laser XT3", ROM_LXT3, { "", cpus_8088, "", NULL, "", NULL}, 0, 0, 128, 640, 64, xt_init, NULL},
|
||||
{"Phoenix XT clone", ROM_PXXT, { "", cpus_8088, "", NULL, "", NULL}, 0, 0, 128, 640, 64, xt_init, NULL},
|
||||
{"Juko XT clone", ROM_JUKOPC, { "", cpus_8088, "", NULL, "", NULL}, 0, 0, 128, 640, 64, xt_init, NULL},
|
||||
{"Tandy 1000", ROM_TANDY, { "", cpus_8088, "", NULL, "", NULL}, 1, 0, 128, 640, 128, tandy1k_init, &tandy1000_device},
|
||||
{"Tandy 1000 HX", ROM_TANDY1000HX, { "", cpus_8088, "", NULL, "", NULL}, 1, 0, 256, 640, 128, tandy1k_init, &tandy1000hx_device},
|
||||
{"Tandy 1000 SL/2", ROM_TANDY1000SL2,{ "", cpus_8086, "", NULL, "", NULL}, 1, 0, 512, 768, 128, tandy1ksl2_init, NULL},
|
||||
{"Amstrad PC1512", ROM_PC1512, { "", cpus_pc1512, "", NULL, "", NULL}, 1, MODEL_AMSTRAD, 512, 640, 128, ams_init, NULL},
|
||||
{"Sinclair PC200", ROM_PC200, { "", cpus_8086, "", NULL, "", NULL}, 1, MODEL_AMSTRAD, 512, 640, 128, ams_init, NULL},
|
||||
{"Euro PC", ROM_EUROPC, { "", cpus_8086, "", NULL, "", NULL}, 0, 0, 512, 640, 128, europc_init, NULL},
|
||||
{"Olivetti M24", ROM_OLIM24, { "", cpus_8086, "", NULL, "", NULL}, 1, MODEL_OLIM24, 128, 640, 128, olim24_init, NULL},
|
||||
{"Amstrad PC1640", ROM_PC1640, { "", cpus_8086, "", NULL, "", NULL}, 1, MODEL_AMSTRAD, 640, 640, 0, ams_init, NULL},
|
||||
{"Amstrad PC2086", ROM_PC2086, { "", cpus_8086, "", NULL, "", NULL}, 1, MODEL_AMSTRAD, 640, 640, 0, ams_init, NULL},
|
||||
{"Amstrad PC3086", ROM_PC3086, { "", cpus_8086, "", NULL, "", NULL}, 1, MODEL_AMSTRAD, 640, 640, 0, ams_init, NULL},
|
||||
{"IBM AT", ROM_IBMAT, { "", cpus_ibmat, "", NULL, "", NULL}, 0, MODEL_AT, 1, 16, 1, at_init, NULL},
|
||||
{"Commodore PC 30 III", ROM_CMDPC30, { "", cpus_286, "", NULL, "", NULL}, 0, MODEL_AT, 1, 16, 1, at_init, NULL},
|
||||
{"AMI 286 clone", ROM_AMI286, { "", cpus_286, "", NULL, "", NULL}, 0, MODEL_AT, 1, 16, 1, at_neat_init, NULL},
|
||||
{"Award 286 clone", ROM_AWARD286, { "", cpus_286, "", NULL, "", NULL}, 0, MODEL_AT, 1, 16, 1, at_scat_init, NULL},
|
||||
{"DELL System 200", ROM_DELL200, { "", cpus_286, "", NULL, "", NULL}, 0, MODEL_AT, 1, 16, 1, at_init, NULL},
|
||||
{"IBM PS/1 model 2011", ROM_IBMPS1_2011, { "", cpus_ps1_m2011,"", NULL, "", NULL}, 1, MODEL_AT|MODEL_PS2, 1, 16, 1, ps1_m2011_init, NULL},
|
||||
{"IBM PS/1 model 2121", ROM_IBMPS1_2121, { "Intel", cpus_i386, "", NULL, "", NULL}, 1, MODEL_AT|MODEL_PS2, 1, 16, 1, ps1_m2121_init, NULL},
|
||||
{"Compaq Deskpro 386", ROM_DESKPRO_386, { "Intel", cpus_i386, "AMD", cpus_Am386, "Cyrix", cpus_486SDLC}, 0, MODEL_AT, 1, 15, 1, deskpro386_init, NULL},
|
||||
{"Acer 386SX25/N", ROM_ACER386, { "Intel", cpus_acer, "", NULL, "", NULL}, 1, MODEL_AT|MODEL_PS2, 1, 16, 1, at_acer386sx_init, NULL},
|
||||
{"DTK 386SX clone", ROM_DTK386, { "Intel", cpus_i386, "AMD", cpus_Am386, "Cyrix", cpus_486SDLC}, 0, MODEL_AT, 1, 16, 1, at_neat_init, NULL},
|
||||
{"Phoenix 386 clone", ROM_PX386, { "Intel", cpus_i386, "AMD", cpus_Am386, "Cyrix", cpus_486SDLC}, 0, MODEL_AT, 1, 16, 1, at_init, NULL},
|
||||
{"Amstrad MegaPC", ROM_MEGAPC, { "Intel", cpus_i386, "AMD", cpus_Am386, "Cyrix", cpus_486SDLC}, 1, MODEL_AT|MODEL_PS2, 1, 16, 1, at_wd76c10_init, NULL},
|
||||
{"AMI 386SX clone", ROM_AMI386SX, { "Intel", cpus_i386, "AMD", cpus_Am386, "Cyrix", cpus_486SDLC}, 0, MODEL_AT, 1, 256, 1, at_headland_init, NULL},
|
||||
{"MR 386DX clone", ROM_MR386DX_OPTI495, { "Intel", cpus_i386DX, "AMD", cpus_Am386DX, "Cyrix", cpus_486DLC}, 0, MODEL_AT, 1, 256, 1, at_opti495_init, NULL},
|
||||
{"AMI 386DX clone", ROM_AMI386DX_OPTI495, { "Intel", cpus_i386DX, "AMD", cpus_Am386DX, "Cyrix", cpus_486DLC}, 0, MODEL_AT, 1, 256, 1, at_opti495_init, NULL},
|
||||
{"AMI 486 clone", ROM_AMI486, { "Intel", cpus_i486, "AMD", cpus_Am486, "Cyrix", cpus_Cx486}, 0, MODEL_AT, 1, 256, 1, at_ali1429_init, NULL},
|
||||
{"AMI WinBIOS 486", ROM_WIN486, { "Intel", cpus_i486, "AMD", cpus_Am486, "Cyrix", cpus_Cx486}, 0, MODEL_AT, 1, 256, 1, at_ali1429_init, NULL},
|
||||
/* {"AMI WinBIOS 486 PCI", ROM_PCI486, { "Intel", cpus_i486, "AMD", cpus_Am486, "Cyrix", cpus_Cx486}, 0, MODEL_AT, 1, 256, 1, at_um8881f_init, NULL},*/
|
||||
{"DTK PKM-0038S E-2", ROM_DTK486, { "Intel", cpus_i486, "AMD", cpus_Am486, "Cyrix", cpus_Cx486}, 0, MODEL_AT, 1, 256, 1, at_dtk486_init, NULL},
|
||||
{"Award SiS 496/497", ROM_SIS496, { "Intel", cpus_i486, "AMD", cpus_Am486, "Cyrix", cpus_Cx486}, 0, MODEL_AT, 1, 256, 1, at_sis496_init, NULL},
|
||||
{"Rise Computer R418", ROM_R418, { "Intel", cpus_i486, "AMD", cpus_Am486, "Cyrix", cpus_Cx486}, 0, MODEL_AT, 1, 256, 1, at_r418_init, NULL},
|
||||
{"Intel Premiere/PCI", ROM_REVENGE, { "Intel", cpus_Pentium5V, "", NULL, "", NULL}, 0, MODEL_AT|MODEL_PS2, 1, 128, 1, at_batman_init, NULL},
|
||||
{"Micro Star 586MC1", ROM_586MC1, { "Intel", cpus_Pentium5V50, "",NULL, "", NULL}, 0, MODEL_AT, 1, 128, 1, at_586mc1_init, NULL},
|
||||
{"Intel Premiere/PCI II",ROM_PLATO, { "Intel", cpus_PentiumS5,"IDT", cpus_WinChip, "AMD", cpus_K5, "", NULL}, 0, MODEL_AT|MODEL_PS2, 1, 128, 1, at_plato_init, NULL},
|
||||
{"Intel Advanced/EV", ROM_ENDEAVOR, { "Intel", cpus_PentiumS5,"IDT", cpus_WinChip, "AMD", cpus_K5, "", NULL}, 0, MODEL_AT|MODEL_PS2, 1, 128, 1, at_endeavor_init, NULL},
|
||||
{"PC Partner MB500N", ROM_MB500N, { "Intel", cpus_PentiumS5,"IDT", cpus_WinChip, "AMD", cpus_K5, "", NULL}, 0, MODEL_AT|MODEL_PS2, 1, 128, 1, at_mb500n_init, NULL},
|
||||
#if 0
|
||||
{"NEC PowerMate V", ROM_POWERMATE_V, { "Intel", cpus_PentiumS5,"IDT", cpus_WinChip, "AMD", cpus_K5, "", NULL}, 0, MODEL_AT|MODEL_PS2, 1, 128, 1, at_powermate_v_init, NULL},
|
||||
#endif
|
||||
{"Intel Advanced/ATX", ROM_THOR, { "Intel", cpus_Pentium, "IDT", cpus_WinChip, "Cyrix", cpus_6x86, "AMD", cpus_K56, "", NULL}, 0, MODEL_AT|MODEL_PS2, 1, 256, 1, at_endeavor_init, NULL},
|
||||
{"MR Intel Advanced/ATX", ROM_MRTHOR, { "Intel", cpus_Pentium, "IDT", cpus_WinChip, "Cyrix", cpus_6x86, "AMD", cpus_K56, "", NULL}, 0, MODEL_AT|MODEL_PS2, 1, 256, 1, at_endeavor_init, NULL},
|
||||
{"ASUS P/I-P54TP4XE", ROM_P54TP4XE, { "Intel", cpus_PentiumS5, "IDT", cpus_WinChip, "AMD", cpus_K5, "", NULL}, 0, MODEL_AT|MODEL_PS2, 1, 512, 1, at_p54tp4xe_init, NULL},
|
||||
// {"Intel Advanced/ML", ROM_MARL, { "Intel", cpus_Pentium, "IDT", cpus_WinChip, "Cyrix", cpus_6x86, "AMD", cpus_K56, "", NULL}, 0, MODEL_AT|MODEL_PS2, 1, 512, 1, at_marl_init, NULL},
|
||||
{"Acer M3a", ROM_ACERM3A, { "Intel", cpus_Pentium, "IDT", cpus_WinChip, "Cyrix", cpus_6x86, "AMD", cpus_K56, "", NULL}, 0, MODEL_AT|MODEL_PS2, 1, 512, 1, at_acerm3a_init, NULL},
|
||||
{"Acer V35N", ROM_ACERV35N, { "Intel", cpus_Pentium, "IDT", cpus_WinChip, "Cyrix", cpus_6x86, "AMD", cpus_K56, "", NULL}, 0, MODEL_AT|MODEL_PS2, 1, 512, 1, at_acerv35n_init, NULL},
|
||||
{"ASUS P/I-P55T2P4", ROM_P55T2P4, { "Intel", cpus_Pentium, "IDT", cpus_WinChip, "Cyrix", cpus_6x86, "AMD", cpus_K56, "", NULL}, 0, MODEL_AT|MODEL_PS2, 1, 512, 1, at_p55t2p4_init, NULL},
|
||||
{"Award 430VX PCI", ROM_430VX, { "Intel", cpus_Pentium, "IDT", cpus_WinChip, "Cyrix", cpus_6x86, "AMD", cpus_K56, "", NULL}, 0, MODEL_AT|MODEL_PS2, 1, 256, 1, at_i430vx_init, NULL},
|
||||
{"Epox P55-VA", ROM_P55VA, { "Intel", cpus_Pentium, "IDT", cpus_WinChip, "Cyrix", cpus_6x86, "AMD", cpus_K56, "", NULL}, 0, MODEL_AT|MODEL_PS2, 1, 256, 1, at_p55va_init, NULL},
|
||||
{"ASUS P/I-P55TVP4", ROM_P55TVP4, { "Intel", cpus_Pentium, "IDT", cpus_WinChip, "Cyrix", cpus_6x86, "AMD", cpus_K56, "", NULL}, 0, MODEL_AT|MODEL_PS2, 1, 256, 1, at_p55tvp4_init, NULL},
|
||||
{"Award 440FX PCI", ROM_440FX, { "Intel", cpus_PentiumPro, "", NULL, "", NULL}, 0, MODEL_AT|MODEL_PS2, 1, 1024, 1, at_i440fx_init, NULL},
|
||||
// {"Award 440FX PCI", ROM_440FX, { "Intel", cpus_PentiumPro,"Klamath", cpus_Pentium2, "Deschutes", cpus_Pentium2D}, 0, MODEL_AT|MODEL_PS2, 1, 1024, 1, at_i440fx_init, NULL},
|
||||
{"", -1, {"", 0, "", 0, "", 0}, 0,0,0, 0}
|
||||
};
|
||||
|
||||
@@ -199,6 +208,12 @@ char *model_getname()
|
||||
return models[model].name;
|
||||
}
|
||||
|
||||
|
||||
device_t *model_getdevice(int model)
|
||||
{
|
||||
return models[model].device;
|
||||
}
|
||||
|
||||
void common_init()
|
||||
{
|
||||
dma_init();
|
||||
@@ -216,7 +231,6 @@ void xt_init()
|
||||
mem_add_bios();
|
||||
pit_set_out_func(1, pit_refresh_timer_xt);
|
||||
keyboard_xt_init();
|
||||
mouse_serial_init();
|
||||
xtide_init();
|
||||
nmi_init();
|
||||
if (joystick_type != 7) device_add(&gameport_device);
|
||||
@@ -241,7 +255,6 @@ void tandy1k_init()
|
||||
common_init();
|
||||
mem_add_bios();
|
||||
keyboard_tandy_init();
|
||||
mouse_serial_init();
|
||||
if (romset == ROM_TANDY)
|
||||
device_add(&sn76489_device);
|
||||
else
|
||||
@@ -258,7 +271,6 @@ void tandy1ksl2_init()
|
||||
common_init();
|
||||
mem_add_bios();
|
||||
keyboard_tandy_init();
|
||||
mouse_serial_init();
|
||||
device_add(&pssj_device);
|
||||
xtide_init();
|
||||
nmi_init();
|
||||
@@ -274,7 +286,6 @@ void ams_init()
|
||||
mem_add_bios();
|
||||
amstrad_init();
|
||||
keyboard_amstrad_init();
|
||||
mouse_amstrad_init();
|
||||
nvr_init();
|
||||
xtide_init();
|
||||
nmi_init();
|
||||
@@ -288,7 +299,6 @@ void europc_init()
|
||||
mem_add_bios();
|
||||
jim_init();
|
||||
keyboard_xt_init();
|
||||
mouse_serial_init();
|
||||
xtide_init();
|
||||
nmi_init();
|
||||
if (joystick_type != 7) device_add(&gameport_device);
|
||||
@@ -299,7 +309,6 @@ void olim24_init()
|
||||
common_init();
|
||||
mem_add_bios();
|
||||
keyboard_olim24_init();
|
||||
mouse_serial_init();
|
||||
nvr_init();
|
||||
olivetti_m24_init();
|
||||
xtide_init();
|
||||
@@ -317,8 +326,6 @@ void at_init()
|
||||
dma16_init();
|
||||
ide_init();
|
||||
keyboard_at_init();
|
||||
if (models[model].init == at_init)
|
||||
mouse_serial_init();
|
||||
nvr_init();
|
||||
pic2_init();
|
||||
if (joystick_type != 7) device_add(&gameport_device);
|
||||
@@ -327,7 +334,6 @@ void at_init()
|
||||
void deskpro386_init()
|
||||
{
|
||||
at_init();
|
||||
mouse_serial_init();
|
||||
compaq_init();
|
||||
}
|
||||
|
||||
@@ -340,7 +346,6 @@ void ps1_common_init()
|
||||
dma16_init();
|
||||
ide_init();
|
||||
keyboard_at_init();
|
||||
mouse_ps2_init();
|
||||
nvr_init();
|
||||
pic2_init();
|
||||
fdc_set_dskchg_activelow();
|
||||
@@ -365,28 +370,24 @@ void ps1_m2121_init()
|
||||
void at_neat_init()
|
||||
{
|
||||
at_init();
|
||||
mouse_serial_init();
|
||||
neat_init();
|
||||
}
|
||||
|
||||
void at_scat_init()
|
||||
{
|
||||
at_init();
|
||||
mouse_serial_init();
|
||||
scat_init();
|
||||
}
|
||||
|
||||
void at_acer386sx_init()
|
||||
{
|
||||
at_init();
|
||||
mouse_ps2_init();
|
||||
acer386sx_init();
|
||||
}
|
||||
|
||||
void at_wd76c10_init()
|
||||
{
|
||||
at_init();
|
||||
mouse_ps2_init();
|
||||
wd76c10_init();
|
||||
}
|
||||
|
||||
@@ -394,21 +395,24 @@ void at_headland_init()
|
||||
{
|
||||
at_init();
|
||||
headland_init();
|
||||
mouse_serial_init();
|
||||
}
|
||||
|
||||
void at_opti495_init()
|
||||
{
|
||||
at_init();
|
||||
opti495_init();
|
||||
}
|
||||
|
||||
void at_ali1429_init()
|
||||
{
|
||||
at_init();
|
||||
ali1429_init();
|
||||
mouse_serial_init();
|
||||
if (atapi_cdrom_channel <= 1) ide_sec_disable();
|
||||
}
|
||||
|
||||
/* void at_um8881f_init()
|
||||
{
|
||||
at_init();
|
||||
mouse_serial_init();
|
||||
pci_init(PCI_CONFIG_TYPE_1, 0, 31);
|
||||
um8881f_init();
|
||||
} */
|
||||
@@ -417,7 +421,6 @@ void at_dtk486_init()
|
||||
{
|
||||
at_init();
|
||||
memregs_init();
|
||||
mouse_serial_init();
|
||||
sis85c471_init();
|
||||
if (atapi_cdrom_channel <= 1) ide_sec_disable();
|
||||
}
|
||||
@@ -426,7 +429,6 @@ void at_sis496_init()
|
||||
{
|
||||
at_init();
|
||||
memregs_init();
|
||||
mouse_serial_init();
|
||||
pci_init(PCI_CONFIG_TYPE_1, 0, 31);
|
||||
device_add(&sis496_device);
|
||||
if ((atapi_cdrom_channel >= 4) && (atapi_cdrom_channel <= 5) && cdrom_enabled && !scsi_cdrom_enabled) ide_ter_init();
|
||||
@@ -434,33 +436,32 @@ void at_sis496_init()
|
||||
|
||||
void at_r418_init()
|
||||
{
|
||||
at_init();
|
||||
memregs_init();
|
||||
mouse_serial_init();
|
||||
pci_init(PCI_CONFIG_TYPE_1, 0, 31);
|
||||
at_sis496_init();
|
||||
fdc37c665_init();
|
||||
device_add(&sis496_device);
|
||||
if ((atapi_cdrom_channel >= 4) && (atapi_cdrom_channel <= 5) && cdrom_enabled && !scsi_cdrom_enabled) ide_ter_init();
|
||||
}
|
||||
|
||||
void at_batman_init()
|
||||
void at_premiere_common_init()
|
||||
{
|
||||
at_init();
|
||||
mouse_always_serial ? mouse_serial_init() : mouse_ps2_init();
|
||||
memregs_init();
|
||||
pci_init(PCI_CONFIG_TYPE_2, 0xd, 0x10);
|
||||
i430lx_init();
|
||||
sio_init(1);
|
||||
sio_init(1);
|
||||
fdc37c665_init();
|
||||
intel_batman_init();
|
||||
device_add(&intel_flash_bxt_ami_device);
|
||||
if ((atapi_cdrom_channel >= 4) && (atapi_cdrom_channel <= 5) && cdrom_enabled && !scsi_cdrom_enabled) ide_ter_init();
|
||||
}
|
||||
|
||||
void at_batman_init()
|
||||
{
|
||||
at_premiere_common_init();
|
||||
i430lx_init();
|
||||
}
|
||||
|
||||
void at_586mc1_init()
|
||||
{
|
||||
at_init();
|
||||
memregs_init();
|
||||
mouse_serial_init();
|
||||
pci_init(PCI_CONFIG_TYPE_2, 0xd, 0x10);
|
||||
i430lx_init();
|
||||
sio_init(1);
|
||||
@@ -470,27 +471,18 @@ void at_586mc1_init()
|
||||
|
||||
void at_plato_init()
|
||||
{
|
||||
at_init();
|
||||
mouse_always_serial ? mouse_serial_init() : mouse_ps2_init();
|
||||
pci_init(PCI_CONFIG_TYPE_2, 0xd, 0x10);
|
||||
at_premiere_common_init();
|
||||
i430nx_init();
|
||||
sio_init(1);
|
||||
fdc37c665_init();
|
||||
/* It seems it uses the same interface as Batman. */
|
||||
intel_batman_init();
|
||||
device_add(&intel_flash_bxt_ami_device);
|
||||
if ((atapi_cdrom_channel >= 4) && (atapi_cdrom_channel <= 5) && cdrom_enabled && !scsi_cdrom_enabled) ide_ter_init();
|
||||
}
|
||||
|
||||
void at_advanced_common_init()
|
||||
{
|
||||
at_init();
|
||||
mouse_always_serial ? mouse_serial_init() : mouse_ps2_init();
|
||||
memregs_init();
|
||||
pci_init(PCI_CONFIG_TYPE_1, 0xd, 0x10);
|
||||
i430fx_init();
|
||||
piix_init(7);
|
||||
// pc87306_init();
|
||||
intel_endeavor_init();
|
||||
pc87306_init();
|
||||
if ((atapi_cdrom_channel >= 4) && (atapi_cdrom_channel <= 5) && cdrom_enabled && !scsi_cdrom_enabled) ide_ter_init();
|
||||
}
|
||||
|
||||
@@ -511,37 +503,45 @@ void at_marl_init()
|
||||
void at_mb500n_init()
|
||||
{
|
||||
at_init();
|
||||
mouse_serial_init();
|
||||
pci_init(PCI_CONFIG_TYPE_1, 0xd, 0x10);
|
||||
i430fx_init();
|
||||
piix_init(7);
|
||||
fdc37c665_init();
|
||||
intel_endeavor_init();
|
||||
device_add(&intel_flash_bxt_device);
|
||||
if ((atapi_cdrom_channel >= 4) && (atapi_cdrom_channel <= 5) && cdrom_enabled && !scsi_cdrom_enabled) ide_ter_init();
|
||||
}
|
||||
|
||||
#if 0
|
||||
void at_p54tp4xe_init()
|
||||
void at_powermate_v_init()
|
||||
{
|
||||
at_init();
|
||||
memregs_init();
|
||||
mouse_always_serial ? mouse_serial_init() : mouse_ps2_init();
|
||||
pci_init(PCI_CONFIG_TYPE_1, 0xd, 0x10);
|
||||
pci_init(PCI_CONFIG_TYPE_1, 0, 31);
|
||||
i430fx_init();
|
||||
piix_init(7);
|
||||
fdc37c665_init();
|
||||
intel_endeavor_init();
|
||||
acerm3a_io_init();
|
||||
device_add(&intel_flash_bxt_device);
|
||||
if ((atapi_cdrom_channel >= 4) && (atapi_cdrom_channel <= 5) && cdrom_enabled && !scsi_cdrom_enabled) ide_ter_init();
|
||||
}
|
||||
#endif
|
||||
|
||||
void at_p54tp4xe_init()
|
||||
{
|
||||
at_init();
|
||||
memregs_init();
|
||||
pci_init(PCI_CONFIG_TYPE_1, 0xd, 0x10);
|
||||
i430fx_init();
|
||||
piix_init(7);
|
||||
fdc37c665_init();
|
||||
device_add(&intel_flash_bxt_device);
|
||||
if ((atapi_cdrom_channel >= 4) && (atapi_cdrom_channel <= 5) && cdrom_enabled && !scsi_cdrom_enabled) ide_ter_init();
|
||||
}
|
||||
|
||||
void at_acerm3a_init()
|
||||
{
|
||||
at_init();
|
||||
memregs_init();
|
||||
mouse_serial_init();
|
||||
pci_init(PCI_CONFIG_TYPE_1, 0xd, 0x10);
|
||||
i430hx_init();
|
||||
piix3_init(7);
|
||||
@@ -555,7 +555,6 @@ void at_acerv35n_init()
|
||||
{
|
||||
at_init();
|
||||
memregs_init();
|
||||
mouse_always_serial ? mouse_serial_init() : mouse_ps2_init();
|
||||
pci_init(PCI_CONFIG_TYPE_1, 0xd, 0x10);
|
||||
i430hx_init();
|
||||
piix3_init(7);
|
||||
@@ -565,12 +564,10 @@ void at_acerv35n_init()
|
||||
if ((atapi_cdrom_channel >= 4) && (atapi_cdrom_channel <= 5) && cdrom_enabled && !scsi_cdrom_enabled) ide_ter_init();
|
||||
}
|
||||
|
||||
#if 0
|
||||
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();
|
||||
piix3_init(7);
|
||||
@@ -578,13 +575,11 @@ void at_p55t2p4_init()
|
||||
device_add(&intel_flash_bxt_device);
|
||||
if ((atapi_cdrom_channel >= 4) && (atapi_cdrom_channel <= 5) && cdrom_enabled && !scsi_cdrom_enabled) ide_ter_init();
|
||||
}
|
||||
#endif
|
||||
|
||||
void at_i430vx_init()
|
||||
{
|
||||
at_init();
|
||||
memregs_init();
|
||||
mouse_serial_init();
|
||||
pci_init(PCI_CONFIG_TYPE_1, 0, 31);
|
||||
i430vx_init();
|
||||
piix3_init(7);
|
||||
@@ -593,34 +588,23 @@ void at_i430vx_init()
|
||||
if ((atapi_cdrom_channel >= 4) && (atapi_cdrom_channel <= 5) && cdrom_enabled && !scsi_cdrom_enabled) ide_ter_init();
|
||||
}
|
||||
|
||||
// rom_t ami_ec_rom;
|
||||
|
||||
#if 0
|
||||
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();
|
||||
piix3_init(7);
|
||||
w83877f_init();
|
||||
device_add(&intel_flash_bxt_device);
|
||||
|
||||
/* rom_init(&ami_ec_rom, "roms/AMIINT13.BIN", 0xd0000, 0x10000, 0xffff, 0, MEM_MAPPING_EXTERNAL);
|
||||
pc87306_init();
|
||||
|
||||
intel_endeavor_init(); */
|
||||
|
||||
if ((atapi_cdrom_channel >= 4) && (atapi_cdrom_channel <= 5) && cdrom_enabled && !scsi_cdrom_enabled) ide_ter_init();
|
||||
}
|
||||
#endif
|
||||
|
||||
void at_p55va_init()
|
||||
{
|
||||
at_init();
|
||||
memregs_init();
|
||||
mouse_always_serial ? mouse_serial_init() : mouse_ps2_init();
|
||||
pci_init(PCI_CONFIG_TYPE_1, 0, 31);
|
||||
i430vx_init();
|
||||
piix3_init(7);
|
||||
@@ -633,7 +617,6 @@ void at_i440fx_init()
|
||||
{
|
||||
at_init();
|
||||
memregs_init();
|
||||
mouse_always_serial ? mouse_serial_init() : mouse_ps2_init();
|
||||
pci_init(PCI_CONFIG_TYPE_1, 0, 31);
|
||||
i440fx_init();
|
||||
piix3_init(7);
|
||||
@@ -651,4 +634,6 @@ void model_init()
|
||||
fdc_update_is_nsc(0);
|
||||
ide_ter_enabled = 0;
|
||||
models[model].init();
|
||||
if (models[model].device)
|
||||
device_add(models[model].device);
|
||||
}
|
||||
|
||||
14
src/model.h
14
src/model.h
@@ -1,6 +1,14 @@
|
||||
/* Copyright holders: Sarah Walker
|
||||
/* Copyright holders: Sarah Walker, Tohka
|
||||
see COPYING for more details
|
||||
*/
|
||||
#define MODEL_AT 1
|
||||
#define MODEL_PS2 2
|
||||
#define MODEL_AMSTRAD 4
|
||||
#define MODEL_OLIM24 8
|
||||
#define MODEL_NEC 16
|
||||
#define MODEL_FUJITSU 32
|
||||
#define MODEL_RM 64
|
||||
|
||||
typedef struct
|
||||
{
|
||||
char name[24];
|
||||
@@ -11,10 +19,11 @@ typedef struct
|
||||
CPU *cpus;
|
||||
} cpu[5];
|
||||
int fixed_gfxcard;
|
||||
int is_at;
|
||||
int flags;
|
||||
int min_ram, max_ram;
|
||||
int ram_granularity;
|
||||
void (*init)();
|
||||
struct device_t *device;
|
||||
} MODEL;
|
||||
|
||||
extern MODEL models[];
|
||||
@@ -26,3 +35,4 @@ int model_getromset();
|
||||
int model_getmodel(int romset);
|
||||
char *model_getname();
|
||||
void model_init();
|
||||
struct device_t *model_getdevice(int model);
|
||||
|
||||
51
src/mouse.c
51
src/mouse.c
@@ -1,7 +1,50 @@
|
||||
/* Copyright holders: Sarah Walker
|
||||
see COPYING for more details
|
||||
*/
|
||||
#include "ibm.h"
|
||||
#include "mouse.h"
|
||||
#include "amstrad.h"
|
||||
#include "mouse_ps2.h"
|
||||
#include "mouse_serial.h"
|
||||
#include "keyboard_olim24.h"
|
||||
|
||||
void (*mouse_poll)(int x, int y, int b);
|
||||
static mouse_t *mouse_list[] =
|
||||
{
|
||||
&mouse_serial_microsoft,
|
||||
&mouse_ps2_2_button,
|
||||
&mouse_intellimouse,
|
||||
&mouse_amstrad,
|
||||
&mouse_olim24,
|
||||
NULL
|
||||
};
|
||||
|
||||
static mouse_t *cur_mouse;
|
||||
static void *mouse_p;
|
||||
int mouse_type = 0;
|
||||
|
||||
void mouse_emu_init()
|
||||
{
|
||||
cur_mouse = mouse_list[mouse_type];
|
||||
mouse_p = cur_mouse->init();
|
||||
}
|
||||
|
||||
void mouse_emu_close()
|
||||
{
|
||||
if (cur_mouse)
|
||||
cur_mouse->close(mouse_p);
|
||||
cur_mouse = NULL;
|
||||
}
|
||||
|
||||
void mouse_poll(int x, int y, int z, int b)
|
||||
{
|
||||
if (cur_mouse)
|
||||
cur_mouse->poll(x, y, z, b, mouse_p);
|
||||
}
|
||||
|
||||
char *mouse_get_name(int mouse)
|
||||
{
|
||||
if (!mouse_list[mouse])
|
||||
return NULL;
|
||||
return mouse_list[mouse]->name;
|
||||
}
|
||||
int mouse_get_type(int mouse)
|
||||
{
|
||||
return mouse_list[mouse]->type;
|
||||
}
|
||||
|
||||
28
src/mouse.h
28
src/mouse.h
@@ -1,8 +1,24 @@
|
||||
/* Copyright holders: Sarah Walker
|
||||
see COPYING for more details
|
||||
*/
|
||||
extern void (*mouse_poll)(int x, int y, int b);
|
||||
void mouse_emu_init();
|
||||
void mouse_emu_close();
|
||||
void mouse_poll(int x, int y, int z, int b);
|
||||
|
||||
extern int mousepos;
|
||||
extern int mousedelay;
|
||||
char *mouse_get_name(int mouse);
|
||||
int mouse_get_type(int mouse);
|
||||
|
||||
#define MOUSE_TYPE_SERIAL 0
|
||||
#define MOUSE_TYPE_PS2 1
|
||||
#define MOUSE_TYPE_AMSTRAD 2
|
||||
#define MOUSE_TYPE_OLIM24 3
|
||||
|
||||
#define MOUSE_TYPE_3BUTTON (1 << 31)
|
||||
|
||||
typedef struct
|
||||
{
|
||||
char name[80];
|
||||
void *(*init)();
|
||||
void (*close)(void *p);
|
||||
uint8_t (*poll)(int x, int y, int z, int b, void *p);
|
||||
int type;
|
||||
} mouse_t;
|
||||
|
||||
extern int mouse_type;
|
||||
|
||||
@@ -1,63 +0,0 @@
|
||||
/* Copyright holders: SA1988, Curt Coder
|
||||
see COPYING for more details
|
||||
*/
|
||||
#include "ibm.h"
|
||||
#include "io.h"
|
||||
#include "mouse.h"
|
||||
#include "mouse_amstrad.h"
|
||||
|
||||
static int amstrad_x = 0, amstrad_y = 0, amstrad_b = 0;
|
||||
|
||||
uint8_t mouse_amstrad_read(uint16_t port, void *priv)
|
||||
{
|
||||
switch (port)
|
||||
{
|
||||
case 0x78:
|
||||
return amstrad_x;
|
||||
|
||||
case 0x7a:
|
||||
return amstrad_y;
|
||||
}
|
||||
return 0xff;
|
||||
}
|
||||
|
||||
void mouse_amstrad_write(uint16_t port, uint8_t val, void *priv)
|
||||
{
|
||||
switch (port)
|
||||
{
|
||||
case 0x78:
|
||||
amstrad_x = 0;
|
||||
break;
|
||||
|
||||
case 0x7a:
|
||||
amstrad_y = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void mouse_amstrad_poll(int x, int y, int b)
|
||||
{
|
||||
if (!x && !y && b==amstrad_b) return;
|
||||
|
||||
amstrad_b=b;
|
||||
if (x > amstrad_x)
|
||||
amstrad_x+=3;
|
||||
else
|
||||
amstrad_x-=3;
|
||||
|
||||
amstrad_x = x;
|
||||
|
||||
if (y > amstrad_y)
|
||||
amstrad_y+=3;
|
||||
else
|
||||
amstrad_y-=3;
|
||||
|
||||
amstrad_y = y;
|
||||
}
|
||||
|
||||
void mouse_amstrad_init()
|
||||
{
|
||||
mouse_poll = mouse_amstrad_poll;
|
||||
io_sethandler(0x0078, 0x0001, mouse_amstrad_read, NULL, NULL, mouse_amstrad_write, NULL, NULL, NULL);
|
||||
io_sethandler(0x007a, 0x0001, mouse_amstrad_read, NULL, NULL, mouse_amstrad_write, NULL, NULL, NULL);
|
||||
}
|
||||
@@ -1,4 +0,0 @@
|
||||
/* Copyright holders: SA1988
|
||||
see COPYING for more details
|
||||
*/
|
||||
void mouse_amstrad_init();
|
||||
211
src/mouse_ps2.c
211
src/mouse_ps2.c
@@ -1,6 +1,3 @@
|
||||
/* Copyright holders: Sarah Walker
|
||||
see COPYING for more details
|
||||
*/
|
||||
#include "ibm.h"
|
||||
#include "keyboard_at.h"
|
||||
#include "mouse.h"
|
||||
@@ -19,7 +16,7 @@ enum
|
||||
#define MOUSE_ENABLE 0x20
|
||||
#define MOUSE_SCALE 0x10
|
||||
|
||||
static struct
|
||||
typedef struct mouse_ps2_t
|
||||
{
|
||||
int mode;
|
||||
|
||||
@@ -30,56 +27,63 @@ static struct
|
||||
uint8_t command;
|
||||
|
||||
int cd;
|
||||
} mouse_ps2;
|
||||
|
||||
int x, y, z, b;
|
||||
|
||||
int is_intellimouse;
|
||||
int intellimouse_mode;
|
||||
|
||||
uint8_t last_data[6];
|
||||
} mouse_ps2_t;
|
||||
|
||||
void mouse_ps2_write(uint8_t val)
|
||||
void mouse_ps2_write(uint8_t val, void *p)
|
||||
{
|
||||
// pclog("PS/2 Mouse: Write %02X\n", val);
|
||||
|
||||
if (mouse_ps2.cd)
|
||||
mouse_ps2_t *mouse = (mouse_ps2_t *)p;
|
||||
|
||||
if (mouse->cd)
|
||||
{
|
||||
mouse_ps2.cd = 0;
|
||||
switch (mouse_ps2.command)
|
||||
mouse->cd = 0;
|
||||
switch (mouse->command)
|
||||
{
|
||||
case 0xe8: /*Set mouse resolution*/
|
||||
mouse_ps2.resolution = val;
|
||||
mouse->resolution = val;
|
||||
keyboard_at_adddata_mouse(0xfa);
|
||||
break;
|
||||
|
||||
case 0xf3: /*Set sample rate*/
|
||||
mouse_ps2.sample_rate = val;
|
||||
mouse->sample_rate = val;
|
||||
keyboard_at_adddata_mouse(0xfa);
|
||||
break;
|
||||
|
||||
// default:
|
||||
// fatal("mouse_ps2 : Bad data write %02X for command %02X\n", val, mouse_ps2.command);
|
||||
// fatal("mouse_ps2 : Bad data write %02X for command %02X\n", val, mouse->command);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
uint8_t temp;
|
||||
|
||||
mouse_ps2.command = val;
|
||||
switch (mouse_ps2.command)
|
||||
mouse->command = val;
|
||||
switch (mouse->command)
|
||||
{
|
||||
case 0xe6: /*Set scaling to 1:1*/
|
||||
mouse_ps2.flags &= ~MOUSE_SCALE;
|
||||
mouse->flags &= ~MOUSE_SCALE;
|
||||
keyboard_at_adddata_mouse(0xfa);
|
||||
break;
|
||||
|
||||
case 0xe7: /*Set scaling to 2:1*/
|
||||
mouse_ps2.flags |= MOUSE_SCALE;
|
||||
mouse->flags |= MOUSE_SCALE;
|
||||
keyboard_at_adddata_mouse(0xfa);
|
||||
break;
|
||||
|
||||
case 0xe8: /*Set mouse resolution*/
|
||||
mouse_ps2.cd = 1;
|
||||
mouse->cd = 1;
|
||||
keyboard_at_adddata_mouse(0xfa);
|
||||
break;
|
||||
|
||||
case 0xe9: /*Status request*/
|
||||
keyboard_at_adddata_mouse(0xfa);
|
||||
temp = mouse_ps2.flags;
|
||||
temp = mouse->flags;
|
||||
if (mouse_buttons & 1)
|
||||
temp |= 1;
|
||||
if (mouse_buttons & 2)
|
||||
@@ -87,105 +91,162 @@ void mouse_ps2_write(uint8_t val)
|
||||
if (mouse_buttons & 4)
|
||||
temp |= 3;
|
||||
keyboard_at_adddata_mouse(temp);
|
||||
keyboard_at_adddata_mouse(mouse_ps2.resolution);
|
||||
keyboard_at_adddata_mouse(mouse_ps2.sample_rate);
|
||||
keyboard_at_adddata_mouse(mouse->resolution);
|
||||
keyboard_at_adddata_mouse(mouse->sample_rate);
|
||||
break;
|
||||
|
||||
case 0xf2: /*Read ID*/
|
||||
keyboard_at_adddata_mouse(0xfa);
|
||||
keyboard_at_adddata_mouse(0x00);
|
||||
if (mouse->intellimouse_mode)
|
||||
keyboard_at_adddata_mouse(0x03);
|
||||
else
|
||||
keyboard_at_adddata_mouse(0x00);
|
||||
break;
|
||||
|
||||
case 0xf3: /*Set sample rate*/
|
||||
mouse_ps2.cd = 1;
|
||||
mouse->cd = 1;
|
||||
keyboard_at_adddata_mouse(0xfa);
|
||||
break;
|
||||
|
||||
case 0xf4: /*Enable*/
|
||||
mouse_ps2.flags |= MOUSE_ENABLE;
|
||||
mouse->flags |= MOUSE_ENABLE;
|
||||
keyboard_at_adddata_mouse(0xfa);
|
||||
break;
|
||||
|
||||
case 0xf5: /*Disable*/
|
||||
mouse_ps2.flags &= ~MOUSE_ENABLE;
|
||||
mouse->flags &= ~MOUSE_ENABLE;
|
||||
keyboard_at_adddata_mouse(0xfa);
|
||||
break;
|
||||
|
||||
case 0xff: /*Reset*/
|
||||
mouse_ps2.mode = MOUSE_STREAM;
|
||||
mouse_ps2.flags = 0;
|
||||
mouse->mode = MOUSE_STREAM;
|
||||
mouse->flags = 0;
|
||||
mouse->intellimouse_mode = 0;
|
||||
keyboard_at_adddata_mouse(0xfa);
|
||||
keyboard_at_adddata_mouse(0xaa);
|
||||
keyboard_at_adddata_mouse(0x00);
|
||||
break;
|
||||
|
||||
// default:
|
||||
// fatal("mouse_ps2 : Bad command %02X\n", val, mouse_ps2.command);
|
||||
// fatal("mouse_ps2 : Bad command %02X\n", val, mouse->command);
|
||||
}
|
||||
}
|
||||
|
||||
if (mouse->is_intellimouse)
|
||||
{
|
||||
int c;
|
||||
|
||||
for (c = 0; c < 5; c++)
|
||||
mouse->last_data[c] = mouse->last_data[c+1];
|
||||
|
||||
mouse->last_data[5] = val;
|
||||
|
||||
if (mouse->last_data[0] == 0xf3 && mouse->last_data[1] == 0xc8 &&
|
||||
mouse->last_data[2] == 0xf3 && mouse->last_data[3] == 0x64 &&
|
||||
mouse->last_data[4] == 0xf3 && mouse->last_data[5] == 0x50)
|
||||
mouse->intellimouse_mode = 1;
|
||||
}
|
||||
}
|
||||
|
||||
static int ps2_x = 0, ps2_y = 0, ps2_b = 0;
|
||||
int first_time = 1;
|
||||
void mouse_ps2_poll(int x, int y, int b)
|
||||
void mouse_ps2_poll(int x, int y, int z, int b, void *p)
|
||||
{
|
||||
mouse_ps2_t *mouse = (mouse_ps2_t *)p;
|
||||
uint8_t packet[3] = {0x08, 0, 0};
|
||||
if (!x && !y && b == ps2_b && !first_time){
|
||||
// pclog("PS/2 Mouse: X is 0, Y is 0, and B is PS2_B\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (first_time) first_time = 0;
|
||||
|
||||
if (!x && !y && !z && b == mouse->b)
|
||||
return;
|
||||
|
||||
if (!mouse_scan)
|
||||
{
|
||||
// pclog("PS/2 Mouse: Not scanning\n");
|
||||
return;
|
||||
}
|
||||
ps2_x += x;
|
||||
ps2_y -= y;
|
||||
if (mouse_ps2.mode == MOUSE_STREAM && (mouse_ps2.flags & MOUSE_ENABLE) &&
|
||||
|
||||
mouse->x += x;
|
||||
mouse->y -= y;
|
||||
mouse->z -= z;
|
||||
if (mouse->mode == MOUSE_STREAM && (mouse->flags & MOUSE_ENABLE) &&
|
||||
((mouse_queue_end - mouse_queue_start) & 0xf) < 13)
|
||||
{
|
||||
ps2_b = b;
|
||||
mouse->b = b;
|
||||
// pclog("Send packet : %i %i\n", ps2_x, ps2_y);
|
||||
if (ps2_x > 255)
|
||||
ps2_x = 255;
|
||||
if (ps2_x < -256)
|
||||
ps2_x = -256;
|
||||
if (ps2_y > 255)
|
||||
ps2_y = 255;
|
||||
if (ps2_y < -256)
|
||||
ps2_y = -256;
|
||||
if (ps2_x < 0)
|
||||
packet[0] |= 0x10;
|
||||
if (ps2_y < 0)
|
||||
packet[0] |= 0x20;
|
||||
if (mouse->x > 255)
|
||||
mouse->x = 255;
|
||||
if (mouse->x < -256)
|
||||
mouse->x = -256;
|
||||
if (mouse->y > 255)
|
||||
mouse->y = 255;
|
||||
if (mouse->y < -256)
|
||||
mouse->y = -256;
|
||||
if (mouse->z < -8)
|
||||
mouse->z = -8;
|
||||
if (mouse->z > 7)
|
||||
mouse->z = 7;
|
||||
if (mouse->x < 0)
|
||||
packet[0] |= 0x10;
|
||||
if (mouse->y < 0)
|
||||
packet[0] |= 0x20;
|
||||
if (mouse_buttons & 1)
|
||||
packet[0] |= 1;
|
||||
packet[0] |= 1;
|
||||
if (mouse_buttons & 2)
|
||||
packet[0] |= 2;
|
||||
if (mouse_buttons & 4)
|
||||
packet[0] |= 4;
|
||||
packet[1] = ps2_x & 0xff;
|
||||
packet[2] = ps2_y & 0xff;
|
||||
|
||||
ps2_x = ps2_y = 0;
|
||||
|
||||
packet[0] |= 2;
|
||||
if ((mouse_buttons & 4) && (mouse_get_type(mouse_type) & MOUSE_TYPE_3BUTTON))
|
||||
packet[0] |= 4;
|
||||
packet[1] = mouse->x & 0xff;
|
||||
packet[2] = mouse->y & 0xff;
|
||||
|
||||
keyboard_at_adddata_mouse(packet[0]);
|
||||
keyboard_at_adddata_mouse(packet[1]);
|
||||
keyboard_at_adddata_mouse(packet[2]);
|
||||
if (mouse->intellimouse_mode)
|
||||
keyboard_at_adddata_mouse(mouse->z);
|
||||
|
||||
mouse->x = mouse->y = mouse->z = 0;
|
||||
}
|
||||
|
||||
// pclog("PS/2 Mouse: Poll\n");
|
||||
}
|
||||
|
||||
|
||||
void mouse_ps2_init()
|
||||
void *mouse_ps2_init()
|
||||
{
|
||||
mouse_poll = mouse_ps2_poll;
|
||||
mouse_write = mouse_ps2_write;
|
||||
mouse_ps2.cd = 0;
|
||||
mouse_ps2.flags = 0;
|
||||
mouse_ps2.mode = MOUSE_STREAM;
|
||||
mouse_ps2_t *mouse = (mouse_ps2_t *)malloc(sizeof(mouse_ps2_t));
|
||||
memset(mouse, 0, sizeof(mouse_ps2_t));
|
||||
|
||||
// mouse_poll = mouse_ps2_poll;
|
||||
// mouse_write = mouse_ps2_write;
|
||||
mouse->cd = 0;
|
||||
mouse->flags = 0;
|
||||
mouse->mode = MOUSE_STREAM;
|
||||
|
||||
keyboard_at_set_mouse(mouse_ps2_write, mouse);
|
||||
|
||||
return mouse;
|
||||
}
|
||||
|
||||
void *mouse_intellimouse_init()
|
||||
{
|
||||
mouse_ps2_t *mouse = mouse_ps2_init();
|
||||
|
||||
mouse->is_intellimouse = 1;
|
||||
|
||||
return mouse;
|
||||
}
|
||||
|
||||
void mouse_ps2_close(void *p)
|
||||
{
|
||||
mouse_ps2_t *mouse = (mouse_ps2_t *)p;
|
||||
|
||||
free(mouse);
|
||||
}
|
||||
|
||||
mouse_t mouse_ps2_2_button =
|
||||
{
|
||||
"2-button mouse (PS/2)",
|
||||
mouse_ps2_init,
|
||||
mouse_ps2_close,
|
||||
mouse_ps2_poll,
|
||||
MOUSE_TYPE_PS2
|
||||
};
|
||||
mouse_t mouse_intellimouse =
|
||||
{
|
||||
"Microsoft Intellimouse (PS/2)",
|
||||
mouse_intellimouse_init,
|
||||
mouse_ps2_close,
|
||||
mouse_ps2_poll,
|
||||
MOUSE_TYPE_PS2 | MOUSE_TYPE_3BUTTON
|
||||
};
|
||||
|
||||
@@ -1,4 +1,2 @@
|
||||
/* Copyright holders: Sarah Walker
|
||||
see COPYING for more details
|
||||
*/
|
||||
void mouse_ps2_init();
|
||||
extern mouse_t mouse_ps2_2_button;
|
||||
extern mouse_t mouse_intellimouse;
|
||||
|
||||
@@ -1,23 +1,28 @@
|
||||
/* Copyright holders: Sarah Walker
|
||||
see COPYING for more details
|
||||
*/
|
||||
#include "ibm.h"
|
||||
#include "mouse.h"
|
||||
#include "pic.h"
|
||||
#include "serial.h"
|
||||
#include "timer.h"
|
||||
|
||||
static int oldb=0;
|
||||
|
||||
void mouse_serial_poll(int x, int y, int b)
|
||||
typedef struct mouse_serial_t
|
||||
{
|
||||
uint8_t mousedat[3];
|
||||
|
||||
if (!(serial1.ier & 1))
|
||||
return;
|
||||
if (!x && !y && b==oldb) return;
|
||||
int mousepos, mousedelay;
|
||||
int oldb;
|
||||
SERIAL *serial;
|
||||
} mouse_serial_t;
|
||||
|
||||
oldb=b;
|
||||
void mouse_serial_poll(int x, int y, int z, int b, void *p)
|
||||
{
|
||||
mouse_serial_t *mouse = (mouse_serial_t *)p;
|
||||
SERIAL *serial = mouse->serial;
|
||||
uint8_t mousedat[3];
|
||||
|
||||
if (!(serial->ier & 1))
|
||||
return;
|
||||
if (!x && !y && b == mouse->oldb)
|
||||
return;
|
||||
|
||||
mouse->oldb = b;
|
||||
if (x>127) x=127;
|
||||
if (y>127) y=127;
|
||||
if (x<-128) x=-128;
|
||||
@@ -32,44 +37,62 @@ void mouse_serial_poll(int x, int y, int b)
|
||||
mousedat[1]=x&0x3F;
|
||||
mousedat[2]=y&0x3F;
|
||||
|
||||
if (!(serial1.mctrl&0x10))
|
||||
if (!(serial->mctrl & 0x10))
|
||||
{
|
||||
// pclog("Serial data %02X %02X %02X\n", mousedat[0], mousedat[1], mousedat[2]);
|
||||
serial_write_fifo(&serial1, mousedat[0]);
|
||||
serial_write_fifo(&serial1, mousedat[1]);
|
||||
serial_write_fifo(&serial1, mousedat[2]);
|
||||
// pclog("Serial data %02X %02X %02X\n", mousedat[0], mousedat[1], mousedat[2]);
|
||||
serial_write_fifo(mouse->serial, mousedat[0]);
|
||||
serial_write_fifo(mouse->serial, mousedat[1]);
|
||||
serial_write_fifo(mouse->serial, mousedat[2]);
|
||||
}
|
||||
}
|
||||
|
||||
void mouse_serial_rcr(void *p)
|
||||
void mouse_serial_rcr(SERIAL *serial, void *p)
|
||||
{
|
||||
mousepos=-1;
|
||||
mousedelay=5000 * (1 << TIMER_SHIFT);
|
||||
mouse_serial_t *mouse = (mouse_serial_t *)p;
|
||||
|
||||
mouse->mousepos = -1;
|
||||
mouse->mousedelay = 5000 * (1 << TIMER_SHIFT);
|
||||
}
|
||||
|
||||
void mousecallback(void *p)
|
||||
{
|
||||
SERIAL *serial = (SERIAL *)p;
|
||||
mousedelay = 0;
|
||||
if (mousepos == -1)
|
||||
mouse_serial_t *mouse = (mouse_serial_t *)p;
|
||||
|
||||
mouse->mousedelay = 0;
|
||||
if (mouse->mousepos == -1)
|
||||
{
|
||||
mousepos = 0;
|
||||
/* serial_fifo_read = serial_fifo_write = 0;
|
||||
serial.lsr &= ~1;*/
|
||||
serial_write_fifo(serial, 'M');
|
||||
mouse->mousepos = 0;
|
||||
serial_write_fifo(mouse->serial, 'M');
|
||||
}
|
||||
/* else if (serial_fifo_read != serial_fifo_write)
|
||||
{
|
||||
serial.iir=4;
|
||||
serial.lsr|=1;
|
||||
if (serial.mctrl&8) picint(0x10);
|
||||
}*/
|
||||
}
|
||||
|
||||
void mouse_serial_init()
|
||||
void *mouse_serial_init()
|
||||
{
|
||||
mouse_poll = mouse_serial_poll;
|
||||
mouse_serial_t *mouse = (mouse_t *)malloc(sizeof(mouse_serial_t));
|
||||
memset(mouse, 0, sizeof(mouse_serial_t));
|
||||
|
||||
mouse->serial = &serial1;
|
||||
serial1.rcr_callback = mouse_serial_rcr;
|
||||
timer_add(mousecallback, &mousedelay, &mousedelay, &serial1);
|
||||
serial1.rcr_callback_p = mouse;
|
||||
timer_add(mousecallback, &mouse->mousedelay, &mouse->mousedelay, mouse);
|
||||
|
||||
return mouse;
|
||||
}
|
||||
|
||||
void mouse_serial_close(void *p)
|
||||
{
|
||||
mouse_serial_t *mouse = (mouse_serial_t *)p;
|
||||
|
||||
free(mouse);
|
||||
|
||||
serial1.rcr_callback = NULL;
|
||||
}
|
||||
|
||||
mouse_t mouse_serial_microsoft =
|
||||
{
|
||||
"Microsoft 2-button mouse (serial)",
|
||||
mouse_serial_init,
|
||||
mouse_serial_close,
|
||||
mouse_serial_poll,
|
||||
MOUSE_TYPE_SERIAL
|
||||
};
|
||||
|
||||
@@ -1,4 +1 @@
|
||||
/* Copyright holders: Sarah Walker
|
||||
see COPYING for more details
|
||||
*/
|
||||
void mouse_serial_init();
|
||||
extern mouse_t mouse_serial_microsoft;
|
||||
|
||||
24
src/nvr.c
24
src/nvr.c
@@ -15,6 +15,8 @@ int nvr_dosave = 0;
|
||||
|
||||
static int nvr_onesec_time = 0, nvr_onesec_cnt = 0;
|
||||
|
||||
static int rtctime;
|
||||
|
||||
void getnvrtime()
|
||||
{
|
||||
time_get(nvrram);
|
||||
@@ -214,7 +216,7 @@ void loadnvr()
|
||||
case ROM_DESKPRO_386: f = romfopen(nvr_concat("deskpro386.nvr"), "rb"); break;
|
||||
case ROM_ACER386: f = romfopen(nvr_concat("acer386.nvr"), "rb"); nvrmask = 127; break;
|
||||
case ROM_MEGAPC: f = romfopen(nvr_concat("megapc.nvr"), "rb"); nvrmask = 127; break;
|
||||
case ROM_AMI386: f = romfopen(nvr_concat("ami386.nvr"), "rb"); nvrmask = 127; break;
|
||||
case ROM_AMI386SX: f = romfopen(nvr_concat("ami386.nvr"), "rb"); nvrmask = 127; break;
|
||||
case ROM_AMI486: f = romfopen(nvr_concat("ami486.nvr"), "rb"); nvrmask = 127; break;
|
||||
case ROM_WIN486: f = romfopen(nvr_concat("win486.nvr"), "rb"); nvrmask = 127; break;
|
||||
case ROM_PCI486: f = romfopen(nvr_concat("hot-433.nvr"), "rb"); nvrmask = 127; break;
|
||||
@@ -224,17 +226,26 @@ void loadnvr()
|
||||
case ROM_ENDEAVOR: f = romfopen(nvr_concat("endeavor.nvr"), "rb"); nvrmask = 127; break;
|
||||
case ROM_PX386: f = romfopen(nvr_concat("px386.nvr"), "rb"); nvrmask = 127; break;
|
||||
case ROM_DTK386: f = romfopen(nvr_concat("dtk386.nvr"), "rb"); nvrmask = 127; break;
|
||||
case ROM_MR386DX_OPTI495: f = romfopen(nvr_concat("mr386dx_opti495.nvr"), "rb"); nvrmask = 127; break;
|
||||
case ROM_AMI386DX_OPTI495: f = romfopen(nvr_concat("ami386dx_opti495.nvr"), "rb"); nvrmask = 127; break;
|
||||
case ROM_DTK486: f = romfopen(nvr_concat("dtk486.nvr"), "rb"); nvrmask = 127; break;
|
||||
case ROM_R418: f = romfopen(nvr_concat("r418.nvr"), "rb"); nvrmask = 127; break;
|
||||
case ROM_586MC1: f = romfopen(nvr_concat("586mc1.nvr"), "rb"); nvrmask = 127; break;
|
||||
case ROM_PLATO: f = romfopen(nvr_concat("plato.nvr"), "rb"); nvrmask = 127; break;
|
||||
case ROM_MB500N: f = romfopen(nvr_concat("mb500n.nvr"), "rb"); nvrmask = 127; break;
|
||||
#if 0
|
||||
case ROM_POWERMATE_V: f = romfopen(nvr_concat("powermate_v.nvr"), "rb"); nvrmask = 127; break;
|
||||
#endif
|
||||
case ROM_P54TP4XE: f = romfopen(nvr_concat("p54tp4xe.nvr"), "rb"); nvrmask = 127; break;
|
||||
case ROM_ACERM3A: f = romfopen(nvr_concat("acerm3a.nvr"), "rb"); nvrmask = 127; break;
|
||||
case ROM_ACERV35N: f = romfopen(nvr_concat("acerv35n.nvr"), "rb"); nvrmask = 127; break;
|
||||
case ROM_P55VA: f = romfopen(nvr_concat("p55va.nvr"), "rb"); nvrmask = 127; break;
|
||||
case ROM_P55T2P4: f = romfopen(nvr_concat("p55t2p4.nvr"), "rb"); nvrmask = 127; break;
|
||||
case ROM_P55TVP4: f = romfopen(nvr_concat("p55tvp4.nvr"), "rb"); nvrmask = 127; break;
|
||||
case ROM_440FX: f = romfopen(nvr_concat("440fx.nvr"), "rb"); nvrmask = 127; break;
|
||||
case ROM_MARL: f = romfopen(nvr_concat("marl.nvr"), "rb"); nvrmask = 127; break;
|
||||
case ROM_THOR: f = romfopen(nvr_concat("thor.nvr"), "rb"); nvrmask = 127; break;
|
||||
case ROM_MRTHOR: f = romfopen(nvr_concat("mrthor.nvr"), "rb"); nvrmask = 127; break;
|
||||
default: return;
|
||||
}
|
||||
if (!f)
|
||||
@@ -282,7 +293,7 @@ void savenvr()
|
||||
case ROM_DESKPRO_386: f = romfopen(nvr_concat("deskpro386.nvr"), "wb"); break;
|
||||
case ROM_ACER386: f = romfopen(nvr_concat("acer386.nvr"), "wb"); break;
|
||||
case ROM_MEGAPC: f = romfopen(nvr_concat("megapc.nvr"), "wb"); break;
|
||||
case ROM_AMI386: f = romfopen(nvr_concat("ami386.nvr"), "wb"); break;
|
||||
case ROM_AMI386SX: f = romfopen(nvr_concat("ami386.nvr"), "wb"); break;
|
||||
case ROM_AMI486: f = romfopen(nvr_concat("ami486.nvr"), "wb"); break;
|
||||
case ROM_WIN486: f = romfopen(nvr_concat("win486.nvr"), "wb"); break;
|
||||
case ROM_PCI486: f = romfopen(nvr_concat("hot-433.nvr"), "wb"); break;
|
||||
@@ -292,17 +303,26 @@ void savenvr()
|
||||
case ROM_ENDEAVOR: f = romfopen(nvr_concat("endeavor.nvr"), "wb"); break;
|
||||
case ROM_PX386: f = romfopen(nvr_concat("px386.nvr"), "wb"); break;
|
||||
case ROM_DTK386: f = romfopen(nvr_concat("dtk386.nvr"), "wb"); break;
|
||||
case ROM_MR386DX_OPTI495: f = romfopen(nvr_concat("mr386dx_opti495.nvr"), "wb"); break;
|
||||
case ROM_AMI386DX_OPTI495: f = romfopen(nvr_concat("ami386dx_opti495.nvr"), "wb"); break;
|
||||
case ROM_DTK486: f = romfopen(nvr_concat("dtk486.nvr"), "wb"); break;
|
||||
case ROM_R418: f = romfopen(nvr_concat("r418.nvr"), "wb"); break;
|
||||
case ROM_586MC1: f = romfopen(nvr_concat("586mc1.nvr"), "wb"); break;
|
||||
case ROM_PLATO: f = romfopen(nvr_concat("plato.nvr"), "wb"); break;
|
||||
case ROM_MB500N: f = romfopen(nvr_concat("mb500n.nvr"), "wb"); break;
|
||||
#if 0
|
||||
case ROM_POWERMATE_V: f = romfopen(nvr_concat("powermate_v.nvr"), "wb"); break;
|
||||
#endif
|
||||
case ROM_P54TP4XE: f = romfopen(nvr_concat("p54tp4xe.nvr"), "wb"); break;
|
||||
case ROM_ACERM3A: f = romfopen(nvr_concat("acerm3a.nvr"), "wb"); break;
|
||||
case ROM_ACERV35N: f = romfopen(nvr_concat("acerv35n.nvr"), "wb"); break;
|
||||
case ROM_P55VA: f = romfopen(nvr_concat("p55va.nvr"), "wb"); break;
|
||||
case ROM_P55T2P4: f = romfopen(nvr_concat("p55t2p4.nvr"), "wb"); break;
|
||||
case ROM_P55TVP4: f = romfopen(nvr_concat("p55tvp4.nvr"), "wb"); break;
|
||||
case ROM_440FX: f = romfopen(nvr_concat("440fx.nvr"), "wb"); break;
|
||||
case ROM_MARL: f = romfopen(nvr_concat("marl.nvr"), "wb"); break;
|
||||
case ROM_THOR: f = romfopen(nvr_concat("thor.nvr"), "wb"); break;
|
||||
case ROM_MRTHOR: f = romfopen(nvr_concat("mrthor.nvr"), "wb"); break;
|
||||
default: return;
|
||||
}
|
||||
fwrite(nvrram,128,1,f);
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
/* Copyright holders: Sarah Walker
|
||||
see COPYING for more details
|
||||
*/
|
||||
/*OPTi 82C495 emulation
|
||||
This is the chipset used in the AMI386 model*/
|
||||
#include "ibm.h"
|
||||
#include "cpu.h"
|
||||
#include "io.h"
|
||||
#include "mem.h"
|
||||
|
||||
uint8_t optiregs[0x10];
|
||||
int optireg;
|
||||
static uint8_t optiregs[0x10];
|
||||
static int optireg;
|
||||
|
||||
void writeopti(uint16_t addr, uint8_t val)
|
||||
static void opti495_write(uint16_t addr, uint8_t val, void *p)
|
||||
{
|
||||
switch (addr)
|
||||
{
|
||||
@@ -17,23 +17,50 @@ void writeopti(uint16_t addr, uint8_t val)
|
||||
break;
|
||||
case 0x24:
|
||||
printf("Writing OPTI reg %02X %02X\n",optireg,val);
|
||||
if (optireg>=0x20 && optireg<=0x2C) optiregs[optireg-0x20]=val;
|
||||
if (optireg>=0x20 && optireg<=0x2C)
|
||||
{
|
||||
optiregs[optireg-0x20]=val;
|
||||
if (optireg == 0x21)
|
||||
{
|
||||
cpu_cache_ext_enabled = val & 0x10;
|
||||
cpu_update_waitstates();
|
||||
}
|
||||
if (optireg == 0x22)
|
||||
{
|
||||
shadowbios = !(val & 0x80);
|
||||
shadowbios_write = val & 0x80;
|
||||
//pclog("shadowbios %i %02x\n", shadowbios, val);
|
||||
if (shadowbios)
|
||||
mem_set_mem_state(0xf0000, 0x10000, MEM_READ_INTERNAL | MEM_WRITE_DISABLED);
|
||||
else
|
||||
mem_set_mem_state(0xf0000, 0x10000, MEM_READ_EXTERNAL | MEM_WRITE_INTERNAL);
|
||||
// if (shadowbios)
|
||||
// fatal("Here\n");
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t readopti(uint16_t addr)
|
||||
static uint8_t opti495_read(uint16_t addr, void *p)
|
||||
{
|
||||
switch (addr)
|
||||
{
|
||||
case 0x24:
|
||||
printf("Read OPTI reg %02X\n",optireg);
|
||||
//printf("Read OPTI reg %02X\n",optireg);
|
||||
if (optireg>=0x20 && optireg<=0x2C) return optiregs[optireg-0x20];
|
||||
break;
|
||||
}
|
||||
return 0xFF;
|
||||
}
|
||||
|
||||
void opti495_init()
|
||||
{
|
||||
io_sethandler(0x0022, 0x0001, opti495_read, NULL, NULL, opti495_write, NULL, NULL, NULL);
|
||||
io_sethandler(0x0024, 0x0001, opti495_read, NULL, NULL, opti495_write, NULL, NULL, NULL);
|
||||
optiregs[0x22-0x20] = 0x80;
|
||||
}
|
||||
|
||||
/*Details for the chipset from Ralph Brown's interrupt list
|
||||
This describes the OPTi 82C493, the 82C495 seems similar except there is one
|
||||
more register (2C)
|
||||
1
src/opti495.h
Normal file
1
src/opti495.h
Normal file
@@ -0,0 +1 @@
|
||||
void opti495_init();
|
||||
87
src/pc.c
87
src/pc.c
@@ -9,7 +9,6 @@
|
||||
#include "device.h"
|
||||
|
||||
#include "ali1429.h"
|
||||
#include "amstrad.h"
|
||||
#include "cdrom-ioctl.h"
|
||||
#include "disc.h"
|
||||
#include "mem.h"
|
||||
@@ -46,6 +45,7 @@
|
||||
#include "timer.h"
|
||||
#include "vid_voodoo.h"
|
||||
#include "video.h"
|
||||
#include "amstrad.h"
|
||||
#include "nethandler.h"
|
||||
#define NE2000 1
|
||||
#define RTL8029AS 2
|
||||
@@ -58,7 +58,6 @@ int path_len;
|
||||
int window_w, window_h, window_x, window_y, window_remember;
|
||||
|
||||
int start_in_fullscreen = 0;
|
||||
int frame = 0;
|
||||
|
||||
int scsi_cdrom_enabled;
|
||||
int cdrom_enabled;
|
||||
@@ -75,7 +74,6 @@ extern int readlnum,writelnum;
|
||||
void fullspeed();
|
||||
|
||||
int framecount,fps;
|
||||
int intcount;
|
||||
|
||||
int output;
|
||||
int atfullspeed;
|
||||
@@ -115,15 +113,15 @@ uint8_t cgastat;
|
||||
int pollmouse_delay = 2;
|
||||
void pollmouse()
|
||||
{
|
||||
int x,y;
|
||||
int x, y, z;
|
||||
// return;
|
||||
pollmouse_delay--;
|
||||
if (pollmouse_delay) return;
|
||||
pollmouse_delay = 2;
|
||||
mouse_poll_host();
|
||||
mouse_get_mickeys(&x,&y);
|
||||
mouse_get_mickeys(&x, &y, &z);
|
||||
if (mouse_poll)
|
||||
mouse_poll(x, y, mouse_buttons);
|
||||
mouse_poll(x, y, z, mouse_buttons);
|
||||
// if (mousecapture) position_mouse(64,64);
|
||||
}
|
||||
|
||||
@@ -187,7 +185,6 @@ void pc_reset()
|
||||
{
|
||||
cpu_set();
|
||||
resetx86();
|
||||
mem_updatecache();
|
||||
//timer_reset();
|
||||
dma_reset();
|
||||
fdc_reset();
|
||||
@@ -288,6 +285,8 @@ void initpc(int argc, char *argv[])
|
||||
|
||||
disc_load(0, discfns[0]);
|
||||
disc_load(1, discfns[1]);
|
||||
disc_load(2, discfns[2]);
|
||||
disc_load(3, discfns[3]);
|
||||
|
||||
//loadfont();
|
||||
loadnvr();
|
||||
@@ -386,6 +385,7 @@ void resetpchard()
|
||||
saveconfig();
|
||||
|
||||
device_close_all();
|
||||
mouse_emu_close();
|
||||
device_init();
|
||||
|
||||
midi_close();
|
||||
@@ -398,6 +398,7 @@ void resetpchard()
|
||||
disc_reset();
|
||||
|
||||
model_init();
|
||||
mouse_emu_init();
|
||||
// mem_add_bios();
|
||||
video_init();
|
||||
speaker_init();
|
||||
@@ -435,6 +436,8 @@ void resetpchard()
|
||||
|
||||
keyboard_at_reset();
|
||||
|
||||
cpu_cache_int_enabled = cpu_cache_ext_enabled = 0;
|
||||
|
||||
// output=3;
|
||||
|
||||
if ((cdrom_drive == -1) || (cdrom_drive == 0))
|
||||
@@ -539,19 +542,16 @@ void runpc()
|
||||
egareads=egawrites=0;
|
||||
cycles_lost = 0;
|
||||
mmuflush=0;
|
||||
intcount=0;
|
||||
intcount=pitcount=0;
|
||||
emu_fps = frames;
|
||||
frames = 0;
|
||||
}
|
||||
if (win_title_update)
|
||||
{
|
||||
win_title_update=0;
|
||||
sprintf(s, "86Box v%s - %i%% - %s - %s - %s", emulator_version, fps, model_getname(), models[model].cpu[cpu_manufacturer].cpus[cpu].name, (!mousecapture) ? "Click to capture mouse" : "Press F12-F8 or middle button to release mouse");
|
||||
sprintf(s, "86Box v%s - %i%% - %s - %s - %s", emulator_version, fps, model_getname(), models[model].cpu[cpu_manufacturer].cpus[cpu].name, (!mousecapture) ? "Click to capture mouse" : ((mouse_get_type(mouse_type) & MOUSE_TYPE_3BUTTON) ? "Press F12-F8 to release mouse" : "Press F12-F8 or middle button to release mouse"));
|
||||
set_window_title(s);
|
||||
}
|
||||
done++;
|
||||
frame++;
|
||||
}
|
||||
|
||||
void fullspeed()
|
||||
@@ -577,7 +577,6 @@ void speedchanged()
|
||||
setpitclock(models[model].cpu[cpu_manufacturer].cpus[cpu].rspeed);
|
||||
else
|
||||
setpitclock(14318184.0);
|
||||
mem_updatecache();
|
||||
nvr_recalc();
|
||||
}
|
||||
|
||||
@@ -591,6 +590,8 @@ void closepc()
|
||||
// while (1) runpc();
|
||||
disc_close(0);
|
||||
disc_close(1);
|
||||
disc_close(2);
|
||||
disc_close(3);
|
||||
dumpregs();
|
||||
closevideo();
|
||||
device_close_all();
|
||||
@@ -610,8 +611,6 @@ void closepc()
|
||||
|
||||
END_OF_MAIN();*/
|
||||
|
||||
int cga_comp=0;
|
||||
|
||||
void loadconfig(char *fn)
|
||||
{
|
||||
int c, d;
|
||||
@@ -649,6 +648,8 @@ void loadconfig(char *fn)
|
||||
cpu = config_get_int(NULL, "cpu", 0);
|
||||
cpu_use_dynarec = config_get_int(NULL, "cpu_use_dynarec", 0);
|
||||
|
||||
cpu_waitstates = config_get_int(NULL, "cpu_waitstates", 0);
|
||||
|
||||
gfxcard = config_get_int(NULL, "gfxcard", 0);
|
||||
video_speed = config_get_int(NULL, "video_speed", 3);
|
||||
sound_card_current = config_get_int(NULL, "sndcard", SB2);
|
||||
@@ -666,9 +667,19 @@ void loadconfig(char *fn)
|
||||
else strcpy(discfns[1], "");
|
||||
ui_writeprot[1] = config_get_int(NULL, "disc_b_writeprot", 0);
|
||||
|
||||
p = (char *)config_get_string(NULL, "disc_3", "");
|
||||
if (p) strcpy(discfns[2], p);
|
||||
else strcpy(discfns[2], "");
|
||||
ui_writeprot[2] = config_get_int(NULL, "disc_3_writeprot", 0);
|
||||
|
||||
p = (char *)config_get_string(NULL, "disc_4", "");
|
||||
if (p) strcpy(discfns[3], p);
|
||||
else strcpy(discfns[3], "");
|
||||
ui_writeprot[3] = config_get_int(NULL, "disc_4_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))
|
||||
mem_size = (models[model].is_at ? models[model].min_ram*1024 : models[model].min_ram);
|
||||
if (mem_size < ((models[model].flags & MODEL_AT) ? models[model].min_ram*1024 : models[model].min_ram))
|
||||
mem_size = ((models[model].flags & MODEL_AT) ? models[model].min_ram*1024 : models[model].min_ram);
|
||||
|
||||
cdrom_drive = config_get_int(NULL, "cdrom_drive", 0);
|
||||
old_cdrom_drive = cdrom_drive;
|
||||
@@ -683,10 +694,6 @@ void loadconfig(char *fn)
|
||||
if (p) strcpy(iso_path, p);
|
||||
else strcpy(iso_path, "");
|
||||
|
||||
slowega = config_get_int(NULL, "slow_video", 1);
|
||||
cache = config_get_int(NULL, "cache", 3);
|
||||
cga_comp = config_get_int(NULL, "cga_composite", 0);
|
||||
|
||||
vid_resize = config_get_int(NULL, "vid_resize", 0);
|
||||
vid_api = config_get_int(NULL, "vid_api", 0);
|
||||
video_fullscreen_scale = config_get_int(NULL, "video_fullscreen_scale", 0);
|
||||
@@ -716,16 +723,29 @@ void loadconfig(char *fn)
|
||||
p = (char *)config_get_string(NULL, "hdf_fn", "");
|
||||
if (p) strcpy(ide_fn[3], p);
|
||||
else strcpy(ide_fn[3], "");
|
||||
hdc[4].spt = config_get_int(NULL, "hdg_sectors", 0);
|
||||
hdc[4].hpc = config_get_int(NULL, "hdg_heads", 0);
|
||||
hdc[4].tracks = config_get_int(NULL, "hdg_cylinders", 0);
|
||||
p = (char *)config_get_string(NULL, "hdg_fn", "");
|
||||
if (p) strcpy(ide_fn[4], p);
|
||||
else strcpy(ide_fn[4], "");
|
||||
hdc[5].spt = config_get_int(NULL, "hdh_sectors", 0);
|
||||
hdc[5].hpc = config_get_int(NULL, "hdh_heads", 0);
|
||||
hdc[5].tracks = config_get_int(NULL, "hdh_cylinders", 0);
|
||||
p = (char *)config_get_string(NULL, "hdh_fn", "");
|
||||
if (p) strcpy(ide_fn[5], p);
|
||||
else strcpy(ide_fn[5], "");
|
||||
|
||||
fdd_set_type(0, config_get_int(NULL, "drive_a_type", 7));
|
||||
fdd_set_type(1, config_get_int(NULL, "drive_b_type", 7));
|
||||
fdd_set_type(0, config_get_int(NULL, "drive_a_type", 1));
|
||||
fdd_set_type(1, config_get_int(NULL, "drive_b_type", 1));
|
||||
fdd_set_type(2, config_get_int(NULL, "drive_3_type", 1));
|
||||
fdd_set_type(3, config_get_int(NULL, "drive_4_type", 1));
|
||||
|
||||
force_43 = config_get_int(NULL, "force_43", 0);
|
||||
enable_overscan = config_get_int(NULL, "enable_overscan", 0);
|
||||
enable_flash = config_get_int(NULL, "enable_flash", 1);
|
||||
|
||||
enable_sync = config_get_int(NULL, "enable_sync", 1);
|
||||
mouse_always_serial = config_get_int(NULL, "mouse_always_serial", 0);
|
||||
|
||||
window_w = config_get_int(NULL, "window_w", 0);
|
||||
window_h = config_get_int(NULL, "window_h", 0);
|
||||
@@ -734,6 +754,7 @@ void loadconfig(char *fn)
|
||||
window_remember = config_get_int(NULL, "window_remember", 0);
|
||||
|
||||
joystick_type = config_get_int(NULL, "joystick_type", 0);
|
||||
mouse_type = config_get_int(NULL, "mouse_type", 0);
|
||||
|
||||
for (c = 0; c < joystick_get_max_joysticks(joystick_type); c++)
|
||||
{
|
||||
@@ -806,19 +827,21 @@ void saveconfig()
|
||||
config_set_int(NULL, "cpu_manufacturer", cpu_manufacturer);
|
||||
config_set_int(NULL, "cpu", cpu);
|
||||
config_set_int(NULL, "cpu_use_dynarec", cpu_use_dynarec);
|
||||
config_set_int(NULL, "cpu_waitstates", cpu_waitstates);
|
||||
|
||||
config_set_int(NULL, "gfxcard", gfxcard);
|
||||
config_set_int(NULL, "video_speed", video_speed);
|
||||
config_set_int(NULL, "sndcard", sound_card_current);
|
||||
config_set_int(NULL, "cpu_speed", cpuspeed);
|
||||
config_set_int(NULL, "has_fpu", hasfpu);
|
||||
config_set_int(NULL, "slow_video", slowega);
|
||||
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_string(NULL, "disc_3", discfns[2]);
|
||||
config_set_int(NULL, "disc_3_writeprot", ui_writeprot[2]);
|
||||
config_set_string(NULL, "disc_4", discfns[3]);
|
||||
config_set_int(NULL, "disc_4_writeprot", ui_writeprot[3]);
|
||||
config_set_int(NULL, "mem_size", mem_size);
|
||||
config_set_int(NULL, "cdrom_drive", cdrom_drive);
|
||||
config_set_int(NULL, "cdrom_enabled", cdrom_enabled);
|
||||
@@ -850,18 +873,28 @@ void saveconfig()
|
||||
config_set_int(NULL, "hdf_heads", hdc[3].hpc);
|
||||
config_set_int(NULL, "hdf_cylinders", hdc[3].tracks);
|
||||
config_set_string(NULL, "hdf_fn", ide_fn[3]);
|
||||
config_set_int(NULL, "hdg_sectors", hdc[4].spt);
|
||||
config_set_int(NULL, "hdg_heads", hdc[4].hpc);
|
||||
config_set_int(NULL, "hdg_cylinders", hdc[4].tracks);
|
||||
config_set_string(NULL, "hdg_fn", ide_fn[4]);
|
||||
config_set_int(NULL, "hdh_sectors", hdc[5].spt);
|
||||
config_set_int(NULL, "hdh_heads", hdc[5].hpc);
|
||||
config_set_int(NULL, "hdh_cylinders", hdc[5].tracks);
|
||||
config_set_string(NULL, "hdh_fn", ide_fn[5]);
|
||||
|
||||
config_set_int(NULL, "drive_a_type", fdd_get_type(0));
|
||||
config_set_int(NULL, "drive_b_type", fdd_get_type(1));
|
||||
config_set_int(NULL, "drive_3_type", fdd_get_type(2));
|
||||
config_set_int(NULL, "drive_4_type", fdd_get_type(3));
|
||||
|
||||
config_set_int(NULL, "force_43", force_43);
|
||||
config_set_int(NULL, "enable_overscan", enable_overscan);
|
||||
config_set_int(NULL, "enable_flash", enable_flash);
|
||||
|
||||
config_set_int(NULL, "enable_sync", enable_sync);
|
||||
config_set_int(NULL, "mouse_always_serial", mouse_always_serial);
|
||||
|
||||
config_set_int(NULL, "joystick_type", joystick_type);
|
||||
config_set_int(NULL, "mouse_type", mouse_type);
|
||||
|
||||
for (c = 0; c < joystick_get_max_joysticks(joystick_type); c++)
|
||||
{
|
||||
|
||||
242
src/pc.rc
242
src/pc.rc
@@ -18,13 +18,21 @@ BEGIN
|
||||
END
|
||||
POPUP "&Disc"
|
||||
BEGIN
|
||||
MENUITEM "Change drive &A:...", IDM_DISC_A
|
||||
MENUITEM "Change drive A (&Write-protected):...", IDM_DISC_A_WP
|
||||
MENUITEM "&Eject drive A:", IDM_EJECT_A
|
||||
MENUITEM "Change FDD& 1...", IDM_DISC_1
|
||||
MENUITEM "Change FDD 1 (&Write-protected)...", IDM_DISC_1_WP
|
||||
MENUITEM "&Eject FDD 1", IDM_EJECT_1
|
||||
MENUITEM SEPARATOR
|
||||
MENUITEM "Change drive &B:...", IDM_DISC_B
|
||||
MENUITEM "Change drive B (W&rite-protected):...", IDM_DISC_B_WP
|
||||
MENUITEM "E&ject drive B:", IDM_EJECT_B
|
||||
MENUITEM "Change FDD &2...", IDM_DISC_2
|
||||
MENUITEM "Change FDD 2 (W&rite-protected)...", IDM_DISC_2_WP
|
||||
MENUITEM "E&ject FDD 2", IDM_EJECT_2
|
||||
MENUITEM SEPARATOR
|
||||
MENUITEM "Change FDD &3...", IDM_DISC_3
|
||||
MENUITEM "Change FDD 3 (W&rite-protected)...", IDM_DISC_3_WP
|
||||
MENUITEM "E&ject FDD 3", IDM_EJECT_3
|
||||
MENUITEM SEPARATOR
|
||||
MENUITEM "Change FDD &4...", IDM_DISC_4
|
||||
MENUITEM "Change FDD 4 (W&rite-protected)...", IDM_DISC_4_WP
|
||||
MENUITEM "E&ject FDD 4", IDM_EJECT_4
|
||||
MENUITEM SEPARATOR
|
||||
MENUITEM "&Configure hard discs...",IDM_HDCONF
|
||||
POPUP "C&D-ROM"
|
||||
@@ -73,7 +81,7 @@ BEGIN
|
||||
POPUP "&Video"
|
||||
BEGIN
|
||||
MENUITEM "&Resizeable window",IDM_VID_RESIZE
|
||||
MENUITEM "Remember size && position",IDM_VID_REMEMBER
|
||||
MENUITEM "R&emember size && position",IDM_VID_REMEMBER
|
||||
MENUITEM SEPARATOR
|
||||
MENUITEM "&DirectDraw", IDM_VID_DDRAW
|
||||
MENUITEM "Direct&3D 9", IDM_VID_D3D
|
||||
@@ -87,6 +95,11 @@ BEGIN
|
||||
MENUITEM "&Integer scale", IDM_VID_FS_INT
|
||||
END
|
||||
MENUITEM SEPARATOR
|
||||
MENUITEM "F&orce 4:3 display ratio", IDM_VID_FORCE43
|
||||
MENUITEM "E&GA/(S)VGA overscan", IDM_VID_OVERSCAN
|
||||
MENUITEM SEPARATOR
|
||||
MENUITEM "D&isc activity flash", IDM_VID_FLASH
|
||||
MENUITEM SEPARATOR
|
||||
MENUITEM "Take s&creenshot\tCtrl+F11", IDM_VID_SCREENSHOT
|
||||
END
|
||||
MENUITEM "&Status", IDM_STATUS
|
||||
@@ -99,141 +112,170 @@ BEGIN
|
||||
VK_F12, IDM_FILE_RESET_CAD, CONTROL, VIRTKEY
|
||||
END
|
||||
|
||||
ConfigureDlg DIALOGEX 0, 0, 248+40, 248+60
|
||||
ConfigureDlg DIALOGEX 0, 0, 252+40, 236+80
|
||||
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU
|
||||
CAPTION "Configure 86Box"
|
||||
FONT 9, "Segoe UI"
|
||||
BEGIN
|
||||
DEFPUSHBUTTON "OK",IDOK,64,284,50,14, WS_TABSTOP
|
||||
PUSHBUTTON "Cancel",IDCANCEL,128,284,50,14, WS_TABSTOP
|
||||
DEFPUSHBUTTON "OK",IDOK,64,292,50,14, WS_TABSTOP
|
||||
PUSHBUTTON "Cancel",IDCANCEL,128,292,50,14, WS_TABSTOP
|
||||
COMBOBOX IDC_COMBO1,62,16,157,120,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
|
||||
PUSHBUTTON "Configure", IDC_CONFIGUREMOD, 224, 16, 40, 14, WS_TABSTOP
|
||||
COMBOBOX IDC_COMBOVID,62,36,157,120,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
|
||||
PUSHBUTTON "Configure", IDC_CONFIGUREVID, 224, 36, 40, 14, WS_TABSTOP
|
||||
COMBOBOX IDC_COMBOCPUM,62,56,157,120,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
|
||||
COMBOBOX IDC_COMBO3,62,76,102,120,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
|
||||
CONTROL "Dynamic Recompiler",IDC_CHECKDYNAREC,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,169,76,99,10
|
||||
COMBOBOX IDC_COMBOCHC,62,96,57,120,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
|
||||
COMBOBOX IDC_COMBOSPD,162,96,57,120,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
|
||||
COMBOBOX IDC_COMBOSND,62,116,157,120,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
|
||||
COMBOBOX IDC_COMBOWS, 62,96,157,120,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
|
||||
COMBOBOX IDC_COMBOSPD,62,116,57,120,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
|
||||
COMBOBOX IDC_COMBOSND,162,116,57,120,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
|
||||
PUSHBUTTON "Configure", IDC_CONFIGURESND, 224, 116, 40, 14, WS_TABSTOP
|
||||
EDITTEXT IDC_MEMTEXT, 62, 136, 36, 14, ES_AUTOHSCROLL | ES_NUMBER
|
||||
CONTROL "", IDC_MEMSPIN, UPDOWN_CLASS, UDS_ALIGNRIGHT | UDS_ARROWKEYS | UDS_NOTHOUSANDS | UDS_SETBUDDYINT, 98, 136, 12, 14
|
||||
LTEXT "MB", IDC_TEXT_MB, 98, 136, 10, 10
|
||||
CONTROL "CMS / Game Blaster",IDC_CHECK3,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,172,102,10
|
||||
CONTROL "Gravis Ultrasound",IDC_CHECKGUS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,188,102,10
|
||||
CONTROL "Innovation SSI-2001",IDC_CHECKSSI,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,204,102,10
|
||||
CONTROL "Composite CGA",IDC_CHECK4,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,220,102,10
|
||||
CONTROL "Enable time sync",IDC_CHECKSYNC,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,236,102,10
|
||||
CONTROL "CMS / Game Blaster",IDC_CHECK3,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,192,102,10
|
||||
CONTROL "Gravis Ultrasound",IDC_CHECKGUS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,208,102,10
|
||||
|
||||
CONTROL "Force 4:3 display ratio",IDC_CHECKFORCE43,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,118,172,102,10
|
||||
CONTROL "EGA/(S)VGA overscan",IDC_CHECKOVERSCAN,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,118,188,102,10
|
||||
CONTROL "Disk activity flash",IDC_CHECKFLASH,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,118,204,102,10
|
||||
CONTROL "Ser.mouse inst.of PS/2",IDC_CHECKSERIAL,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,118,220,102,10
|
||||
CONTROL "Innovation SSI-2001",IDC_CHECKSSI,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,118,192,102,10
|
||||
CONTROL "Enable time sync",IDC_CHECKSYNC,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,118,208,102,10
|
||||
|
||||
CONTROL "Voodoo Graphics",IDC_CHECKVOODOO,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,118,236,102,10
|
||||
PUSHBUTTON "Configure", IDC_CONFIGUREVOODOO, 224, 236, 40, 14, WS_TABSTOP
|
||||
CONTROL "Voodoo Graphics",IDC_CHECKVOODOO,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,118,224,102,10
|
||||
PUSHBUTTON "Configure", IDC_CONFIGUREVOODOO, 224, 224, 40, 14, WS_TABSTOP
|
||||
|
||||
LTEXT "Joystick :",IDC_STATIC,15,252,40,10
|
||||
COMBOBOX IDC_COMBOJOY,62,252,157,120,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
|
||||
DEFPUSHBUTTON "Joystick 1...",IDC_JOY1,16,268,50,14, WS_TABSTOP
|
||||
PUSHBUTTON "Joystick 2...",IDC_JOY2,80,268,50,14, WS_TABSTOP
|
||||
DEFPUSHBUTTON "Joystick 3...",IDC_JOY3,144,268,50,14, WS_TABSTOP
|
||||
PUSHBUTTON "Joystick 4...",IDC_JOY4,208,268,50,14, WS_TABSTOP
|
||||
LTEXT "Mouse :",IDC_STATIC,15,240,40,10
|
||||
COMBOBOX IDC_COMBOMOUSE,62,240,157,120,CBS_DROPDOWN | WS_VSCROLL | WS_TABSTOP
|
||||
|
||||
LTEXT "Joystick :",IDC_STATIC,15,260,40,10
|
||||
COMBOBOX IDC_COMBOJOY,62,260,157,120,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
|
||||
DEFPUSHBUTTON "Joystick 1...",IDC_JOY1,16,276,50,14, WS_TABSTOP
|
||||
PUSHBUTTON "Joystick 2...",IDC_JOY2,80,276,50,14, WS_TABSTOP
|
||||
DEFPUSHBUTTON "Joystick 3...",IDC_JOY3,144,276,50,14, WS_TABSTOP
|
||||
PUSHBUTTON "Joystick 4...",IDC_JOY4,208,276,50,14, WS_TABSTOP
|
||||
|
||||
LTEXT "Machine :",IDC_STATIC,15,16,40,10
|
||||
LTEXT "Video :",IDC_STATIC,15,36,34,10
|
||||
LTEXT "CPU type :",IDC_STATIC,15,56,34,10
|
||||
LTEXT "CPU :",IDC_STATIC,15,76,34,10
|
||||
LTEXT "Cache :",IDC_STATIC,15,96,40,10
|
||||
LTEXT "Vid. speed :",IDC_STATIC,125,96,34,10
|
||||
LTEXT "Soundcard :",IDC_STATIC,15,116,40,10
|
||||
LTEXT "Waitstates :",IDC_STATIC,15,96,40,10
|
||||
LTEXT "Vid. speed :",IDC_STATIC,15,116,40,10
|
||||
LTEXT "Soundcard:",IDC_STATIC,125,116,34,10
|
||||
LTEXT "Network :",IDC_STATIC,125,136,34,10
|
||||
COMBOBOX IDC_COMBONET,162,136,57,120,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
|
||||
PUSHBUTTON "Configure", IDC_CONFIGURENET, 224, 136, 40, 14, WS_TABSTOP
|
||||
LTEXT "Memory :",IDC_STATIC,15,136,40,10
|
||||
LTEXT "Drive A: :",IDC_STATIC,15,156,40,10
|
||||
LTEXT "Drive B: :",IDC_STATIC,125,156,40,10
|
||||
COMBOBOX IDC_COMBODRA,62,156,57,120,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
|
||||
COMBOBOX IDC_COMBODRB,162,156,57,120,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
|
||||
LTEXT "FDD 1 :",IDC_STATIC,15,156,40,10
|
||||
LTEXT "FDD 2 :",IDC_STATIC,125,156,40,10
|
||||
COMBOBOX IDC_COMBODR1,62,156,57,120,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
|
||||
COMBOBOX IDC_COMBODR2,162,156,57,120,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
|
||||
LTEXT "FDD 3 :",IDC_STATIC,15,176,40,10
|
||||
LTEXT "FDD 4 :",IDC_STATIC,125,176,40,10
|
||||
COMBOBOX IDC_COMBODR3,62,176,57,120,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
|
||||
COMBOBOX IDC_COMBODR4,162,176,57,120,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
|
||||
END
|
||||
|
||||
HdConfDlg DIALOGEX 0, 0, 210, 286+4*16
|
||||
HdConfDlg DIALOGEX 0, 0, 210, DLG_HEIGHT
|
||||
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU
|
||||
CAPTION "Configure Hard Discs"
|
||||
FONT 9, "Segoe UI"
|
||||
BEGIN
|
||||
DEFPUSHBUTTON "OK",IDOK,31+12,264+64,50,14
|
||||
PUSHBUTTON "Cancel",IDCANCEL,101+12,264+64,50,14
|
||||
DEFPUSHBUTTON "OK",IDOK,31+12,CMD_BASE,50,14
|
||||
PUSHBUTTON "Cancel",IDCANCEL,101+12,CMD_BASE,50,14
|
||||
|
||||
LTEXT "C:",IDC_STATIC,7,6,27,10
|
||||
RADIOBUTTON "Hard drive", IDC_CHDD, 7+64, 6, 53, 12 , WS_TABSTOP
|
||||
RADIOBUTTON "CD-ROM", IDC_CCDROM, 7+128, 6, 53, 12 , WS_TABSTOP
|
||||
EDITTEXT IDC_EDIT_C_FN, 7, 6+16, 136, 12, WS_DISABLED
|
||||
PUSHBUTTON "...",IDC_CFILE,7 + 136, 6+16, 16, 14
|
||||
PUSHBUTTON "New",IDC_CNEW,7 + 136 + 16, 6+16, 24, 14
|
||||
PUSHBUTTON "Eject", IDC_EJECTC, 7 + 136 + 16 + 24, 6+16, 24, 14
|
||||
LTEXT "C:",IDC_STATIC,7,C_BASE+2,27,10
|
||||
RADIOBUTTON "Hard drive", IDC_CHDD, 7+64, C_BASE, 53, 12 , WS_TABSTOP
|
||||
RADIOBUTTON "CD-ROM", IDC_CCDROM, 7+128, C_BASE, 53, 12 , WS_TABSTOP
|
||||
EDITTEXT IDC_EDIT_C_FN, 7, C_BASE+16, 136, 12, WS_DISABLED
|
||||
PUSHBUTTON "...",IDC_CFILE,7 + 136, C_BASE+16, 16, 14
|
||||
PUSHBUTTON "New",IDC_CNEW,7 + 136 + 16, C_BASE+16, 24, 14
|
||||
PUSHBUTTON "Eject", IDC_EJECTC, 7 + 136 + 16 + 24, C_BASE+16, 24, 14
|
||||
|
||||
EDITTEXT IDC_EDIT_C_SPT,36,22+16,16,12, WS_DISABLED
|
||||
EDITTEXT IDC_EDIT_C_HPC,94,22+16,16,12, WS_DISABLED
|
||||
EDITTEXT IDC_EDIT_C_CYL,152,22+16,28,12, WS_DISABLED
|
||||
LTEXT "Sectors:",IDC_STATIC,7,22+16,27,10
|
||||
LTEXT "Heads:",IDC_STATIC,63,22+16,29,8
|
||||
LTEXT "Cylinders:",IDC_STATIC,120,22+16,32,12
|
||||
LTEXT "", IDC_TEXT_C_SIZE, 7, 38+16, 136, 12
|
||||
EDITTEXT IDC_EDIT_C_SPT,15,C_BASE+32,16,12, WS_DISABLED
|
||||
EDITTEXT IDC_EDIT_C_HPC,48,C_BASE+32,16,12, WS_DISABLED
|
||||
EDITTEXT IDC_EDIT_C_CYL,81,C_BASE+32,28,12, WS_DISABLED
|
||||
LTEXT "S:",IDC_STATIC,7,C_BASE+34,8,12
|
||||
LTEXT "H:",IDC_STATIC,40,C_BASE+34,8,12
|
||||
LTEXT "C:",IDC_STATIC,73,C_BASE+34,8,12
|
||||
LTEXT "", IDC_TEXT_C_SIZE, 118, C_BASE+34, 89, 12
|
||||
|
||||
LTEXT "D:",IDC_STATIC,7,60+16,27,10
|
||||
RADIOBUTTON "Hard drive", IDC_DHDD, 7+64, 60+16, 53, 12 , WS_TABSTOP
|
||||
RADIOBUTTON "CD-ROM", IDC_DCDROM, 7+128, 60+16, 53, 12 , WS_TABSTOP
|
||||
EDITTEXT IDC_EDIT_D_FN, 7, 60+32, 136, 12, WS_DISABLED
|
||||
PUSHBUTTON "...",IDC_DFILE,7 + 136, 60+32, 16, 14
|
||||
PUSHBUTTON "New",IDC_DNEW,7 + 136 + 16, 60+32, 24, 14
|
||||
PUSHBUTTON "Eject", IDC_EJECTD, 7 + 136 + 16 + 24, 60+32, 24, 14
|
||||
LTEXT "D:",IDC_STATIC,7,D_BASE+2,27,10
|
||||
RADIOBUTTON "Hard drive", IDC_DHDD, 7+64, D_BASE, 53, 12 , WS_TABSTOP
|
||||
RADIOBUTTON "CD-ROM", IDC_DCDROM, 7+128, D_BASE, 53, 12 , WS_TABSTOP
|
||||
EDITTEXT IDC_EDIT_D_FN, 7, D_BASE+16, 136, 12, WS_DISABLED
|
||||
PUSHBUTTON "...",IDC_DFILE,7 + 136, D_BASE+16, 16, 14
|
||||
PUSHBUTTON "New",IDC_DNEW,7 + 136 + 16, D_BASE+16, 24, 14
|
||||
PUSHBUTTON "Eject", IDC_EJECTD, 7 + 136 + 16 + 24, D_BASE+16, 24, 14
|
||||
|
||||
EDITTEXT IDC_EDIT_D_SPT,36,76+32,16,12, WS_DISABLED
|
||||
EDITTEXT IDC_EDIT_D_HPC,94,76+32,16,12, WS_DISABLED
|
||||
EDITTEXT IDC_EDIT_D_CYL,152,76+32,28,12, WS_DISABLED
|
||||
LTEXT "Sectors:",IDC_STATIC,7,76+32,27,10
|
||||
LTEXT "Heads:",IDC_STATIC,63,76+32,29,8
|
||||
LTEXT "Cylinders:",IDC_STATIC,120,76+32,32,12
|
||||
LTEXT "", IDC_TEXT_D_SIZE, 7, 92+32, 136, 12
|
||||
EDITTEXT IDC_EDIT_D_SPT,15,D_BASE+32,16,12, WS_DISABLED
|
||||
EDITTEXT IDC_EDIT_D_HPC,48,D_BASE+32,16,12, WS_DISABLED
|
||||
EDITTEXT IDC_EDIT_D_CYL,81,D_BASE+32,28,12, WS_DISABLED
|
||||
LTEXT "S:",IDC_STATIC,7,D_BASE+34,8,12
|
||||
LTEXT "H:",IDC_STATIC,40,D_BASE+34,8,12
|
||||
LTEXT "C:",IDC_STATIC,73,D_BASE+34,8,12
|
||||
LTEXT "", IDC_TEXT_D_SIZE, 118, D_BASE+34, 89, 12
|
||||
|
||||
LTEXT "E:",IDC_STATIC,7,114+32,27,10
|
||||
RADIOBUTTON "Hard drive", IDC_EHDD, 7+64, 114+32, 53, 12 , WS_TABSTOP
|
||||
RADIOBUTTON "CD-ROM", IDC_ECDROM, 7+128, 114+32, 53, 12 , WS_TABSTOP
|
||||
EDITTEXT IDC_EDIT_E_FN, 7, 114+48, 136, 12, WS_DISABLED
|
||||
PUSHBUTTON "...",IDC_EFILE,7 + 136, 114+48, 16, 14
|
||||
PUSHBUTTON "New",IDC_ENEW,7 + 136 + 16, 114+48, 24, 14
|
||||
PUSHBUTTON "Eject", IDC_EJECTE, 7 + 136 + 16 + 24, 114+48, 24, 14
|
||||
LTEXT "E:",IDC_STATIC,7,E_BASE+2,27,10
|
||||
RADIOBUTTON "Hard drive", IDC_EHDD, 7+64, E_BASE, 53, 12 , WS_TABSTOP
|
||||
RADIOBUTTON "CD-ROM", IDC_ECDROM, 7+128, E_BASE, 53, 12 , WS_TABSTOP
|
||||
EDITTEXT IDC_EDIT_E_FN, 7, E_BASE+16, 136, 12, WS_DISABLED
|
||||
PUSHBUTTON "...",IDC_EFILE,7 + 136, E_BASE+16, 16, 14
|
||||
PUSHBUTTON "New",IDC_ENEW,7 + 136 + 16, E_BASE+16, 24, 14
|
||||
PUSHBUTTON "Eject", IDC_EJECTE, 7 + 136 + 16 + 24, E_BASE+16, 24, 14
|
||||
|
||||
EDITTEXT IDC_EDIT_E_SPT,36,130+48,16,12, WS_DISABLED
|
||||
EDITTEXT IDC_EDIT_E_HPC,94,130+48,16,12, WS_DISABLED
|
||||
EDITTEXT IDC_EDIT_E_CYL,152,130+48,28,12, WS_DISABLED
|
||||
LTEXT "Sectors:",IDC_STATIC,7,130+48,27,10
|
||||
LTEXT "Heads:",IDC_STATIC,63,130+48,29,8
|
||||
LTEXT "Cylinders:",IDC_STATIC,120,130+48,32,12
|
||||
LTEXT "", IDC_TEXT_E_SIZE, 7, 146+48, 136, 12
|
||||
EDITTEXT IDC_EDIT_E_SPT,15,E_BASE+32,16,12, WS_DISABLED
|
||||
EDITTEXT IDC_EDIT_E_HPC,48,E_BASE+32,16,12, WS_DISABLED
|
||||
EDITTEXT IDC_EDIT_E_CYL,81,E_BASE+32,28,12, WS_DISABLED
|
||||
LTEXT "S:",IDC_STATIC,7,E_BASE+34,8,12
|
||||
LTEXT "H:",IDC_STATIC,40,E_BASE+34,8,12
|
||||
LTEXT "C:",IDC_STATIC,73,E_BASE+34,8,12
|
||||
LTEXT "", IDC_TEXT_E_SIZE, 118, E_BASE+34, 89, 12
|
||||
|
||||
LTEXT "F:",IDC_STATIC,7,168+48,27,10
|
||||
RADIOBUTTON "Hard drive", IDC_FHDD, 7+64, 168+48, 53, 12 , WS_TABSTOP
|
||||
RADIOBUTTON "CD-ROM", IDC_FCDROM, 7+128, 168+48, 53, 12 , WS_TABSTOP
|
||||
EDITTEXT IDC_EDIT_F_FN, 7, 168+64, 136, 12, WS_DISABLED
|
||||
PUSHBUTTON "...",IDC_FFILE,7 + 136, 168+64, 16, 14
|
||||
PUSHBUTTON "New",IDC_FNEW,7 + 136 + 16, 168+64, 24, 14
|
||||
PUSHBUTTON "Eject", IDC_EJECTF, 7 + 136 + 16 + 24, 168+64, 24, 14
|
||||
LTEXT "F:",IDC_STATIC,7,F_BASE+2,27,10
|
||||
RADIOBUTTON "Hard drive", IDC_FHDD, 7+64, F_BASE, 53, 12 , WS_TABSTOP
|
||||
RADIOBUTTON "CD-ROM", IDC_FCDROM, 7+128, F_BASE, 53, 12 , WS_TABSTOP
|
||||
EDITTEXT IDC_EDIT_F_FN, 7, F_BASE+16, 136, 12, WS_DISABLED
|
||||
PUSHBUTTON "...",IDC_FFILE,7 + 136, F_BASE+16, 16, 14
|
||||
PUSHBUTTON "New",IDC_FNEW,7 + 136 + 16, F_BASE+16, 24, 14
|
||||
PUSHBUTTON "Eject", IDC_EJECTF, 7 + 136 + 16 + 24, F_BASE+16, 24, 14
|
||||
|
||||
EDITTEXT IDC_EDIT_F_SPT,36,184+64,16,12, WS_DISABLED
|
||||
EDITTEXT IDC_EDIT_F_HPC,94,184+64,16,12, WS_DISABLED
|
||||
EDITTEXT IDC_EDIT_F_CYL,152,184+64,28,12, WS_DISABLED
|
||||
LTEXT "Sectors:",IDC_STATIC,7,184+64,27,10
|
||||
LTEXT "Heads:",IDC_STATIC,63,184+64,29,8
|
||||
LTEXT "Cylinders:",IDC_STATIC,120,184+64,32,12
|
||||
LTEXT "", IDC_TEXT_F_SIZE, 7, 200+64, 136, 12
|
||||
EDITTEXT IDC_EDIT_F_SPT,15,F_BASE+32,16,12, WS_DISABLED
|
||||
EDITTEXT IDC_EDIT_F_HPC,48,F_BASE+32,16,12, WS_DISABLED
|
||||
EDITTEXT IDC_EDIT_F_CYL,81,F_BASE+32,28,12, WS_DISABLED
|
||||
LTEXT "S:",IDC_STATIC,7,F_BASE+34,8,12
|
||||
LTEXT "H:",IDC_STATIC,40,F_BASE+34,8,12
|
||||
LTEXT "C:",IDC_STATIC,73,F_BASE+34,8,12
|
||||
LTEXT "", IDC_TEXT_F_SIZE, 118, F_BASE+34, 89, 12
|
||||
|
||||
LTEXT "G:",IDC_STATIC,7,222+64,27,10
|
||||
RADIOBUTTON "CD-ROM", IDC_GCDROM, 7+128, 222+64, 53, 12 , WS_TABSTOP
|
||||
LTEXT "G:",IDC_STATIC,7,G_BASE+2,27,10
|
||||
RADIOBUTTON "Hard drive", IDC_GHDD, 7+64, G_BASE, 53, 12 , WS_TABSTOP
|
||||
RADIOBUTTON "CD-ROM", IDC_GCDROM, 7+128, G_BASE, 53, 12 , WS_TABSTOP
|
||||
EDITTEXT IDC_EDIT_G_FN, 7, G_BASE+16, 136, 12, WS_DISABLED
|
||||
PUSHBUTTON "...",IDC_GFILE,7 + 136, G_BASE+16, 16, 14
|
||||
PUSHBUTTON "New",IDC_GNEW,7 + 136 + 16, G_BASE+16, 24, 14
|
||||
PUSHBUTTON "Eject", IDC_EJECTG, 7 + 136 + 16 + 24, G_BASE+16, 24, 14
|
||||
|
||||
LTEXT "H:",IDC_STATIC,7,238+64,27,10
|
||||
RADIOBUTTON "CD-ROM", IDC_HCDROM, 7+128, 238+64, 53, 12 , WS_TABSTOP
|
||||
EDITTEXT IDC_EDIT_G_SPT,15,G_BASE+32,16,12, WS_DISABLED
|
||||
EDITTEXT IDC_EDIT_G_HPC,48,G_BASE+32,16,12, WS_DISABLED
|
||||
EDITTEXT IDC_EDIT_G_CYL,81,G_BASE+32,28,12, WS_DISABLED
|
||||
LTEXT "S:",IDC_STATIC,7,G_BASE+34,8,12
|
||||
LTEXT "H:",IDC_STATIC,40,G_BASE+34,8,12
|
||||
LTEXT "C:",IDC_STATIC,73,G_BASE+34,8,12
|
||||
LTEXT "", IDC_TEXT_G_SIZE, 118, G_BASE+34, 89, 12
|
||||
|
||||
LTEXT "H:",IDC_STATIC,7,H_BASE+2,27,10
|
||||
RADIOBUTTON "Hard drive", IDC_HHDD, 7+64, H_BASE, 53, 12 , WS_TABSTOP
|
||||
RADIOBUTTON "CD-ROM", IDC_HCDROM, 7+128, H_BASE, 53, 12 , WS_TABSTOP
|
||||
EDITTEXT IDC_EDIT_H_FN, 7, H_BASE+16, 136, 12, WS_DISABLED
|
||||
PUSHBUTTON "...",IDC_HFILE,7 + 136, H_BASE+16, 16, 14
|
||||
PUSHBUTTON "New",IDC_HNEW,7 + 136 + 16, H_BASE+16, 24, 14
|
||||
PUSHBUTTON "Eject", IDC_EJECTH, 7 + 136 + 16 + 24, H_BASE+16, 24, 14
|
||||
|
||||
EDITTEXT IDC_EDIT_H_SPT,15,H_BASE+32,16,12, WS_DISABLED
|
||||
EDITTEXT IDC_EDIT_H_HPC,48,H_BASE+32,16,12, WS_DISABLED
|
||||
EDITTEXT IDC_EDIT_H_CYL,81,H_BASE+32,28,12, WS_DISABLED
|
||||
LTEXT "S:",IDC_STATIC,7,H_BASE+34,8,12
|
||||
LTEXT "H:",IDC_STATIC,40,H_BASE+34,8,12
|
||||
LTEXT "C:",IDC_STATIC,73,H_BASE+34,8,12
|
||||
LTEXT "", IDC_TEXT_H_SIZE, 118, H_BASE+34, 89, 12
|
||||
|
||||
END
|
||||
|
||||
|
||||
170
src/pc87306.c
170
src/pc87306.c
@@ -13,7 +13,6 @@
|
||||
#include "fdd.h"
|
||||
#include "io.h"
|
||||
#include "lpt.h"
|
||||
#include "mouse_serial.h"
|
||||
#include "serial.h"
|
||||
#include "pc87306.h"
|
||||
|
||||
@@ -23,29 +22,36 @@ static uint8_t pc87306_regs[29];
|
||||
static uint8_t pc87306_gpio[2] = {0xFF, 0xFF};
|
||||
static uint8_t tries;
|
||||
static uint16_t lpt_port;
|
||||
static int power_down = 0;
|
||||
|
||||
void pc87306_gpio_remove();
|
||||
void pc87306_gpio_init();
|
||||
|
||||
void pc87306_gpio_write(uint16_t port, uint8_t val, void *priv)
|
||||
{
|
||||
if (port & 1)
|
||||
{
|
||||
return;
|
||||
}
|
||||
pc87306_gpio[port & 1] = val;
|
||||
}
|
||||
|
||||
uint8_t uart_int1()
|
||||
{
|
||||
return ((pc87306_regs[0x1C] >> 2) & 1) ? 4 : 3;
|
||||
/* 0: IRQ3, 1: IRQ4 */
|
||||
return ((pc87306_regs[0x1C] >> 2) & 1) ? 3 : 4;
|
||||
}
|
||||
|
||||
uint8_t uart_int2()
|
||||
{
|
||||
return ((pc87306_regs[0x1C] >> 6) & 1) ? 4 : 3;
|
||||
return ((pc87306_regs[0x1C] >> 6) & 1) ? 3 : 4;
|
||||
}
|
||||
|
||||
uint8_t uart1_int()
|
||||
{
|
||||
uint8_t temp;
|
||||
temp = ((pc87306_regs[1] >> 2) & 1) ? 3 : 4; /* 0 = IRQ 4, 1 = IRQ 3 */
|
||||
// pclog("UART 1 set to IRQ %i\n", (pc87306_regs[0x1C] & 1) ? uart_int1() : temp);
|
||||
return (pc87306_regs[0x1C] & 1) ? uart_int1() : temp;
|
||||
}
|
||||
|
||||
@@ -53,9 +59,39 @@ uint8_t uart2_int()
|
||||
{
|
||||
uint8_t temp;
|
||||
temp = ((pc87306_regs[1] >> 4) & 1) ? 3 : 4; /* 0 = IRQ 4, 1 = IRQ 3 */
|
||||
// pclog("UART 2 set to IRQ %i\n", (pc87306_regs[0x1C] & 1) ? uart_int2() : temp);
|
||||
return (pc87306_regs[0x1C] & 1) ? uart_int2() : temp;
|
||||
}
|
||||
|
||||
void lpt1_handler()
|
||||
{
|
||||
int temp;
|
||||
if (pc87306_regs[0x1B] & 0x10)
|
||||
{
|
||||
temp = (pc87306_regs[0x1B] & 0x20) >> 5;
|
||||
if (temp)
|
||||
{
|
||||
lpt_port = 0x378;
|
||||
}
|
||||
else
|
||||
{
|
||||
lpt_port = 0x278;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
temp = pc87306_regs[0x01] & 3;
|
||||
switch (temp)
|
||||
{
|
||||
case 0: lpt_port = 0x378;
|
||||
case 1: lpt_port = 0x3bc;
|
||||
case 2: lpt_port = 0x278;
|
||||
}
|
||||
}
|
||||
lpt1_init(lpt_port);
|
||||
pc87306_regs[0x19] = lpt_port >> 2;
|
||||
}
|
||||
|
||||
void serial1_handler()
|
||||
{
|
||||
int temp;
|
||||
@@ -124,7 +160,7 @@ void pc87306_write(uint16_t port, uint8_t val, void *priv)
|
||||
|
||||
if (index)
|
||||
{
|
||||
pc87306_curreg = val;
|
||||
pc87306_curreg = val & 0x1f;
|
||||
// pclog("Register set to: %02X\n", val);
|
||||
tries = 0;
|
||||
return;
|
||||
@@ -135,10 +171,13 @@ void pc87306_write(uint16_t port, uint8_t val, void *priv)
|
||||
{
|
||||
if (pc87306_curreg <= 28) valxor = val ^ pc87306_regs[pc87306_curreg];
|
||||
if (pc87306_curreg == 0xF) pc87306_gpio_remove();
|
||||
if (pc87306_curreg <= 28) pc87306_regs[pc87306_curreg] = val;
|
||||
// pclog("Register %02X set to: %02X\n", pc87306_regs[pc87306_curreg], val);
|
||||
if ((pc87306_curreg <= 28) && (pc87306_curreg != 8))
|
||||
{
|
||||
pc87306_regs[pc87306_curreg] = val;
|
||||
// pclog("Register %02X set to: %02X (was: %02X)\n", pc87306_curreg, val, pc87306_regs[pc87306_curreg]);
|
||||
}
|
||||
tries = 0;
|
||||
if (pc87306_curreg <= 28) goto process_value;
|
||||
if ((pc87306_curreg <= 28) && (pc87306_curreg != 8)) goto process_value;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -155,32 +194,10 @@ process_value:
|
||||
if (valxor & 1)
|
||||
{
|
||||
lpt1_remove();
|
||||
lpt2_remove();
|
||||
}
|
||||
if ((valxor & 1) && (val & 1))
|
||||
{
|
||||
if (pc87306_regs[0x1B] & 0x10)
|
||||
{
|
||||
temp = (pc87306_regs[0x1B] & 0x20) >> 5;
|
||||
if (temp)
|
||||
{
|
||||
lpt1_init(0x378); break;
|
||||
}
|
||||
else
|
||||
{
|
||||
lpt1_init(0x278); break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
temp = pc87306_regs[1] & 3;
|
||||
switch (temp)
|
||||
{
|
||||
case 0: lpt1_init(0x378); break;
|
||||
case 1: lpt1_init(0x3bc); break;
|
||||
case 2: lpt1_init(0x278); break;
|
||||
}
|
||||
}
|
||||
lpt1_handler();
|
||||
}
|
||||
|
||||
if (valxor & 2)
|
||||
@@ -189,13 +206,15 @@ process_value:
|
||||
if (val & 2)
|
||||
{
|
||||
serial1_handler();
|
||||
// if (mouse_always_serial) mouse_serial_init();
|
||||
}
|
||||
}
|
||||
if (valxor & 4)
|
||||
{
|
||||
serial2_remove();
|
||||
if (val & 4) serial2_handler();
|
||||
if (val & 4)
|
||||
{
|
||||
serial2_handler();
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
@@ -205,30 +224,7 @@ process_value:
|
||||
lpt1_remove();
|
||||
if (pc87306_regs[0] & 1)
|
||||
{
|
||||
if (pc87306_regs[0x1B] & 0x10)
|
||||
{
|
||||
temp = (pc87306_regs[0x1B] & 0x20) >> 5;
|
||||
if (temp)
|
||||
{
|
||||
lpt_port = 0x378; break;
|
||||
}
|
||||
else
|
||||
{
|
||||
lpt_port = 0x278; break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
temp = val & 3;
|
||||
switch (temp)
|
||||
{
|
||||
case 0: lpt_port = 0x378; break;
|
||||
case 1: lpt_port = 0x3bc; break;
|
||||
case 2: lpt_port = 0x278; break;
|
||||
}
|
||||
}
|
||||
lpt1_init(lpt_port);
|
||||
pc87306_regs[0x19] = lpt_port >> 2;
|
||||
lpt1_handler();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -239,7 +235,6 @@ process_value:
|
||||
if (pc87306_regs[0] & 2)
|
||||
{
|
||||
serial1_handler();
|
||||
// if (mouse_always_serial) mouse_serial_init();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -247,11 +242,30 @@ process_value:
|
||||
{
|
||||
serial2_remove();
|
||||
|
||||
if (pc87306_regs[0] & 4) serial2_handler();
|
||||
if (pc87306_regs[0] & 4)
|
||||
{
|
||||
serial2_handler();
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
lpt1_remove();
|
||||
serial1_remove();
|
||||
serial2_remove();
|
||||
if (val & 1)
|
||||
{
|
||||
pc87306_regs[0] &= 0xb0;
|
||||
}
|
||||
else
|
||||
{
|
||||
lpt1_handler();
|
||||
serial1_handler();
|
||||
// serial2_handler();
|
||||
pc87306_regs[0] |= 0x4b;
|
||||
}
|
||||
break;
|
||||
case 9:
|
||||
// pclog("Setting DENSEL polarity to: %i (before: %i)\n", (val & 0x40 ? 1 : 0), fdc_get_densel_polarity());
|
||||
pclog("Setting DENSEL polarity to: %i (before: %i)\n", (val & 0x40 ? 1 : 0), fdc_get_densel_polarity());
|
||||
fdc_update_enh_mode((val & 4) ? 1 : 0);
|
||||
fdc_update_densel_polarity((val & 0x40) ? 1 : 0);
|
||||
break;
|
||||
@@ -267,7 +281,6 @@ process_value:
|
||||
if (pc87306_regs[0] & 2)
|
||||
{
|
||||
serial1_handler();
|
||||
// if (mouse_always_serial) mouse_serial_init();
|
||||
}
|
||||
if (pc87306_regs[0] & 4) serial2_handler();
|
||||
}
|
||||
@@ -277,6 +290,10 @@ process_value:
|
||||
|
||||
uint8_t pc87306_gpio_read(uint16_t port, void *priv)
|
||||
{
|
||||
if (port & 1)
|
||||
{
|
||||
return 0xfb; /* Bit 2 clear, since we don't emulate the on-board audio. */
|
||||
}
|
||||
return pc87306_gpio[port & 1];
|
||||
}
|
||||
|
||||
@@ -286,14 +303,35 @@ uint8_t pc87306_read(uint16_t port, void *priv)
|
||||
uint8_t index;
|
||||
index = (port & 1) ? 0 : 1;
|
||||
|
||||
tries = 0;
|
||||
|
||||
if (index)
|
||||
return pc87306_curreg;
|
||||
{
|
||||
// pclog("PC87306: Read value %02X at the index register\n", pc87306_curreg & 0x1f);
|
||||
return pc87306_curreg & 0x1f;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (pc87306_curreg >= 28)
|
||||
{
|
||||
// pclog("PC87306: Read invalid at data register, index %02X\n", pc87306_curreg);
|
||||
return 0xff;
|
||||
}
|
||||
else if (pc87306_curreg == 8)
|
||||
{
|
||||
// pclog("PC87306: Read ID at data register, index 08\n");
|
||||
return 0x70;
|
||||
}
|
||||
else if (pc87306_curreg == 5)
|
||||
{
|
||||
// pclog("PC87306: Read value %02X at data register, index 05\n", pc87306_regs[pc87306_curreg] | 4);
|
||||
return pc87306_regs[pc87306_curreg] | 4;
|
||||
}
|
||||
else
|
||||
{
|
||||
// pclog("PC87306: Read value %02X at data register, index %02X\n", pc87306_regs[pc87306_curreg], pc87306_curreg);
|
||||
return pc87306_regs[pc87306_curreg];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -309,13 +347,19 @@ void pc87306_gpio_init()
|
||||
|
||||
void pc87306_init()
|
||||
{
|
||||
pc87306_regs[0] = 0xF;
|
||||
pc87306_regs[1] = 0x11;
|
||||
memset(pc87306_regs, 0, 29);
|
||||
lpt2_remove();
|
||||
|
||||
// pc87306_regs[0] = 0xF;
|
||||
pc87306_regs[0] = 0x4B;
|
||||
// pc87306_regs[1] = 0x11;
|
||||
pc87306_regs[1] = 0x01;
|
||||
pc87306_regs[3] = 2;
|
||||
pc87306_regs[5] = 0xD;
|
||||
pc87306_regs[8] = 0x70;
|
||||
pc87306_regs[9] = 0xFF;
|
||||
pc87306_regs[0xF] = 0x1E;
|
||||
pc87306_regs[0x12] = 0x30;
|
||||
pc87306_regs[0x19] = 0xDE;
|
||||
pc87306_regs[0x1B] = 0x10;
|
||||
pc87306_regs[0x1C] = 0;
|
||||
|
||||
12
src/pci.c
12
src/pci.c
@@ -33,14 +33,14 @@ uint32_t pci_cf8_read(uint16_t port, void *p)
|
||||
|
||||
void pci_write(uint16_t port, uint8_t val, void *priv)
|
||||
{
|
||||
// pclog("pci_write: port=%04x val=%02x %08x:%08x\n", port, val, cs, pc);
|
||||
// pclog("pci_write: port=%04x val=%02x %08x:%08x\n", port, val, cs, cpu_state.pc);
|
||||
switch (port)
|
||||
{
|
||||
case 0xcfc: case 0xcfd: case 0xcfe: case 0xcff:
|
||||
if (!pci_enable)
|
||||
return;
|
||||
|
||||
// pclog("PCI write bus %i card %i func %i index %02X val %02X %04X:%04X\n", pci_bus, pci_card, pci_func, pci_index | (port & 3), val, CS, pc);
|
||||
// pclog("PCI write bus %i card %i func %i index %02X val %02X %04X:%04X\n", pci_bus, pci_card, pci_func, pci_index | (port & 3), val, CS, cpu_state.pc);
|
||||
|
||||
if (!pci_bus && pci_card_write[pci_card])
|
||||
pci_card_write[pci_card](pci_func, pci_index | (port & 3), val, pci_priv[pci_card]);
|
||||
@@ -51,14 +51,14 @@ void pci_write(uint16_t port, uint8_t val, void *priv)
|
||||
|
||||
uint8_t pci_read(uint16_t port, void *priv)
|
||||
{
|
||||
// pclog("pci_read: port=%04x %08x:%08x\n", port, cs, pc);
|
||||
// pclog("pci_read: port=%04x %08x:%08x\n", port, cs, cpu_state.pc);
|
||||
switch (port)
|
||||
{
|
||||
case 0xcfc: case 0xcfd: case 0xcfe: case 0xcff:
|
||||
if (!pci_enable)
|
||||
return 0xff;
|
||||
|
||||
// pclog("PCI read bus %i card %i func %i index %02X\n", pci_bus, pci_card, pci_func, pci_index | (port & 3));
|
||||
// pclog("PCI read bus %i card %i func %i index %02X\n", pci_bus, pci_card, pci_func, pci_index | (port & 3));
|
||||
|
||||
if (!pci_bus && pci_card_read[pci_card])
|
||||
return pci_card_read[pci_card](pci_func, pci_index | (port & 3), pci_priv[pci_card]);
|
||||
@@ -91,7 +91,7 @@ void pci_type2_write(uint16_t port, uint8_t val, void *priv)
|
||||
pci_card = (port >> 8) & 0xf;
|
||||
pci_index = port & 0xff;
|
||||
|
||||
// pclog("PCI write bus %i card %i func %i index %02X val %02X %04X:%04X\n", pci_bus, pci_card, pci_func, pci_index | (port & 3), val, CS, pc);
|
||||
// pclog("PCI write bus %i card %i func %i index %02X val %02X %04X:%04X\n", pci_bus, pci_card, pci_func, pci_index | (port & 3), val, CS, cpu_state.pc);
|
||||
|
||||
if (!pci_bus && pci_card_write[pci_card])
|
||||
pci_card_write[pci_card](pci_func, pci_index | (port & 3), val, pci_priv[pci_card]);
|
||||
@@ -114,7 +114,7 @@ uint8_t pci_type2_read(uint16_t port, void *priv)
|
||||
pci_card = (port >> 8) & 0xf;
|
||||
pci_index = port & 0xff;
|
||||
|
||||
// pclog("PCI read bus %i card %i func %i index %02X %04X:%04X\n", pci_bus, pci_card, pci_func, pci_index | (port & 3), CS, pc);
|
||||
// pclog("PCI read bus %i card %i func %i index %02X %04X:%04X\n", pci_bus, pci_card, pci_func, pci_index | (port & 3), CS, cpu_state.pc);
|
||||
|
||||
if (!pci_bus && pci_card_write[pci_card])
|
||||
return pci_card_read[pci_card](pci_func, pci_index | (port & 3), pci_priv[pci_card]);
|
||||
|
||||
30
src/pic.c
30
src/pic.c
@@ -9,15 +9,20 @@ int pic_intpending;
|
||||
|
||||
void pic_updatepending()
|
||||
{
|
||||
uint16_t temp_pending = 0;
|
||||
if ((pic2.pend&~pic2.mask)&~pic2.mask2)
|
||||
pic.pend |= (1 << 2);
|
||||
else
|
||||
pic.pend &= ~(1 << 2);
|
||||
pic_intpending = (pic.pend & ~pic.mask) & ~pic.mask2;
|
||||
if (!((pic.mask | pic.mask2) & (1 << 2)))
|
||||
pic_intpending |= ((pic2.pend&~pic2.mask)&~pic2.mask2);
|
||||
{
|
||||
temp_pending = ((pic2.pend&~pic2.mask)&~pic2.mask2);
|
||||
temp_pending <<= 8;
|
||||
pic_intpending |= temp_pending;
|
||||
}
|
||||
/* pclog("pic_intpending = %i %02X %02X %02X %02X\n", pic_intpending, pic.ins, pic.pend, pic.mask, pic.mask2);
|
||||
pclog(" %02X %02X %02X %02X %i %i\n", pic2.ins, pic2.pend, pic2.mask, pic2.mask2, ((pic.mask | pic.mask2) & (1 << 2)), ((pic2.pend&~pic2.mask)&~pic2.mask2));*/
|
||||
pclog(" %02X %02X %02X %02X %i %i\n", pic2.ins, pic2.pend, pic2.mask, pic2.mask2, ((pic.mask | pic.mask2) & (1 << 2)), ((pic2.pend&~pic2.mask)&~pic2.mask2)); */
|
||||
}
|
||||
|
||||
|
||||
@@ -45,6 +50,7 @@ void pic_update_mask(uint8_t *mask, uint8_t ins)
|
||||
if (ins & (1 << c))
|
||||
{
|
||||
*mask = 0xff << c;
|
||||
// pclog("Mask is: %02X\n", *mask);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -73,9 +79,10 @@ static void pic_autoeoi()
|
||||
void pic_write(uint16_t addr, uint8_t val, void *priv)
|
||||
{
|
||||
int c;
|
||||
// pclog("Write PIC %04X %02X %04X(%06X):%04X\n",addr,val,CS,cs,pc);
|
||||
// if (addr&1) pclog("Write PIC %04X %02X %04X(%06X):%04X\n",addr,val,CS,cs,cpu_state.pc);
|
||||
if (addr&1)
|
||||
{
|
||||
// pclog("PIC ICW is: %i\n", pic.icw);
|
||||
switch (pic.icw)
|
||||
{
|
||||
case 0: /*OCW1*/
|
||||
@@ -85,7 +92,7 @@ void pic_write(uint16_t addr, uint8_t val, void *priv)
|
||||
break;
|
||||
case 1: /*ICW2*/
|
||||
pic.vector=val&0xF8;
|
||||
// printf("PIC vector now %02X\n",pic.vector);
|
||||
// printf("PIC vector now %02X\n",pic.vector);
|
||||
// output=1;
|
||||
if (pic.icw1&2) pic.icw=3;
|
||||
else pic.icw=2;
|
||||
@@ -96,7 +103,7 @@ void pic_write(uint16_t addr, uint8_t val, void *priv)
|
||||
break;
|
||||
case 3: /*ICW4*/
|
||||
pic.icw4 = val;
|
||||
// pclog("ICW4 = %02x\n", val);
|
||||
// pclog("ICW4 = %02x\n", val);
|
||||
pic.icw=0;
|
||||
break;
|
||||
}
|
||||
@@ -105,6 +112,7 @@ void pic_write(uint16_t addr, uint8_t val, void *priv)
|
||||
{
|
||||
if (val&16) /*ICW1*/
|
||||
{
|
||||
// pclog("ICW1 = %02x\n", val);
|
||||
pic.mask = 0;
|
||||
pic.mask2=0;
|
||||
pic.icw=1;
|
||||
@@ -120,7 +128,7 @@ void pic_write(uint16_t addr, uint8_t val, void *priv)
|
||||
// pclog("Specific EOI - %02X %i\n",pic.ins,1<<(val&7));
|
||||
pic.ins&=~(1<<(val&7));
|
||||
pic_update_mask(&pic.mask2, pic.ins);
|
||||
if (val == 2 && (pic2.pend&~pic2.mask)&~pic2.mask2)
|
||||
if ((val&7) == 2 && (pic2.pend&~pic2.mask)&~pic2.mask2)
|
||||
pic.pend |= (1 << 2);
|
||||
// pic.pend&=(1<<(val&7));
|
||||
// if ((val&7)==1) pollkeywaiting();
|
||||
@@ -285,6 +293,7 @@ int pic_current[16];
|
||||
|
||||
void picint(uint16_t num)
|
||||
{
|
||||
int old_pend = pic_intpending;
|
||||
if (AT && num == (1 << 2))
|
||||
num = 1 << 9;
|
||||
// pclog("picint : %04X\n", num);
|
||||
@@ -299,8 +308,15 @@ void picint(uint16_t num)
|
||||
{
|
||||
pic.pend|=num;
|
||||
}
|
||||
// pclog("picint : PEND now %02X %02X\n", pic.pend, pic2.pend);
|
||||
/* if (num == 0x40)
|
||||
{
|
||||
pclog("picint : PEND now %02X %02X\n", pic.pend, pic2.pend);
|
||||
} */
|
||||
pic_updatepending();
|
||||
/* if (num == 0x40)
|
||||
{
|
||||
pclog("Processing FDC interrupt, pending: %s, previously pending: %s, masked: %s, masked (2): %s, T: %s, I: %s\n", (pic_intpending & num) ? "yes" : "no", (old_pend & num) ? "yes" : "no", (pic.mask & num) ? "yes" : "no", (pic.mask2 & num) ? "yes" : "no", (flags & 0x100) ? "yes" : "no", (flags&I_FLAG) ? "yes" : "no");
|
||||
} */
|
||||
}
|
||||
|
||||
void picintlevel(uint16_t num)
|
||||
|
||||
124
src/piix.c
124
src/piix.c
@@ -35,10 +35,11 @@ void piix_write(int func, int addr, uint8_t val, void *priv)
|
||||
switch (addr)
|
||||
{
|
||||
case 0x04:
|
||||
card_piix_ide[0x04] = (card_piix_ide[0x04] & ~5) | (val & 5);
|
||||
card_piix_ide[0x04] = (val & 5) | 2;
|
||||
break;
|
||||
case 0x07:
|
||||
card_piix_ide[0x07] = (card_piix_ide[0x07] & ~0x38) | (val & 0x38);
|
||||
card_piix_ide[0x07] = val & 0x3e;
|
||||
// card_piix_ide[0x07] = (card_piix_ide[0x07] & ~0x38) | (val & 0x38);
|
||||
break;
|
||||
case 0x0d:
|
||||
card_piix_ide[0x0d] = val;
|
||||
@@ -86,7 +87,7 @@ void piix_write(int func, int addr, uint8_t val, void *priv)
|
||||
if (card_piix_ide[0x04] & 1)
|
||||
io_sethandler(base, 0x10, piix_bus_master_read, NULL, NULL, piix_bus_master_write, NULL, NULL, NULL);
|
||||
}
|
||||
// pclog("PIIX write %02X %02X\n", addr, val);
|
||||
// pclog("PIIX write %02X %02X\n", addr, val);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -97,7 +98,32 @@ void piix_write(int func, int addr, uint8_t val, void *priv)
|
||||
case 0x0e:
|
||||
return;
|
||||
}
|
||||
if (addr == 0x6A)
|
||||
if (addr == 0x4C)
|
||||
{
|
||||
if (!((val ^ card_piix[addr]) & 0x80))
|
||||
{
|
||||
card_piix[addr] = val;
|
||||
return;
|
||||
}
|
||||
|
||||
card_piix[addr] = val;
|
||||
if (val & 0x80)
|
||||
{
|
||||
if (piix_type == 3)
|
||||
{
|
||||
dma_alias_remove();
|
||||
}
|
||||
else
|
||||
{
|
||||
dma_alias_remove_piix();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
dma_alias_set();
|
||||
}
|
||||
}
|
||||
else if (addr == 0x6A)
|
||||
{
|
||||
if (piix_type == 1)
|
||||
card_piix[addr] = (val & 0xFC) | (card_piix[addr] | 3);
|
||||
@@ -117,11 +143,11 @@ uint8_t piix_read(int func, int addr, void *priv)
|
||||
|
||||
if (func == 1) /*IDE*/
|
||||
{
|
||||
// pclog("PIIX IDE read %02X %02X\n", addr, card_piix_ide[addr]);
|
||||
// pclog("PIIX IDE read %02X %02X\n", addr, card_piix_ide[addr]);
|
||||
|
||||
if (addr == 4)
|
||||
{
|
||||
return (card_piix_ide[addr] & 4) | 3;
|
||||
return (card_piix_ide[addr] & 5) | 2;
|
||||
}
|
||||
else if (addr == 5)
|
||||
{
|
||||
@@ -141,7 +167,7 @@ uint8_t piix_read(int func, int addr, void *priv)
|
||||
}
|
||||
else if (addr == 0x20)
|
||||
{
|
||||
return card_piix_ide[addr] & 0xF1;
|
||||
return (card_piix_ide[addr] & 0xF0) | 1;
|
||||
}
|
||||
else if (addr == 0x22)
|
||||
{
|
||||
@@ -470,10 +496,10 @@ void piix_bus_master_set_irq(int channel)
|
||||
piix_busmaster[channel].status |= 4;
|
||||
}
|
||||
|
||||
void piix_init(int card)
|
||||
static int reset_reg = 0;
|
||||
|
||||
void piix_reset()
|
||||
{
|
||||
pci_add_specific(card, piix_read, piix_write, NULL);
|
||||
|
||||
memset(card_piix, 0, 256);
|
||||
card_piix[0x00] = 0x86; card_piix[0x01] = 0x80; /*Intel*/
|
||||
card_piix[0x02] = 0x2e; card_piix[0x03] = 0x12; /*82371FB (PIIX)*/
|
||||
@@ -509,16 +535,10 @@ void piix_init(int card)
|
||||
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;
|
||||
|
||||
piix_type = 1;
|
||||
|
||||
ide_set_bus_master(piix_bus_master_sector_read, piix_bus_master_sector_write, piix_bus_master_set_irq);
|
||||
}
|
||||
|
||||
void piix3_init(int card)
|
||||
void piix3_reset()
|
||||
{
|
||||
pci_add_specific(card, piix_read, piix_write, NULL);
|
||||
|
||||
memset(card_piix, 0, 256);
|
||||
card_piix[0x00] = 0x86; card_piix[0x01] = 0x80; /*Intel*/
|
||||
card_piix[0x02] = 0x00; card_piix[0x03] = 0x70; /*82371SB (PIIX3)*/
|
||||
@@ -556,8 +576,78 @@ void piix3_init(int card)
|
||||
card_piix_ide[0x40] = card_piix_ide[0x41] = 0x00;
|
||||
card_piix_ide[0x42] = card_piix_ide[0x43] = 0x00;
|
||||
card_piix_ide[0x44] = 0x00;
|
||||
}
|
||||
|
||||
static uint8_t rc_read(uint16_t port, void *priv)
|
||||
{
|
||||
return reset_reg & 0xfb;
|
||||
}
|
||||
|
||||
static void rc_write(uint16_t port, uint8_t val, void *priv)
|
||||
{
|
||||
if (!(reset_reg & 4) && (val & 4))
|
||||
{
|
||||
if (reset_reg & 2)
|
||||
{
|
||||
// pclog("PIIX: Hard reset\n");
|
||||
resetpchard();
|
||||
}
|
||||
else
|
||||
{
|
||||
// pclog("PIIX: Soft reset\n");
|
||||
if (piix_type == 3)
|
||||
{
|
||||
piix3_reset();
|
||||
}
|
||||
else
|
||||
{
|
||||
piix_reset();
|
||||
}
|
||||
resetide();
|
||||
softresetx86();
|
||||
}
|
||||
}
|
||||
reset_reg = val;
|
||||
}
|
||||
|
||||
void piix_init(int card)
|
||||
{
|
||||
pci_add_specific(card, piix_read, piix_write, NULL);
|
||||
|
||||
piix_reset();
|
||||
|
||||
reset_reg = 0;
|
||||
|
||||
piix_type = 1;
|
||||
|
||||
ide_set_bus_master(piix_bus_master_sector_read, piix_bus_master_sector_write, piix_bus_master_set_irq);
|
||||
|
||||
io_sethandler(0x0cf9, 0x0001, rc_read, NULL, NULL, rc_write, NULL, NULL, NULL);
|
||||
|
||||
port_92_reset();
|
||||
|
||||
port_92_add();
|
||||
|
||||
dma_alias_set();
|
||||
}
|
||||
|
||||
void piix3_init(int card)
|
||||
{
|
||||
pci_add_specific(card, piix_read, piix_write, NULL);
|
||||
|
||||
piix3_reset();
|
||||
|
||||
reset_reg = 0;
|
||||
|
||||
piix_type = 3;
|
||||
|
||||
ide_set_bus_master(piix_bus_master_sector_read, piix_bus_master_sector_write, piix_bus_master_set_irq);
|
||||
|
||||
io_sethandler(0x0cf9, 0x0001, rc_read, NULL, NULL, rc_write, NULL, NULL, NULL);
|
||||
|
||||
port_92_reset();
|
||||
|
||||
port_92_add();
|
||||
|
||||
dma_alias_set();
|
||||
}
|
||||
|
||||
@@ -59,7 +59,6 @@ void pit_reset()
|
||||
pit.m[0]=pit.m[1]=pit.m[2]=0;
|
||||
pit.ctrls[0]=pit.ctrls[1]=pit.ctrls[2]=0;
|
||||
pit.thit[0]=1;
|
||||
spkstat=0;
|
||||
pit.gate[0] = pit.gate[1] = 1;
|
||||
pit.gate[2] = 0;
|
||||
pit.using_timer[0] = pit.using_timer[1] = pit.using_timer[2] = 1;
|
||||
|
||||
@@ -9,7 +9,7 @@ extern "C" {
|
||||
void mouse_close();
|
||||
extern int mouse_buttons;
|
||||
void mouse_poll_host();
|
||||
void mouse_get_mickeys(int *x, int *y);
|
||||
void mouse_get_mickeys(int *x, int *y, int *z);
|
||||
extern int mousecapture;
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
@@ -216,7 +216,10 @@ void ps1_m2121_write(uint16_t port, uint8_t val, void *p)
|
||||
{
|
||||
case 0x0092:
|
||||
if (val & 1)
|
||||
{
|
||||
softresetx86();
|
||||
cpu_set_edx();
|
||||
}
|
||||
ps1_92 = val & ~1;
|
||||
mem_a20_alt = val & 2;
|
||||
mem_a20_recalc();
|
||||
|
||||
@@ -5,13 +5,13 @@
|
||||
#define IDM_FILE_HRESET 40001
|
||||
#define IDM_FILE_EXIT 40002
|
||||
#define IDM_FILE_RESET_CAD 40003
|
||||
#define IDM_DISC_A 40010
|
||||
#define IDM_DISC_B 40011
|
||||
#define IDM_EJECT_A 40012
|
||||
#define IDM_EJECT_B 40013
|
||||
#define IDM_DISC_1 40010
|
||||
#define IDM_DISC_2 40011
|
||||
#define IDM_EJECT_1 40012
|
||||
#define IDM_EJECT_2 40013
|
||||
#define IDM_HDCONF 40014
|
||||
#define IDM_DISC_A_WP 40015
|
||||
#define IDM_DISC_B_WP 40016
|
||||
#define IDM_DISC_1_WP 40015
|
||||
#define IDM_DISC_2_WP 40016
|
||||
#define IDM_CONFIG 40020
|
||||
#define IDM_CONFIG_LOAD 40021
|
||||
#define IDM_CONFIG_SAVE 40022
|
||||
@@ -25,7 +25,16 @@
|
||||
#define IDM_VID_FS_43 40072
|
||||
#define IDM_VID_FS_SQ 40073
|
||||
#define IDM_VID_FS_INT 40074
|
||||
#define IDM_VID_SCREENSHOT 40075
|
||||
#define IDM_VID_FORCE43 40075
|
||||
#define IDM_VID_OVERSCAN 40076
|
||||
#define IDM_VID_FLASH 40077
|
||||
#define IDM_VID_SCREENSHOT 40078
|
||||
#define IDM_DISC_3 40079
|
||||
#define IDM_DISC_4 40080
|
||||
#define IDM_EJECT_3 40081
|
||||
#define IDM_EJECT_4 40082
|
||||
#define IDM_DISC_3_WP 40083
|
||||
#define IDM_DISC_4_WP 40084
|
||||
#define IDM_CDROM_ISO 40100
|
||||
#define IDM_CDROM_EMPTY 40200
|
||||
#define IDM_CDROM_REAL 40200
|
||||
@@ -56,28 +65,25 @@
|
||||
#define IDC_COMBO386 1005
|
||||
#define IDC_COMBO486 1006
|
||||
#define IDC_COMBOSND 1007
|
||||
#define IDC_COMBOCHC 1008
|
||||
#define IDC_COMBONET 1009
|
||||
#define IDC_COMBONET 1008
|
||||
#define IDC_COMBOCPUM 1060
|
||||
#define IDC_COMBOSPD 1061
|
||||
#define IDC_COMBODRA 1062
|
||||
#define IDC_COMBODRB 1063
|
||||
#define IDC_COMBODR1 1062
|
||||
#define IDC_COMBODR2 1063
|
||||
#define IDC_COMBOJOY 1064
|
||||
#define IDC_COMBOWS 1065
|
||||
#define IDC_COMBOMOUSE 1066
|
||||
#define IDC_COMBODR3 1067
|
||||
#define IDC_COMBODR4 1068
|
||||
#define IDC_CHECK1 1010
|
||||
#define IDC_CHECK2 1011
|
||||
#define IDC_CHECK3 1012
|
||||
#define IDC_CHECK4 1013
|
||||
#define IDC_CHECKGUS 1014
|
||||
#define IDC_CHECKSSI 1015
|
||||
#define IDC_CHECKVOODOO 1016
|
||||
#define IDC_CHECKDYNAREC 1017
|
||||
#define IDC_CHECK_AHA154X 1018
|
||||
#define IDC_CHECKGUS 1013
|
||||
#define IDC_CHECKSSI 1014
|
||||
#define IDC_CHECKVOODOO 1015
|
||||
#define IDC_CHECKDYNAREC 1016
|
||||
#define IDC_STATIC 1020
|
||||
#define IDC_CHECKFORCE43 1021
|
||||
#define IDC_CHECKOVERSCAN 1022
|
||||
#define IDC_CHECKFLASH 1023
|
||||
#define IDC_CHECKSYNC 1024
|
||||
#define IDC_CHECKSERIAL 1025
|
||||
#define IDC_EDIT1 1030
|
||||
#define IDC_EDIT2 1031
|
||||
#define IDC_EDIT3 1032
|
||||
@@ -103,6 +109,14 @@
|
||||
#define IDC_FNEW 1063
|
||||
#define IDC_EJECTE 1064
|
||||
#define IDC_EJECTF 1065
|
||||
#define IDC_EDITG 1066
|
||||
#define IDC_GFILE 1067
|
||||
#define IDC_GNEW 1068
|
||||
#define IDC_EDITH 1069
|
||||
#define IDC_HFILE 1070
|
||||
#define IDC_HNEW 1071
|
||||
#define IDC_EJECTG 1072
|
||||
#define IDC_EJECTH 1073
|
||||
#define IDC_MEMSPIN 1070
|
||||
#define IDC_MEMTEXT 1071
|
||||
#define IDC_CHDD 1080
|
||||
@@ -113,8 +127,10 @@
|
||||
#define IDC_ECDROM 1085
|
||||
#define IDC_FHDD 1086
|
||||
#define IDC_FCDROM 1087
|
||||
#define IDC_GCDROM 1088
|
||||
#define IDC_HCDROM 1089
|
||||
#define IDC_GHDD 1088
|
||||
#define IDC_GCDROM 1089
|
||||
#define IDC_HHDD 1090
|
||||
#define IDC_HCDROM 1091
|
||||
#define IDC_STEXT1 1100
|
||||
#define IDC_STEXT2 1101
|
||||
#define IDC_STEXT3 1102
|
||||
@@ -138,19 +154,30 @@
|
||||
#define IDC_EDIT_F_SPT 1209
|
||||
#define IDC_EDIT_F_HPC 1210
|
||||
#define IDC_EDIT_F_CYL 1211
|
||||
#define IDC_EDIT_G_SPT 1212
|
||||
#define IDC_EDIT_G_HPC 1213
|
||||
#define IDC_EDIT_G_CYL 1214
|
||||
#define IDC_EDIT_H_SPT 1215
|
||||
#define IDC_EDIT_H_HPC 1216
|
||||
#define IDC_EDIT_H_CYL 1217
|
||||
#define IDC_TEXT_C_SIZE 1220
|
||||
#define IDC_TEXT_D_SIZE 1221
|
||||
#define IDC_TEXT_E_SIZE 1222
|
||||
#define IDC_TEXT_F_SIZE 1223
|
||||
#define IDC_TEXT_G_SIZE 1224
|
||||
#define IDC_TEXT_H_SIZE 1225
|
||||
#define IDC_EDIT_C_FN 1230
|
||||
#define IDC_EDIT_D_FN 1231
|
||||
#define IDC_EDIT_E_FN 1232
|
||||
#define IDC_EDIT_F_FN 1233
|
||||
#define IDC_EDIT_G_FN 1234
|
||||
#define IDC_EDIT_H_FN 1235
|
||||
|
||||
#define IDC_CONFIGUREVID 1200
|
||||
#define IDC_CONFIGURESND 1201
|
||||
#define IDC_CONFIGUREVOODOO 1202
|
||||
#define IDC_CONFIGURENET 1203
|
||||
#define IDC_CONFIGUREMOD 1203
|
||||
#define IDC_CONFIGURENET 1204
|
||||
#define IDC_JOY1 1210
|
||||
#define IDC_JOY2 1211
|
||||
#define IDC_JOY3 1212
|
||||
@@ -160,3 +187,13 @@
|
||||
|
||||
#define WM_RESETD3D WM_USER
|
||||
#define WM_LEAVEFULLSCREEN WM_USER + 1
|
||||
|
||||
#define C_BASE 6 /* End at 38. */
|
||||
#define D_BASE 60 /* End at 92. */
|
||||
#define E_BASE 114 /* End at 146. */
|
||||
#define F_BASE 168 /* End at 200. */
|
||||
#define G_BASE 222 /* End at 254. */
|
||||
#define H_BASE 276 /* End at 308. */
|
||||
#define CMD_BASE 334
|
||||
#define DLG_HEIGHT 366
|
||||
|
||||
|
||||
@@ -211,6 +211,7 @@ void scat_write(uint16_t port, uint8_t val, void *priv)
|
||||
if ((~scat_port_92 & val) & 1)
|
||||
{
|
||||
softresetx86();
|
||||
cpu_set_edx();
|
||||
}
|
||||
scat_port_92 = val;
|
||||
break;
|
||||
|
||||
@@ -16,7 +16,6 @@ static uint8_t *SegmentBufferGet(SGBUF *SegmentBuf, uint32_t Data)
|
||||
if (SegmentBuf->SegmentIndex == SegmentBuf->SegmentNum
|
||||
&& !SegmentBuf->SegmentLeft)
|
||||
{
|
||||
Data = 0;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -33,8 +32,6 @@ static uint8_t *SegmentBufferGet(SGBUF *SegmentBuf, uint32_t Data)
|
||||
SegmentBuf->SegmentPtrCur = SegmentBuf->SegmentPtr[SegmentBuf->SegmentIndex].Address;
|
||||
SegmentBuf->SegmentLeft = SegmentBuf->SegmentPtr[SegmentBuf->SegmentIndex].Length;
|
||||
}
|
||||
|
||||
Data = DataSize;
|
||||
}
|
||||
else
|
||||
SegmentBuf->SegmentPtrCur = (uint8_t *)SegmentBuf->SegmentPtrCur + DataSize;
|
||||
@@ -76,18 +73,42 @@ uint32_t SegmentBufferCopy(SGBUF *SegmentDst, SGBUF *SegmentSrc, uint32_t Copy)
|
||||
uint32_t SegmentBufferCopyFromBuf(SGBUF *SegmentBuf, uint8_t *BufSrc, uint32_t Copy)
|
||||
{
|
||||
uint32_t Left = Copy;
|
||||
|
||||
while (Left)
|
||||
{
|
||||
uint32_t ThisCopy = Left;
|
||||
uint8_t *BufDst = SegmentBufferGet(SegmentBuf, ThisCopy);
|
||||
|
||||
uint32_t ThisCopy = MIN(MIN(SegmentBuf->SegmentLeft, Left), (uint32_t)BufSrc);
|
||||
if (!ThisCopy)
|
||||
break;
|
||||
|
||||
uint32_t Tmp = ThisCopy;
|
||||
uint8_t *BufDst = SegmentBufferGet(SegmentBuf, Tmp);
|
||||
|
||||
memcpy(BufDst, BufSrc, ThisCopy);
|
||||
|
||||
BufDst += ThisCopy;
|
||||
BufSrc -= ThisCopy;
|
||||
Left -= ThisCopy;
|
||||
}
|
||||
|
||||
return Copy - Left;
|
||||
}
|
||||
|
||||
uint32_t SegmentBufferCopyToBuf(SGBUF *SegmentBuf, uint8_t *BufDst, uint32_t Copy)
|
||||
{
|
||||
uint32_t Left = Copy;
|
||||
while (Left)
|
||||
{
|
||||
uint32_t ThisCopy = MIN(MIN(SegmentBuf->SegmentLeft, Left), (uint32_t)BufDst);
|
||||
if (!ThisCopy)
|
||||
break;
|
||||
|
||||
uint32_t Tmp = ThisCopy;
|
||||
uint8_t *BufSrc = SegmentBufferGet(SegmentBuf, Tmp);
|
||||
|
||||
memcpy(BufSrc, BufDst, ThisCopy);
|
||||
|
||||
BufSrc += ThisCopy;
|
||||
BufDst -= ThisCopy;
|
||||
Left -= ThisCopy;
|
||||
BufSrc = (void *)((uintptr_t)BufSrc + ThisCopy);
|
||||
}
|
||||
|
||||
return Copy - Left;
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
typedef struct SGSEG
|
||||
{
|
||||
uint8_t Address[128*512];
|
||||
uint8_t Address[512];
|
||||
uint32_t Length;
|
||||
} SGSEG;
|
||||
|
||||
|
||||
85
src/scsi.c
85
src/scsi.c
@@ -14,42 +14,6 @@
|
||||
int ScsiCallback[7] = {0,0,0,0,0,0,0};
|
||||
uint8_t scsi_cdrom_id = 3; /*common setting*/
|
||||
|
||||
uint8_t SCSIDeviceIsPresent(SCSI *Scsi)
|
||||
{
|
||||
return (scsi_cdrom_id < 7 && Scsi->LunType != SCSI_NONE);
|
||||
}
|
||||
|
||||
void SCSIReadTransfer(SCSI *Scsi, uint8_t Id)
|
||||
{
|
||||
if (Scsi->LunType == SCSI_CDROM)
|
||||
{
|
||||
SCSICDROM_CallRead(Scsi, Id);
|
||||
}
|
||||
|
||||
pclog("SCSI: Read Transfer\n");
|
||||
SGBUF SegmentBuffer;
|
||||
SegmentBufferInit(&SegmentBuffer, &Scsi->SegmentData, 1);
|
||||
pfnIoRequestCopyFromBuffer(0, &SegmentBuffer, Scsi->SegmentData.Length);
|
||||
}
|
||||
|
||||
void SCSIWriteTransfer(SCSI *Scsi, uint8_t Id)
|
||||
{
|
||||
if (Scsi->LunType == SCSI_CDROM)
|
||||
{
|
||||
if ((Scsi->CdbLength >= prefix_len + 4) && (page_flags[page_current] & PAGE_CHANGEABLE))
|
||||
{
|
||||
mode_pages_in[page_current][Scsi->CdbLength - prefix_len - 4] = Scsi->Cdb[Scsi->CdbLength - 2];
|
||||
mode_pages_in[page_current][Scsi->CdbLength - prefix_len - 3] = Scsi->Cdb[Scsi->CdbLength - 1];
|
||||
}
|
||||
}
|
||||
|
||||
pclog("SCSI: Write Transfer\n");
|
||||
|
||||
SGBUF SegmentBuffer;
|
||||
SegmentBufferInit(&SegmentBuffer, &Scsi->SegmentData, 1);
|
||||
pfnIoRequestCopyToBuffer(0, &SegmentBuffer, Scsi->SegmentData.Length);
|
||||
}
|
||||
|
||||
void SCSIQueryResidual(SCSI *Scsi, uint32_t *Residual)
|
||||
{
|
||||
*Residual = ScsiStatus == SCSI_STATUS_OK ? 0 : Scsi->SegmentData.Length;
|
||||
@@ -87,31 +51,37 @@ static uint32_t SCSICopyToBuffer(uint32_t OffSrc, SGBUF *SegmentBuffer,
|
||||
return Copied;
|
||||
}
|
||||
|
||||
void SCSISendCommand(SCSI *Scsi, uint8_t Id, uint8_t *Cdb, uint8_t CdbLength,
|
||||
uint32_t BufferLength, uint8_t *SenseBufferPointer,
|
||||
uint8_t SenseBufferLength)
|
||||
void SCSIWriteTransfer(SCSI *Scsi, uint8_t Id)
|
||||
{
|
||||
if ((Scsi->BufferPosition >= prefix_len + 4) && (page_flags[page_current] & PAGE_CHANGEABLE))
|
||||
{
|
||||
mode_pages_in[page_current][Scsi->BufferPosition - prefix_len - 4] = Scsi->SegmentData.Address[Scsi->BufferPosition - 2];
|
||||
mode_pages_in[page_current][Scsi->BufferPosition - prefix_len - 3] = Scsi->SegmentData.Address[Scsi->BufferPosition - 1];
|
||||
}
|
||||
SGBUF SegmentBuffer;
|
||||
SCSICopyToBuffer(Scsi->SegmentData.Length, &SegmentBuffer, 1);
|
||||
pfnIoRequestCopyToBuffer(0, &SegmentBuffer, Scsi->SegmentData.Length);
|
||||
}
|
||||
|
||||
void SCSIReadTransfer(SCSI *Scsi, uint8_t Id)
|
||||
{
|
||||
SCSICDROM_ReadCallback(Scsi, Id);
|
||||
|
||||
SGBUF SegmentBuffer;
|
||||
SCSICopyFromBuffer(Scsi->SegmentData.Length, &SegmentBuffer, 1);
|
||||
pfnIoRequestCopyFromBuffer(0, &SegmentBuffer, Scsi->SegmentData.Length);
|
||||
}
|
||||
|
||||
void SCSISendCommand(SCSI *Scsi, uint8_t Id, uint8_t *Cdb, uint8_t CdbLength, uint32_t DataBufferLength, uint8_t *SenseBufferPointer, uint8_t SenseBufferLength)
|
||||
{
|
||||
uint32_t i;
|
||||
for (i = 0; i < CdbLength; i++)
|
||||
pclog("Cdb[%d]=%02X\n", i, Cdb[i]);
|
||||
pclog("Cdb[%d]=0x%02X\n", i, Cdb[i]);
|
||||
|
||||
Scsi->SegmentData.Length = BufferLength;
|
||||
Scsi->CdbLength = CdbLength;
|
||||
|
||||
if (SCSIDeviceIsPresent(Scsi))
|
||||
{
|
||||
if (Scsi->LunType == SCSI_CDROM)
|
||||
{
|
||||
pclog("SCSI CD-ROM in ID %d\n", Id);
|
||||
SCSICDROM_RunCommand(Scsi, Id, Cdb);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
pclog("SCSI Device not present\n");
|
||||
ScsiStatus = SCSI_STATUS_CHECK_CONDITION;
|
||||
SCSISenseCodeError(SENSE_ILLEGAL_REQUEST, 0x00, 0x00);
|
||||
}
|
||||
pclog("SCSI CD-ROM in ID %d\n", Id);
|
||||
SCSICDROM_RunCommand(Scsi, Id, Cdb, SenseBufferLength, SenseBufferPointer, DataBufferLength);
|
||||
}
|
||||
|
||||
void SCSIReset(SCSI *Scsi, uint8_t Id)
|
||||
@@ -119,8 +89,6 @@ void SCSIReset(SCSI *Scsi, uint8_t Id)
|
||||
page_flags[GPMODE_CDROM_AUDIO_PAGE] &= 0xFD; /* Clear changed flag for CDROM AUDIO mode page. */
|
||||
memset(mode_pages_in[GPMODE_CDROM_AUDIO_PAGE], 0, 256); /* Clear the page itself. */
|
||||
|
||||
ScsiCallback[Id] = 0;
|
||||
|
||||
if (scsi_cdrom_enabled)
|
||||
{
|
||||
if (cdrom_enabled)
|
||||
@@ -131,8 +99,7 @@ void SCSIReset(SCSI *Scsi, uint8_t Id)
|
||||
else
|
||||
{
|
||||
Scsi->LunType = SCSI_NONE;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
pfnIoRequestCopyFromBuffer = SCSICopyFromBuffer;
|
||||
pfnIoRequestCopyToBuffer = SCSICopyToBuffer;
|
||||
|
||||
20
src/scsi.h
20
src/scsi.h
@@ -181,6 +181,11 @@ extern int prev_status;
|
||||
#define SCSI_HDD 1 /*not present yet*/
|
||||
#define SCSI_CDROM 2
|
||||
|
||||
// extern sector_buffer_t cdrom_sector_buffer;
|
||||
|
||||
// extern int cdrom_sector_type, cdrom_sector_flags;
|
||||
// extern int cdrom_sector_size, cdrom_sector_ismsf;
|
||||
|
||||
typedef struct SCSI
|
||||
{
|
||||
uint8_t Cdb[32];
|
||||
@@ -188,9 +193,13 @@ typedef struct SCSI
|
||||
SGBUF SegmentBuffer;
|
||||
int SectorLen;
|
||||
int SectorLba;
|
||||
int BufferLength;
|
||||
int BufferPosition;
|
||||
SGSEG SegmentData;
|
||||
int LunType;
|
||||
uint8_t PacketStatus;
|
||||
int ReadCDCallback;
|
||||
int RequestSenseEnabled;
|
||||
void *p;
|
||||
} SCSI;
|
||||
|
||||
@@ -198,15 +207,14 @@ SCSI ScsiDrives[7];
|
||||
|
||||
void SCSIQueryResidual(SCSI *Scsi, uint32_t *Residual);
|
||||
|
||||
void SCSISendCommand(SCSI *Scsi, uint8_t Id, uint8_t *Cdb, uint8_t CdbLength,
|
||||
uint32_t BufferLength, uint8_t *SenseBufferPointer,
|
||||
uint8_t SenseBufferLength);
|
||||
void SCSISendCommand(SCSI *Scsi, uint8_t Id, uint8_t *Cdb, uint8_t CdbLength,
|
||||
uint32_t DataBufferLength, uint8_t *SenseBufferPointer,
|
||||
uint8_t SenseBufferLength);
|
||||
|
||||
uint32_t (*pfnIoRequestCopyFromBuffer)(uint32_t OffDst, SGBUF *SegmentBuffer,
|
||||
uint32_t Copy);
|
||||
uint32_t (*pfnIoRequestCopyToBuffer)(uint32_t OffSrc, SGBUF *SegmentBuffer,
|
||||
uint32_t Copy);
|
||||
|
||||
uint32_t Copy);
|
||||
void SCSIReadTransfer(SCSI *Scsi, uint8_t Id);
|
||||
void SCSIWriteTransfer(SCSI *Scsi, uint8_t Id);
|
||||
|
||||
@@ -217,6 +225,8 @@ extern uint8_t SCSICDROMSetProfile(uint8_t *buf, uint8_t *index, uint16_t profil
|
||||
extern int SCSICDROMReadDVDStructure(int format, const uint8_t *packet, uint8_t *buf);
|
||||
extern uint32_t SCSICDROMEventStatus(uint8_t *buffer);
|
||||
|
||||
extern void SCSICDROM_ReadyHandler(int IsReady);
|
||||
extern void SCSICDROM_Insert();
|
||||
// extern int cdrom_add_error_and_subchannel(uint8_t *b, int real_sector_type);
|
||||
|
||||
#endif
|
||||
1019
src/scsi_cdrom.c
1019
src/scsi_cdrom.c
File diff suppressed because it is too large
Load Diff
26
src/serial.c
26
src/serial.c
@@ -18,14 +18,10 @@ enum
|
||||
|
||||
SERIAL serial1, serial2;
|
||||
|
||||
int mousepos=-1;
|
||||
int mousedelay;
|
||||
|
||||
void serial_reset()
|
||||
{
|
||||
serial1.iir = serial1.ier = serial1.lcr = 0;
|
||||
serial2.iir = serial2.ier = serial2.lcr = 0;
|
||||
mousedelay = 0;
|
||||
serial1.fifo_read = serial1.fifo_write = 0;
|
||||
serial2.fifo_read = serial2.fifo_write = 0;
|
||||
}
|
||||
@@ -123,7 +119,7 @@ void serial_write(uint16_t addr, uint8_t val, void *p)
|
||||
if ((val & 2) && !(serial->mctrl & 2))
|
||||
{
|
||||
if (serial->rcr_callback)
|
||||
serial->rcr_callback(serial);
|
||||
serial->rcr_callback(serial, serial->rcr_callback_p);
|
||||
// pclog("RCR raised! sending M\n");
|
||||
}
|
||||
serial->mctrl = val;
|
||||
@@ -263,11 +259,17 @@ void serial1_set(uint16_t addr, int irq)
|
||||
serial1_remove();
|
||||
io_sethandler(addr, 0x0008, serial_read, NULL, NULL, serial_write, NULL, NULL, &serial1);
|
||||
serial1.irq = irq;
|
||||
// pclog("serial1_set(%04X, %02X)\n", addr, irq);
|
||||
}
|
||||
void serial1_remove()
|
||||
{
|
||||
io_removehandler(0x208, 0x0008, serial_read, NULL, NULL, serial_write, NULL, NULL, &serial1);
|
||||
io_removehandler(0x228, 0x0008, serial_read, NULL, NULL, serial_write, NULL, NULL, &serial1);
|
||||
io_removehandler(0x238, 0x0008, serial_read, NULL, NULL, serial_write, NULL, NULL, &serial1);
|
||||
io_removehandler(0x2e0, 0x0008, serial_read, NULL, NULL, serial_write, NULL, NULL, &serial1);
|
||||
io_removehandler(0x2e8, 0x0008, serial_read, NULL, NULL, serial_write, NULL, NULL, &serial1);
|
||||
io_removehandler(0x2f8, 0x0008, serial_read, NULL, NULL, serial_write, NULL, NULL, &serial1);
|
||||
io_removehandler(0x338, 0x0008, serial_read, NULL, NULL, serial_write, NULL, NULL, &serial1);
|
||||
io_removehandler(0x3e8, 0x0008, serial_read, NULL, NULL, serial_write, NULL, NULL, &serial1);
|
||||
io_removehandler(0x3f8, 0x0008, serial_read, NULL, NULL, serial_write, NULL, NULL, &serial1);
|
||||
}
|
||||
@@ -285,11 +287,17 @@ void serial2_set(uint16_t addr, int irq)
|
||||
serial2_remove();
|
||||
io_sethandler(addr, 0x0008, serial_read, NULL, NULL, serial_write, NULL, NULL, &serial2);
|
||||
serial2.irq = irq;
|
||||
// pclog("serial2_set(%04X, %02X)\n", addr, irq);
|
||||
}
|
||||
void serial2_remove()
|
||||
{
|
||||
io_removehandler(0x2e8, 0x0008, serial_read, NULL, NULL, serial_write, NULL, NULL, &serial2);
|
||||
io_removehandler(0x2f8, 0x0008, serial_read, NULL, NULL, serial_write, NULL, NULL, &serial2);
|
||||
io_removehandler(0x3e8, 0x0008, serial_read, NULL, NULL, serial_write, NULL, NULL, &serial2);
|
||||
io_removehandler(0x3f8, 0x0008, serial_read, NULL, NULL, serial_write, NULL, NULL, &serial2);
|
||||
io_removehandler(0x208, 0x0008, serial_read, NULL, NULL, serial_write, NULL, NULL, &serial2);
|
||||
io_removehandler(0x228, 0x0008, serial_read, NULL, NULL, serial_write, NULL, NULL, &serial2);
|
||||
io_removehandler(0x238, 0x0008, serial_read, NULL, NULL, serial_write, NULL, NULL, &serial2);
|
||||
io_removehandler(0x2e0, 0x0008, serial_read, NULL, NULL, serial_write, NULL, NULL, &serial2);
|
||||
io_removehandler(0x2e8, 0x0008, serial_read, NULL, NULL, serial_write, NULL, NULL, &serial2);
|
||||
io_removehandler(0x2f8, 0x0008, serial_read, NULL, NULL, serial_write, NULL, NULL, &serial2);
|
||||
io_removehandler(0x338, 0x0008, serial_read, NULL, NULL, serial_write, NULL, NULL, &serial2);
|
||||
io_removehandler(0x3e8, 0x0008, serial_read, NULL, NULL, serial_write, NULL, NULL, &serial2);
|
||||
io_removehandler(0x3f8, 0x0008, serial_read, NULL, NULL, serial_write, NULL, NULL, &serial2);
|
||||
}
|
||||
|
||||
@@ -21,11 +21,12 @@ typedef struct
|
||||
|
||||
int irq;
|
||||
|
||||
void (*rcr_callback)(void *p);
|
||||
void (*rcr_callback)(struct SERIAL *serial, void *p);
|
||||
void *rcr_callback_p;
|
||||
uint8_t fifo[256];
|
||||
int fifo_read, fifo_write;
|
||||
|
||||
int64_t recieve_delay;
|
||||
int recieve_delay;
|
||||
} SERIAL;
|
||||
|
||||
extern SERIAL serial1, serial2;
|
||||
|
||||
80
src/sio.c
80
src/sio.c
@@ -37,6 +37,38 @@ void sio_write(int func, int addr, uint8_t val, void *priv)
|
||||
return;
|
||||
}
|
||||
card_sio[addr] = val;
|
||||
if (addr == 0x40)
|
||||
{
|
||||
if (!((val ^ card_sio[addr]) & 0x40))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (val & 0x40)
|
||||
{
|
||||
dma_alias_remove();
|
||||
}
|
||||
else
|
||||
{
|
||||
dma_alias_set();
|
||||
}
|
||||
}
|
||||
else if (addr == 0x4f)
|
||||
{
|
||||
if (!((val ^ card_sio[addr]) & 0x40))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (val & 0x40)
|
||||
{
|
||||
port_92_add();
|
||||
}
|
||||
else
|
||||
{
|
||||
port_92_remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -50,10 +82,10 @@ uint8_t sio_read(int func, int addr, void *priv)
|
||||
return card_sio[addr];
|
||||
}
|
||||
|
||||
void sio_init(int card)
|
||||
static int reset_reg = 0;
|
||||
|
||||
void sio_reset()
|
||||
{
|
||||
pci_add_specific(card, sio_read, sio_write, NULL);
|
||||
|
||||
memset(card_sio, 0, 256);
|
||||
card_sio[0x00] = 0x86; card_sio[0x01] = 0x80; /*Intel*/
|
||||
card_sio[0x02] = 0x84; card_sio[0x03] = 0x04; /*82378ZB (SIO)*/
|
||||
@@ -76,3 +108,45 @@ void sio_init(int card)
|
||||
card_sio[0xA0] = 0x08;
|
||||
card_sio[0xA8] = 0x0F;
|
||||
}
|
||||
|
||||
static uint8_t rc_read(uint16_t port, void *priv)
|
||||
{
|
||||
return reset_reg & 0xfb;
|
||||
}
|
||||
|
||||
static void rc_write(uint16_t port, uint8_t val, void *priv)
|
||||
{
|
||||
if (!(reset_reg & 4) && (val & 4))
|
||||
{
|
||||
if (reset_reg & 2)
|
||||
{
|
||||
// pclog("SIO: Hard reset\n");
|
||||
resetpchard();
|
||||
}
|
||||
else
|
||||
{
|
||||
// pclog("SIO: Soft reset\n");
|
||||
sio_reset();
|
||||
resetide();
|
||||
softresetx86();
|
||||
}
|
||||
}
|
||||
reset_reg = val;
|
||||
}
|
||||
|
||||
void sio_init(int card)
|
||||
{
|
||||
pci_add_specific(card, sio_read, sio_write, NULL);
|
||||
|
||||
sio_reset();
|
||||
|
||||
reset_reg = 0;
|
||||
|
||||
io_sethandler(0x0cf9, 0x0001, rc_read, NULL, NULL, rc_write, NULL, NULL, NULL);
|
||||
|
||||
port_92_reset();
|
||||
|
||||
port_92_add();
|
||||
|
||||
dma_alias_set();
|
||||
}
|
||||
|
||||
@@ -14,7 +14,6 @@
|
||||
#include "fdd.h"
|
||||
#include "io.h"
|
||||
#include "lpt.h"
|
||||
#include "mouse_serial.h"
|
||||
#include "serial.h"
|
||||
#include "sis85c471.h"
|
||||
|
||||
@@ -63,7 +62,6 @@ process_value:
|
||||
{
|
||||
serial1_init(0x3f8, 4);
|
||||
serial2_init(0x2f8, 3);
|
||||
mouse_serial_init();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -2,8 +2,6 @@
|
||||
|
||||
void sound_add_handler(void (*get_buffer)(int32_t *buffer, int len, void *p), void *p);
|
||||
|
||||
extern int sbtype;
|
||||
|
||||
extern int sound_card_current;
|
||||
|
||||
int sound_card_available(int card);
|
||||
|
||||
@@ -45,7 +45,6 @@ COM2 :
|
||||
#include "fdc.h"
|
||||
#include "io.h"
|
||||
#include "lpt.h"
|
||||
#include "mouse_serial.h"
|
||||
#include "serial.h"
|
||||
#include "um8669f.h"
|
||||
|
||||
@@ -107,8 +106,6 @@ void um8669f_write(uint16_t port, uint8_t val, void *priv)
|
||||
}
|
||||
}
|
||||
|
||||
mouse_serial_init();
|
||||
|
||||
lpt1_remove();
|
||||
lpt2_remove();
|
||||
temp = (um8669f_regs[0xc3] >> 4) & 3;
|
||||
|
||||
@@ -53,7 +53,7 @@ void cga_out(uint16_t addr, uint8_t val, void *p)
|
||||
if (((cga->cgamode ^ val) & 5) != 0)
|
||||
{
|
||||
cga->cgamode = val;
|
||||
update_cga16_color(cga);
|
||||
update_cga16_color(cga->cgamode);
|
||||
}
|
||||
cga->cgamode = val;
|
||||
return;
|
||||
@@ -303,7 +303,7 @@ void cga_poll(void *p)
|
||||
for (c = 0; c < x; c++)
|
||||
buffer32->line[cga->displine][c] = buffer->line[cga->displine][c] & 0xf;
|
||||
|
||||
Composite_Process(cga, 0, x >> 2, buffer32->line[cga->displine]);
|
||||
Composite_Process(cga->cgamode, 0, x >> 2, buffer32->line[cga->displine]);
|
||||
}
|
||||
|
||||
cga->sc = oldsc;
|
||||
@@ -455,7 +455,7 @@ void *cga_standalone_init()
|
||||
|
||||
cga->vram = malloc(0x4000);
|
||||
|
||||
cga_comp_init(cga);
|
||||
cga_comp_init(cga->revision);
|
||||
timer_add(cga_poll, &cga->vidtime, TIMER_ALWAYS_ENABLED, cga);
|
||||
mem_mapping_add(&cga->mapping, 0xb8000, 0x08000, cga_read, NULL, NULL, cga_write, NULL, NULL, NULL, 0, cga);
|
||||
io_sethandler(0x03d0, 0x0010, cga_in, NULL, NULL, cga_out, NULL, NULL, cga);
|
||||
|
||||
@@ -984,7 +984,6 @@ void *ega_standalone_init()
|
||||
|
||||
mem_mapping_add(&ega->mapping, 0xa0000, 0x20000, ega_read, NULL, NULL, ega_write, NULL, NULL, NULL, 0, ega);
|
||||
timer_add(ega_poll, &ega->vidtime, TIMER_ALWAYS_ENABLED, ega);
|
||||
vramp = ega->vram;
|
||||
io_sethandler(0x03c0, 0x0020, ega_in, NULL, NULL, ega_out, NULL, NULL, ega);
|
||||
return ega;
|
||||
}
|
||||
@@ -1025,7 +1024,6 @@ void *cpqega_standalone_init()
|
||||
|
||||
mem_mapping_add(&ega->mapping, 0xa0000, 0x20000, ega_read, NULL, NULL, ega_write, NULL, NULL, NULL, 0, ega);
|
||||
timer_add(ega_poll, &ega->vidtime, TIMER_ALWAYS_ENABLED, ega);
|
||||
vramp = ega->vram;
|
||||
// io_sethandler(0x03a0, 0x0040, ega_in, NULL, NULL, ega_out, NULL, NULL, ega);
|
||||
io_sethandler(0x03c0, 0x0020, ega_in, NULL, NULL, ega_out, NULL, NULL, ega);
|
||||
return ega;
|
||||
@@ -1067,7 +1065,6 @@ void *sega_standalone_init()
|
||||
|
||||
mem_mapping_add(&ega->mapping, 0xa0000, 0x20000, ega_read, NULL, NULL, ega_write, NULL, NULL, NULL, 0, ega);
|
||||
timer_add(ega_poll, &ega->vidtime, TIMER_ALWAYS_ENABLED, ega);
|
||||
vramp = ega->vram;
|
||||
// io_sethandler(0x03a0, 0x0040, ega_in, NULL, NULL, ega_out, NULL, NULL, ega);
|
||||
io_sethandler(0x03c0, 0x0020, ega_in, NULL, NULL, ega_out, NULL, NULL, ega);
|
||||
return ega;
|
||||
|
||||
@@ -1119,11 +1119,11 @@ uint8_t et4000w32p_pci_read(int func, int addr, void *p)
|
||||
case 0x09: return 0; /*Programming interface*/
|
||||
|
||||
case 0x0a: return 0x00; /*Supports VGA interface, XGA compatible*/
|
||||
case 0x0b: return 0x03;
|
||||
case 0x0b: return is_pentium ? 0x03 : 0x00; /* This has to be done in order to make this card work with the two 486 PCI machines. */
|
||||
|
||||
case 0x10: return 0x00; /*Linear frame buffer address*/
|
||||
case 0x11: return 0x00;
|
||||
case 0x12: return (et4000->linearbase >> 16) & 0xff;
|
||||
case 0x12: return 0x00;
|
||||
case 0x13: return (et4000->linearbase >> 24);
|
||||
|
||||
case 0x30: return et4000->pci_regs[0x30] & 0x01; /*BIOS ROM address*/
|
||||
@@ -1157,9 +1157,10 @@ void et4000w32p_pci_write(int func, int addr, uint8_t val, void *p)
|
||||
break;
|
||||
|
||||
case 0x13:
|
||||
et4000->linearbase &= 0xffff0000;
|
||||
et4000->linearbase = (et4000->pci_regs[0x12] << 16) | (et4000->pci_regs[0x13] << 24);
|
||||
svga->crtc[0x30] = ((et4000->linearbase & 0x3fc00000) >> 22);
|
||||
et4000->linearbase &= 0x00c00000;
|
||||
et4000->linearbase = (et4000->pci_regs[0x13] << 24);
|
||||
svga->crtc[0x30] &= 3;
|
||||
svga->crtc[0x30] = ((et4000->linearbase & 0x3f000000) >> 22);
|
||||
et4000w32p_recalcmapping(et4000);
|
||||
break;
|
||||
|
||||
|
||||
@@ -106,7 +106,12 @@ typedef struct riva128_t
|
||||
|
||||
struct
|
||||
{
|
||||
uint32_t time;
|
||||
uint32_t intr, intr_en;
|
||||
|
||||
uint64_t time;
|
||||
uint32_t alarm;
|
||||
|
||||
uint16_t clock_mul, clock_div;
|
||||
} ptimer;
|
||||
|
||||
struct
|
||||
@@ -177,7 +182,8 @@ typedef struct riva128_t
|
||||
uint8_t addr; //actually 7 bits
|
||||
} i2c;
|
||||
|
||||
int coretime;
|
||||
int mtime, mfreq;
|
||||
int nvtime, nvfreq;
|
||||
|
||||
} riva128_t;
|
||||
|
||||
@@ -302,6 +308,13 @@ static uint8_t riva128_pmc_read(uint32_t addr, void *p)
|
||||
case 0x000002: ret = 0x00; break;
|
||||
case 0x000003: ret = 0x00; break;
|
||||
}
|
||||
else if(riva128->card_id == 0x05) switch(addr)
|
||||
{
|
||||
case 0x000000: ret = 0x00; break;
|
||||
case 0x000001: ret = 0x40; break;
|
||||
case 0x000002: ret = 0x10; break;
|
||||
case 0x000003: ret = 0x00; break;
|
||||
}
|
||||
switch(addr)
|
||||
{
|
||||
case 0x000100: ret = riva128->pmc.intr & 0xff; break;
|
||||
@@ -537,18 +550,80 @@ static uint8_t riva128_ptimer_read(uint32_t addr, void *p)
|
||||
|
||||
switch(addr)
|
||||
{
|
||||
case 0x009100: ret = riva128->ptimer.intr & 0xff; break;
|
||||
case 0x009101: ret = (riva128->ptimer.intr >> 8) & 0xff; break;
|
||||
case 0x009102: ret = (riva128->ptimer.intr >> 16) & 0xff; break;
|
||||
case 0x009103: ret = (riva128->ptimer.intr >> 24) & 0xff; break;
|
||||
case 0x009140: ret = riva128->ptimer.intr & 0xff; break;
|
||||
case 0x009141: ret = (riva128->ptimer.intr_en >> 8) & 0xff; break;
|
||||
case 0x009142: ret = (riva128->ptimer.intr_en >> 16) & 0xff; break;
|
||||
case 0x009143: ret = (riva128->ptimer.intr_en >> 24) & 0xff; break;
|
||||
case 0x009200: ret = riva128->ptimer.clock_div & 0xff; break;
|
||||
case 0x009201: ret = (riva128->ptimer.clock_div >> 8) & 0xff; break;
|
||||
case 0x009202: ret = (riva128->ptimer.clock_div >> 16) & 0xff; break;
|
||||
case 0x009203: ret = (riva128->ptimer.clock_div >> 24) & 0xff; break;
|
||||
case 0x009210: ret = riva128->ptimer.clock_mul & 0xff; break;
|
||||
case 0x009211: ret = (riva128->ptimer.clock_mul >> 8) & 0xff; break;
|
||||
case 0x009212: ret = (riva128->ptimer.clock_mul >> 16) & 0xff; break;
|
||||
case 0x009213: ret = (riva128->ptimer.clock_mul >> 24) & 0xff; break;
|
||||
case 0x009400: ret = riva128->ptimer.time & 0xff; break;
|
||||
case 0x009401: ret = (riva128->ptimer.time >> 8) & 0xff; break;
|
||||
case 0x009402: ret = (riva128->ptimer.time >> 16) & 0xff; break;
|
||||
case 0x009403: ret = (riva128->ptimer.time >> 24) & 0xff; break;
|
||||
case 0x009410: ret = (riva128->ptimer.time >> 32) & 0xff; break;
|
||||
case 0x009411: ret = (riva128->ptimer.time >> 40) & 0xff; break;
|
||||
case 0x009412: ret = (riva128->ptimer.time >> 48) & 0xff; break;
|
||||
case 0x009413: ret = (riva128->ptimer.time >> 56) & 0xff; break;
|
||||
case 0x009420: ret = riva128->ptimer.alarm & 0xff; break;
|
||||
case 0x009421: ret = (riva128->ptimer.alarm >> 8) & 0xff; break;
|
||||
case 0x009422: ret = (riva128->ptimer.alarm >> 16) & 0xff; break;
|
||||
case 0x009423: ret = (riva128->ptimer.alarm >> 24) & 0xff; break;
|
||||
}
|
||||
|
||||
//TODO: gross hack to make NT4 happy for the time being.
|
||||
riva128->ptimer.time += 0x10000;
|
||||
|
||||
//TODO: NECESSARY SPEED HACK. DO NOT REMOVE THIS.
|
||||
riva128->ptimer.time += 0x10000;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void riva128_ptimer_write(uint32_t addr, uint32_t val, void *p)
|
||||
{
|
||||
riva128_t *riva128 = (riva128_t *)p;
|
||||
svga_t *svga = &riva128->svga;
|
||||
pclog("RIVA 128 PTIMER write %08X %08X %04X:%08X\n", addr, val, CS, cpu_state.pc);
|
||||
|
||||
switch(addr)
|
||||
{
|
||||
case 0x009100:
|
||||
riva128->ptimer.intr &= ~val;
|
||||
break;
|
||||
case 0x009140:
|
||||
riva128->ptimer.intr_en = val;
|
||||
break;
|
||||
case 0x009200:
|
||||
if(!(val & 0xffff)) val = 1;
|
||||
riva128->ptimer.clock_div = val & 0xffff;
|
||||
break;
|
||||
case 0x009210:
|
||||
if((val & 0xffff) > riva128->ptimer.clock_div) val = riva128->ptimer.clock_div;
|
||||
riva128->ptimer.clock_mul = val & 0xffff;
|
||||
break;
|
||||
case 0x009420:
|
||||
riva128->ptimer.alarm = val & 0xffffffe0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void riva128_ptimer_interrupt(int num, void *p)
|
||||
{
|
||||
riva128_t *riva128 = (riva128_t *)p;
|
||||
svga_t *svga = &riva128->svga;
|
||||
|
||||
riva128->ptimer.intr &= ~(1 << num);
|
||||
|
||||
riva128_pmc_interrupt(20, riva128);
|
||||
}
|
||||
|
||||
static uint8_t riva128_pfb_read(uint32_t addr, void *p)
|
||||
{
|
||||
riva128_t *riva128 = (riva128_t *)p;
|
||||
@@ -574,7 +649,7 @@ static uint8_t riva128_pfb_read(uint32_t addr, void *p)
|
||||
ret |= 0x04;
|
||||
break;
|
||||
}
|
||||
case 0x04:
|
||||
case 0x04: case 0x05:
|
||||
{
|
||||
switch(riva128->memory_size)
|
||||
{
|
||||
@@ -909,12 +984,14 @@ static void riva128_pramdac_write(uint32_t addr, uint32_t val, void *p)
|
||||
riva128->pramdac.nv_m = val & 0xff;
|
||||
riva128->pramdac.nv_n = (val >> 8) & 0xff;
|
||||
riva128->pramdac.nv_p = (val >> 16) & 7;
|
||||
svga_recalctimings(svga);
|
||||
break;
|
||||
case 0x680504:
|
||||
riva128->pramdac.mpll = val;
|
||||
riva128->pramdac.m_m = val & 0xff;
|
||||
riva128->pramdac.m_n = (val >> 8) & 0xff;
|
||||
riva128->pramdac.m_p = (val >> 16) & 7;
|
||||
svga_recalctimings(svga);
|
||||
break;
|
||||
case 0x680508:
|
||||
riva128->pramdac.vpll = val;
|
||||
@@ -1185,10 +1262,39 @@ static void riva128_mmio_write_l(uint32_t addr, uint32_t val, void *p)
|
||||
}
|
||||
}
|
||||
|
||||
static void riva128_poll(void *p)
|
||||
static void riva128_ptimer_tick(void *p)
|
||||
{
|
||||
riva128_t *riva128 = (riva128_t *)p;
|
||||
svga_t *svga = &riva128->svga;
|
||||
|
||||
uint64_t time = riva128->ptimer.clock_mul - riva128->ptimer.clock_div;
|
||||
|
||||
time *= 1000;
|
||||
|
||||
uint64_t tmp = riva128->ptimer.time;
|
||||
riva128->ptimer.time += time << 5;
|
||||
|
||||
if((tmp < riva128->ptimer.alarm) && (riva128->ptimer.time >= riva128->ptimer.alarm)) riva128_ptimer_interrupt(0, riva128);
|
||||
}
|
||||
|
||||
static void riva128_mclk_poll(void *p)
|
||||
{
|
||||
riva128_t *riva128 = (riva128_t *)p;
|
||||
svga_t *svga = &riva128->svga;
|
||||
|
||||
if(riva128->card_id == 0x03) riva128_ptimer_tick(riva128);
|
||||
|
||||
riva128->mtime += cpuclock / riva128->mfreq;
|
||||
}
|
||||
|
||||
static void riva128_nvclk_poll(void *p)
|
||||
{
|
||||
riva128_t *riva128 = (riva128_t *)p;
|
||||
svga_t *svga = &riva128->svga;
|
||||
|
||||
if(riva128->card_id > 0x40 && riva128->card_id != 0x03) riva128_ptimer_tick(riva128);
|
||||
|
||||
riva128->nvtime += cpuclock / riva128->nvfreq;
|
||||
}
|
||||
|
||||
static uint8_t riva128_rma_in(uint16_t addr, void *p)
|
||||
@@ -1779,22 +1885,43 @@ static void riva128_recalctimings(svga_t *svga)
|
||||
}
|
||||
else svga_set_ramdac_type(svga, RAMDAC_6BIT);*/
|
||||
|
||||
double freq;
|
||||
|
||||
if (((svga->miscout >> 2) & 2) == 2)
|
||||
{
|
||||
double freq = 0;
|
||||
|
||||
//if(riva128->pextdev.boot0 & 0x40) freq = 14318180.0;
|
||||
freq = 13500000.0;
|
||||
freq = 13500000.0;
|
||||
|
||||
if(riva128->pramdac.v_m == 0) freq = 0;
|
||||
if(riva128->pramdac.v_m == 0) freq = 0;
|
||||
else
|
||||
{
|
||||
freq = (freq * riva128->pramdac.v_n) / (1 << riva128->pramdac.v_p) / riva128->pramdac.v_m;
|
||||
//pclog("RIVA 128 Pixel clock is %f Hz\n", freq);
|
||||
}
|
||||
|
||||
svga->clock = cpuclock / freq;
|
||||
}
|
||||
|
||||
freq = 13500.0;
|
||||
|
||||
if(riva128->pramdac.nv_m == 0) freq = 0;
|
||||
else
|
||||
{
|
||||
freq = (freq * riva128->pramdac.v_n) / (1 << riva128->pramdac.v_p) / riva128->pramdac.v_m;
|
||||
//pclog("RIVA 128 Pixel clock is %f Hz\n", freq);
|
||||
freq = (freq * riva128->pramdac.nv_n) / (1 << riva128->pramdac.nv_p) / riva128->pramdac.nv_m;
|
||||
//pclog("RIVA 128 Core clock is %f Hz\n", freq);
|
||||
}
|
||||
|
||||
svga->clock = cpuclock / freq;
|
||||
}
|
||||
|
||||
riva128->mfreq = freq;
|
||||
|
||||
freq = 13500.0;
|
||||
|
||||
if(riva128->pramdac.m_m == 0) freq = 0;
|
||||
else
|
||||
{
|
||||
freq = (freq * riva128->pramdac.m_n) / (1 << riva128->pramdac.m_p) / riva128->pramdac.m_m;
|
||||
//pclog("RIVA 128 Core clock is %f Hz\n", freq);
|
||||
}
|
||||
|
||||
riva128->nvfreq = freq;
|
||||
}
|
||||
|
||||
static void *riva128_init()
|
||||
@@ -1878,6 +2005,18 @@ static void *riva128_init()
|
||||
|
||||
pci_add(riva128_pci_read, riva128_pci_write, riva128);
|
||||
|
||||
//Some bullshit default values so that the emulator won't shit itself trying to boot. These'll be overwritten by the video BIOS anyway.
|
||||
riva128->pramdac.m_m = 0x03;
|
||||
riva128->pramdac.m_n = 0xc2;
|
||||
riva128->pramdac.m_p = 0x0d;
|
||||
|
||||
riva128->pramdac.nv_m = 0x03;
|
||||
riva128->pramdac.nv_n = 0xc2;
|
||||
riva128->pramdac.nv_p = 0x0d;
|
||||
|
||||
timer_add(riva128_mclk_poll, &riva128->mtime, TIMER_ALWAYS_ENABLED, riva128);
|
||||
timer_add(riva128_nvclk_poll, &riva128->nvtime, TIMER_ALWAYS_ENABLED, riva128);
|
||||
|
||||
return riva128;
|
||||
}
|
||||
|
||||
@@ -2067,6 +2206,18 @@ static void *rivatnt_init()
|
||||
|
||||
pci_add(riva128_pci_read, rivatnt_pci_write, riva128);
|
||||
|
||||
//Some bullshit default values so that the emulator won't shit itself trying to boot. These'll be overwritten by the video BIOS anyway.
|
||||
riva128->pramdac.m_m = 0x03;
|
||||
riva128->pramdac.m_n = 0xc2;
|
||||
riva128->pramdac.m_p = 0x0d;
|
||||
|
||||
riva128->pramdac.nv_m = 0x03;
|
||||
riva128->pramdac.nv_n = 0xc2;
|
||||
riva128->pramdac.nv_p = 0x0d;
|
||||
|
||||
timer_add(riva128_mclk_poll, &riva128->mtime, TIMER_ALWAYS_ENABLED, riva128);
|
||||
timer_add(riva128_nvclk_poll, &riva128->nvtime, TIMER_ALWAYS_ENABLED, riva128);
|
||||
|
||||
return riva128;
|
||||
}
|
||||
|
||||
@@ -2152,3 +2303,201 @@ device_t rivatnt_device =
|
||||
rivatnt_config
|
||||
};
|
||||
|
||||
static void *rivatnt2_init()
|
||||
{
|
||||
riva128_t *riva128 = malloc(sizeof(riva128_t));
|
||||
memset(riva128, 0, sizeof(riva128_t));
|
||||
|
||||
riva128->card_id = 0x05;
|
||||
riva128->is_nv3t = 0;
|
||||
|
||||
int model = device_get_config_int("model");
|
||||
|
||||
riva128->vendor_id = 0x10de;
|
||||
riva128->device_id = ((model > 1) ? 0x0029 : 0x0028);
|
||||
|
||||
riva128->memory_size = device_get_config_int("memory");
|
||||
|
||||
svga_init(&riva128->svga, riva128, riva128->memory_size << 20,
|
||||
riva128_recalctimings,
|
||||
riva128_in, riva128_out,
|
||||
NULL, NULL);
|
||||
|
||||
switch(model)
|
||||
{
|
||||
case 0: rom_init(&riva128->bios_rom, "roms/NV5diamond.bin", 0xc0000, 0x10000, 0xffff, 0, MEM_MAPPING_EXTERNAL); break;
|
||||
case 1: rom_init(&riva128->bios_rom, "roms/inno3d64bit.BIN", 0xc0000, 0x10000, 0xffff, 0, MEM_MAPPING_EXTERNAL); break;
|
||||
case 2: rom_init(&riva128->bios_rom, "roms/creative.BIN", 0xc0000, 0x10000, 0xffff, 0, MEM_MAPPING_EXTERNAL); break;
|
||||
}
|
||||
if (PCI)
|
||||
mem_mapping_disable(&riva128->bios_rom.mapping);
|
||||
|
||||
mem_mapping_add(&riva128->mmio_mapping, 0, 0,
|
||||
riva128_mmio_read,
|
||||
riva128_mmio_read_w,
|
||||
riva128_mmio_read_l,
|
||||
riva128_mmio_write,
|
||||
riva128_mmio_write_w,
|
||||
riva128_mmio_write_l,
|
||||
NULL,
|
||||
0,
|
||||
riva128);
|
||||
mem_mapping_add(&riva128->linear_mapping, 0, 0,
|
||||
svga_read_linear,
|
||||
svga_readw_linear,
|
||||
svga_readl_linear,
|
||||
svga_write_linear,
|
||||
svga_writew_linear,
|
||||
svga_writel_linear,
|
||||
NULL,
|
||||
0,
|
||||
&riva128->svga);
|
||||
|
||||
io_sethandler(0x03c0, 0x0020, riva128_in, NULL, NULL, riva128_out, NULL, NULL, riva128);
|
||||
|
||||
// riva128->pci_regs[4] = 3;
|
||||
riva128->pci_regs[4] = 7;
|
||||
riva128->pci_regs[5] = 0;
|
||||
riva128->pci_regs[6] = 0;
|
||||
riva128->pci_regs[7] = 2;
|
||||
|
||||
riva128->pci_regs[0x2c] = 0x02;
|
||||
riva128->pci_regs[0x2d] = 0x11;
|
||||
riva128->pci_regs[0x2e] = 0x16;
|
||||
riva128->pci_regs[0x2f] = 0x10;
|
||||
|
||||
riva128->pci_regs[0x30] = 0x00;
|
||||
riva128->pci_regs[0x32] = 0x0c;
|
||||
riva128->pci_regs[0x33] = 0x00;
|
||||
|
||||
//riva128->pci_regs[0x3c] = 3;
|
||||
|
||||
riva128->pmc.intr = 0;
|
||||
riva128->pbus.intr = 0;
|
||||
riva128->pfifo.intr = 0;
|
||||
riva128->pgraph.intr = 0;
|
||||
|
||||
pci_add(riva128_pci_read, rivatnt_pci_write, riva128);
|
||||
|
||||
//Some bullshit default values so that the emulator won't shit itself trying to boot. These'll be overwritten by the video BIOS anyway.
|
||||
riva128->pramdac.m_m = 0x03;
|
||||
riva128->pramdac.m_n = 0xc2;
|
||||
riva128->pramdac.m_p = 0x0d;
|
||||
|
||||
riva128->pramdac.nv_m = 0x03;
|
||||
riva128->pramdac.nv_n = 0xc2;
|
||||
riva128->pramdac.nv_p = 0x0d;
|
||||
|
||||
//timer_add(riva128_mclk_poll, &riva128->mtime, TIMER_ALWAYS_ENABLED, riva128);
|
||||
//timer_add(riva128_nvclk_poll, &riva128->nvtime, TIMER_ALWAYS_ENABLED, riva128);
|
||||
|
||||
return riva128;
|
||||
}
|
||||
|
||||
static void rivatnt2_close(void *p)
|
||||
{
|
||||
riva128_t *riva128 = (riva128_t *)p;
|
||||
FILE *f = fopen("vram.dmp", "wb");
|
||||
fwrite(riva128->svga.vram, 4 << 20, 1, f);
|
||||
fclose(f);
|
||||
|
||||
svga_close(&riva128->svga);
|
||||
|
||||
free(riva128);
|
||||
}
|
||||
|
||||
static int rivatnt2_available()
|
||||
{
|
||||
return rom_present("roms/NV5diamond.bin") || rom_present("roms/inno3d64bit.BIN") || rom_present("roms/creative.BIN");
|
||||
}
|
||||
|
||||
static void rivatnt2_speed_changed(void *p)
|
||||
{
|
||||
riva128_t *riva128 = (riva128_t *)p;
|
||||
|
||||
svga_recalctimings(&riva128->svga);
|
||||
}
|
||||
|
||||
static void rivatnt2_force_redraw(void *p)
|
||||
{
|
||||
riva128_t *riva128 = (riva128_t *)p;
|
||||
|
||||
riva128->svga.fullchange = changeframecount;
|
||||
}
|
||||
|
||||
static void rivatnt2_add_status_info(char *s, int max_len, void *p)
|
||||
{
|
||||
riva128_t *riva128 = (riva128_t *)p;
|
||||
|
||||
svga_add_status_info(s, max_len, &riva128->svga);
|
||||
}
|
||||
|
||||
static device_config_t rivatnt2_config[] =
|
||||
{
|
||||
{
|
||||
.name = "model",
|
||||
.description = "Card model",
|
||||
.type = CONFIG_SELECTION,
|
||||
.selection =
|
||||
{
|
||||
{
|
||||
.description = "Vanilla TNT2",
|
||||
.value = 0,
|
||||
},
|
||||
{
|
||||
.description = "TNT2 Pro",
|
||||
.value = 1,
|
||||
},
|
||||
{
|
||||
.description = "TNT2 Ultra",
|
||||
.value = 2,
|
||||
},
|
||||
},
|
||||
.default_int = 0
|
||||
},
|
||||
{
|
||||
.name = "memory",
|
||||
.description = "Memory size",
|
||||
.type = CONFIG_SELECTION,
|
||||
.selection =
|
||||
{
|
||||
{
|
||||
.description = "4 MB",
|
||||
.value = 4
|
||||
},
|
||||
{
|
||||
.description = "8 MB",
|
||||
.value = 8
|
||||
},
|
||||
{
|
||||
.description = "16 MB",
|
||||
.value = 16
|
||||
},
|
||||
{
|
||||
.description = "32 MB",
|
||||
.value = 32
|
||||
},
|
||||
{
|
||||
.description = ""
|
||||
}
|
||||
},
|
||||
.default_int = 32
|
||||
},
|
||||
{
|
||||
.type = -1
|
||||
}
|
||||
};
|
||||
|
||||
device_t rivatnt2_device =
|
||||
{
|
||||
"nVidia RIVA TNT2",
|
||||
0,
|
||||
rivatnt2_init,
|
||||
rivatnt2_close,
|
||||
rivatnt2_available,
|
||||
rivatnt2_speed_changed,
|
||||
rivatnt2_force_redraw,
|
||||
rivatnt2_add_status_info,
|
||||
rivatnt2_config
|
||||
};
|
||||
|
||||
|
||||
@@ -1,2 +1,3 @@
|
||||
extern device_t riva128_device;
|
||||
extern device_t rivatnt_device;
|
||||
extern device_t rivatnt2_device;
|
||||
|
||||
@@ -240,8 +240,6 @@ void paradise_recalctimings(svga_t *svga)
|
||||
svga->render = svga_render_8bpp_highres;
|
||||
}
|
||||
|
||||
#define egacycles 1
|
||||
#define egacycles2 1
|
||||
void paradise_write(uint32_t addr, uint8_t val, void *p)
|
||||
{
|
||||
paradise_t *paradise = (paradise_t *)p;
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user