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:
OBattler
2016-12-23 03:16:24 +01:00
parent 724c5699ca
commit dc46480aa4
142 changed files with 8778 additions and 3331 deletions

BIN
nvr/ami386dx_opti495.nvr Normal file

Binary file not shown.

BIN
nvr/mr386dx_opti495.nvr Normal file

Binary file not shown.

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

File diff suppressed because it is too large Load Diff

View File

@@ -1 +1 @@
extern void AdaptecInit(uint8_t Id);
extern void AdaptecInit();

View File

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

View File

@@ -1,5 +1,3 @@
/* Copyright holders: Sarah Walker
see COPYING for more details
*/
void amstrad_init();
extern mouse_t mouse_amstrad;

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

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

View File

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

View File

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

View File

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

569
src/fdc.c

File diff suppressed because it is too large Load Diff

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -1,4 +0,0 @@
/* Copyright holders: SA1988
see COPYING for more details
*/
void mouse_amstrad_init();

View File

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

View File

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

View File

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

View File

@@ -1,4 +1 @@
/* Copyright holders: Sarah Walker
see COPYING for more details
*/
void mouse_serial_init();
extern mouse_t mouse_serial_microsoft;

View File

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

View File

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

@@ -0,0 +1 @@
void opti495_init();

View File

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

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -3,7 +3,7 @@
typedef struct SGSEG
{
uint8_t Address[128*512];
uint8_t Address[512];
uint32_t Length;
} SGSEG;

View File

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

View File

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

File diff suppressed because it is too large Load Diff

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -1,2 +1,3 @@
extern device_t riva128_device;
extern device_t rivatnt_device;
extern device_t rivatnt2_device;

View File

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