Assorted Debugger fixes

This commit is contained in:
Jeff Parsons 2015-07-20 13:11:46 -07:00
commit c2187e1e1b
28 changed files with 2360 additions and 2212 deletions

View file

@ -10,9 +10,9 @@
<rom id="romBIOS" addr="0xf8000" size="0x8000" alias="[0xf0000,0xffff0000,0xffff8000]" file="/devices/pc/bios/compaq/deskpro386/1988-01-28/1988-01-28.json"/>
<video ref="/devices/pc/video/ibm/vga/ibm-vga-autolockfs.xml"/>
<keyboard ref="/devices/pc/keyboard/keyboard-minimal-functions.xml"/>
<fdc ref="/disks/pc/library.xml" automount='{A: {name: "PC-DOS 3.30 (Disk 1)", path: "/disks/pc/dos/ibm/3.30/PCDOS330-DISK1.json"}, B: {name: "VGA Tests (Black Book)", path: "/tests/pc/vga/VGABIN.json"}}'/>
<debugger id="debugger" messages="fault|int" commands=""/>
<panel ref="/devices/pc/panel/btpanel.xml"/>
<fdc ref="/disks/pc/library.xml" automount='{A: {name: "PC-DOS 3.30 (Disk 1)", path: "/disks/pc/dos/ibm/3.30/PCDOS330-DISK1.json"}, B: {name: "VGA Tests (Black Book)", path: "/tests/pc/vga/VGABIN.json"}}'/>
<hdc id="hdcAT" type="at" drives='[{name:"20Mb Hard Disk",type:2,path:"/disks/pc/games/id/wolf3d/harddisk.json"}]'/>
<chipset id="chipset" model="deskpro386" floppies="[1200,1200]" monitor="vga"/>
<serial id="com1" adapter="1"/>

View file

@ -34,6 +34,7 @@
<manifest ref="/disks/pc/windows/1.03a/manifest.xml" disk="*"/>
<manifest ref="/disks/pc/windows/1.04/manifest.xml" disk="*"/>
<manifest ref="/disks/pc/windows/2.03/manifest.xml" disk="*"/>
<manifest ref="/disks/pc/windows/3.00/manifest.xml" disk="*"/>
<manifest ref="/disks/pc/windows/win95/build499/manifest.xml" disk="*"/>
<manifest ref="/disks/pc/minix/1.1/manifest.xml" disk="*"/>
<manifest ref="/disks/pc/unix/ibm/pcix/manifest.xml" disk="*"/>

View file

@ -3,13 +3,13 @@ Windows 1.03a Installation Disks
[Manifest](manifest.xml) updated using:
diskdump --disk=private/WIN103A-DISK1-SETUP.img --format=json --output=WIN103A-DISK1-SETUP.json --manifest
diskdump --disk=private/WIN103A-DISK2-BUILD.img --format=json --output=WIN103A-DISK2-BUILD.json --manifest
diskdump --disk=private/WIN103A-DISK3-UTILITY.img --format=json --output=WIN103A-DISK3-UTILITY.json --manifest
diskdump --disk=private/WIN103A-DISK4-FONTS.img --format=json --output=WIN103A-DISK4-FONTS.json --manifest
diskdump --disk=private/WIN103A-DISK5-APPS.img --format=json --output=WIN103A-DISK5-APPS.json --manifest
diskdump --disk=private/WIN103A-DISK6-PROGRAM.img --format=json --output=WIN103A-DISK6-PROGRAM.json --manifest
diskdump --disk=private/WIN103A-DISK7-SYMBOLSA.img --format=json --output=WIN103A-DISK7-SYMBOLSA.json --manifest
diskdump --disk=private/WIN103A-DISK8-SYMBOLSB.img --format=json --output=WIN103A-DISK8-SYMBOLSB.json --manifest
diskdump --disk=static/WIN103A-DISK1-SETUP.img --format=json --output=WIN103A-DISK1-SETUP.json --manifest
diskdump --disk=static/WIN103A-DISK2-BUILD.img --format=json --output=WIN103A-DISK2-BUILD.json --manifest
diskdump --disk=static/WIN103A-DISK3-UTILITY.img --format=json --output=WIN103A-DISK3-UTILITY.json --manifest
diskdump --disk=static/WIN103A-DISK4-FONTS.img --format=json --output=WIN103A-DISK4-FONTS.json --manifest
diskdump --disk=static/WIN103A-DISK5-APPS.img --format=json --output=WIN103A-DISK5-APPS.json --manifest
diskdump --disk=static/WIN103A-DISK6-PROGRAM.img --format=json --output=WIN103A-DISK6-PROGRAM.json --manifest
diskdump --disk=static/WIN103A-DISK7-SYMBOLSA.img --format=json --output=WIN103A-DISK7-SYMBOLSA.json --manifest
diskdump --disk=static/WIN103A-DISK8-SYMBOLSB.img --format=json --output=WIN103A-DISK8-SYMBOLSB.json --manifest
The original diskettes are not part of the repository/website.

View file

@ -3,12 +3,12 @@ Windows 1.04 Installation Disks
[Manifest](manifest.xml) updated using:
diskdump --disk=private/WIN104-DISK1-SETUP.img --format=json --output=WIN104-DISK1-SETUP.json --manifest
diskdump --disk=private/WIN104-DISK2-BUILD.img --format=json --output=WIN104-DISK2-BUILD.json --manifest
diskdump --disk=private/WIN104-DISK3-UTILITY.img --format=json --output=WIN104-DISK3-UTILITY.json --manifest
diskdump --disk=private/WIN104-DISK4-FONT.img --format=json --output=WIN104-DISK4-FONT.json --manifest
diskdump --disk=private/WIN104-DISK5-APPS.img --format=json --output=WIN104-DISK5-APPS.json --manifest
diskdump --disk=private/WIN104-DISK6-WRITE.img --format=json --output=WIN104-DISK6-WRITE.json --manifest
diskdump --disk=private/WIN104-DISK7-SUPPDRV.img --format=json --output=WIN104-DISK7-SUPPDRV.json --manifest
diskdump --disk=static/WIN104-DISK1-SETUP.img --format=json --output=WIN104-DISK1-SETUP.json --manifest
diskdump --disk=static/WIN104-DISK2-BUILD.img --format=json --output=WIN104-DISK2-BUILD.json --manifest
diskdump --disk=static/WIN104-DISK3-UTILITY.img --format=json --output=WIN104-DISK3-UTILITY.json --manifest
diskdump --disk=static/WIN104-DISK4-FONT.img --format=json --output=WIN104-DISK4-FONT.json --manifest
diskdump --disk=static/WIN104-DISK5-APPS.img --format=json --output=WIN104-DISK5-APPS.json --manifest
diskdump --disk=static/WIN104-DISK6-WRITE.img --format=json --output=WIN104-DISK6-WRITE.json --manifest
diskdump --disk=static/WIN104-DISK7-SUPPDRV.img --format=json --output=WIN104-DISK7-SUPPDRV.json --manifest
The original diskettes are not part of the repository/website.

View file

@ -3,14 +3,14 @@ Windows 2.03 Installation Disks
[Manifest](manifest.xml) updated using:
diskdump --disk=private/WIN203-DISK1-SETUP.img --format=json --output=WIN203-DISK1-SETUP.json --manifest
diskdump --disk=private/WIN203-DISK2-BUILD.img --format=json --output=WIN203-DISK2-BUILD.json --manifest
diskdump --disk=private/WIN203-DISK3-DISPLAYS.img --format=json --output=WIN203-DISK3-DISPLAYS.json --manifest
diskdump --disk=private/WIN203-DISK4-UTILS1.img --format=json --output=WIN203-DISK4-UTILS1.json --manifest
diskdump --disk=private/WIN203-DISK5-UTILS2.img --format=json --output=WIN203-DISK5-UTILS2.json --manifest
diskdump --disk=private/WIN203-DISK6-FONTS1.img --format=json --output=WIN203-DISK6-FONTS1.json --manifest
diskdump --disk=private/WIN203-DISK7-FONTS2.img --format=json --output=WIN203-DISK7-FONTS2.json --manifest
diskdump --disk=private/WIN203-DISK8-APPS.img --format=json --output=WIN203-DISK8-APPS.json --manifest
diskdump --disk=private/WIN203-DISK9-WRITE.img --format=json --output=WIN203-DISK9-WRITE.json --manifest
diskdump --disk=static/WIN203-DISK1-SETUP.img --format=json --output=WIN203-DISK1-SETUP.json --manifest
diskdump --disk=static/WIN203-DISK2-BUILD.img --format=json --output=WIN203-DISK2-BUILD.json --manifest
diskdump --disk=static/WIN203-DISK3-DISPLAYS.img --format=json --output=WIN203-DISK3-DISPLAYS.json --manifest
diskdump --disk=static/WIN203-DISK4-UTILS1.img --format=json --output=WIN203-DISK4-UTILS1.json --manifest
diskdump --disk=static/WIN203-DISK5-UTILS2.img --format=json --output=WIN203-DISK5-UTILS2.json --manifest
diskdump --disk=static/WIN203-DISK6-FONTS1.img --format=json --output=WIN203-DISK6-FONTS1.json --manifest
diskdump --disk=static/WIN203-DISK7-FONTS2.img --format=json --output=WIN203-DISK7-FONTS2.json --manifest
diskdump --disk=static/WIN203-DISK8-APPS.img --format=json --output=WIN203-DISK8-APPS.json --manifest
diskdump --disk=static/WIN203-DISK9-WRITE.img --format=json --output=WIN203-DISK9-WRITE.json --manifest
The original diskettes are not part of the repository/website.

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,41 @@
<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="/versions/pcjs/1.18.4/manifest.xsl"?>
<manifest type="software">
<title>Microsoft Windows 3.00</title>
<disk id="disk01" size="737280" chs="80:2:9" img="static/720K/WIN300-DISK1.img" href="/disks/pc/windows/3.00/720K/WIN300-DISK1.json" md5="e885338cbefa095c6b2c403d03085cba" md5json="f6efc1eb0d6abd697fe09d2de7efc0c2">
<name>Windows 3.00 (720K Disk 1)</name>
</disk>
<disk id="disk02" size="737280" chs="80:2:9" img="static/720K/WIN300-DISK2.img" href="/disks/pc/windows/3.00/720K/WIN300-DISK2.json" md5="1c6c289cc6d5ba5ccf0dd935e87f2cd8" md5json="9b7700a3cebb2437f603e46a17bb2428">
<name>Windows 3.00 (720K Disk 2)</name>
</disk>
<disk id="disk03" size="737280" chs="80:2:9" img="static/720K/WIN300-DISK3.img" href="/disks/pc/windows/3.00/720K/WIN300-DISK3.json" md5="706bf6ae705644ffb72bf1b6ce50356e" md5json="0f770d50d4c515c9f2774acf9097f13b">
<name>Windows 3.00 (720K Disk 3)</name>
</disk>
<disk id="disk04" size="737280" chs="80:2:9" img="static/720K/WIN300-DISK4.img" href="/disks/pc/windows/3.00/720K/WIN300-DISK4.json" md5="be69aa0330b7d052a0201fcb3f11a8bd" md5json="176ce2ad5a7c607ecc7a1b21be6582de">
<name>Windows 3.00 (720K Disk 4)</name>
</disk>
<disk id="disk05" size="737280" chs="80:2:9" img="static/720K/WIN300-DISK5.img" href="/disks/pc/windows/3.00/720K/WIN300-DISK5.json" md5="a8192459926dc6fdcc7b6ca74388a99f" md5json="6aa9301b0188cb74d10384f6c953a350">
<name>Windows 3.00 (720K Disk 5)</name>
</disk>
<disk id="disk06" size="737280" chs="80:2:9" img="static/720K/WIN300-DISK6.img" href="/disks/pc/windows/3.00/720K/WIN300-DISK6.json" md5="974875d1b298c631961f47267fc8e725" md5json="2a388c20cb2fe950f8a5e8b4d2c86132">
<name>Windows 3.00 (720K Disk 6)</name>
</disk>
<disk id="disk07" size="737280" chs="80:2:9" img="static/720K/WIN300-DISK7.img" href="/disks/pc/windows/3.00/720K/WIN300-DISK7.json" md5="321daf0fe6b4dc80371c7f34a995e861" md5json="668909b9c813f567e921c57eb0c71b8f">
<name>Windows 3.00 (720K Disk 7)</name>
</disk>
<disk id="disk08" size="1228800" chs="80:2:15" img="static/1200K/WIN300-DISK1.img" href="/disks/pc/windows/3.00/1200K/WIN300-DISK1.json" md5="1deff1f338043f245788de88c4a57570" md5json="ff8e9c821c66eb6d799f62f38a042b63">
<name>Windows 3.00 (1200K Disk 1)</name>
</disk>
<disk id="disk09" size="1228800" chs="80:2:15" img="static/1200K/WIN300-DISK2.img" href="/disks/pc/windows/3.00/1200K/WIN300-DISK2.json" md5="b8edd0072aebf390e9da32b4c27c77ba" md5json="7aee2e323e16879f86d7157fa8cd9640">
<name>Windows 3.00 (1200K Disk 2)</name>
</disk>
<disk id="disk10" size="1228800" chs="80:2:15" img="static/1200K/WIN300-DISK3.img" href="/disks/pc/windows/3.00/1200K/WIN300-DISK3.json" md5="e40bba28ef8fab25db114b84155ae976" md5json="f4f492dd1730cf2521bbd9e29bae282f">
<name>Windows 3.00 (1200K Disk 3)</name>
</disk>
<disk id="disk11" size="1228800" chs="80:2:15" img="static/1200K/WIN300-DISK4.img" href="/disks/pc/windows/3.00/1200K/WIN300-DISK4.json" md5="37e539fea32536dad2adfedd13127378" md5json="0e3febe3070de8171985bd6c2566f54b">
<name>Windows 3.00 (1200K Disk 4)</name>
</disk>
<disk id="disk12" size="1228800" chs="80:2:15" img="static/1200K/WIN300-DISK5.img" href="/disks/pc/windows/3.00/1200K/WIN300-DISK5.json" md5="49cb80aa1d3a8106be527957aae27b44" md5json="d72b4d610b44174f7bf422d2b8fdd63e">
<name>Windows 3.00 (1200K Disk 5)</name>
</disk>
</manifest>

View file

@ -3,6 +3,6 @@ Windows COMM Driver (Source)
[Manifest](manifest.xml) updated using:
diskdump --disk=private/WINCOMM.img --format=json --output=WINCOMM.json --manifest
diskdump --disk=static/WINCOMM.img --format=json --output=WINCOMM.json --manifest
The original diskettes are not part of the repository/website.

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -453,10 +453,10 @@ if (DEBUGGER) {
Debugger.TYPE_IMPREG = 0x0060; // implicit register in TYPE_IREG
Debugger.TYPE_IMPSEG = 0x0070; // implicit segment register in TYPE_IREG
Debugger.TYPE_MODRM = 0x0080; // (E) standard ModRM decoding
Debugger.TYPE_MEM = 0x0090; // (M) ModRM refers to memory only
Debugger.TYPE_REG = 0x00A0; // (G) standard Reg decoding
Debugger.TYPE_SEGREG = 0x00B0; // (S) Reg selects segment register
Debugger.TYPE_MODREG = 0x00C0; // (R) Mod refers to register only
Debugger.TYPE_MODMEM = 0x0090; // (M) ModRM refers to memory only
Debugger.TYPE_MODREG = 0x00A0; // (R) ModRM refers to register only
Debugger.TYPE_REG = 0x00B0; // (G) standard Reg decoding
Debugger.TYPE_SEGREG = 0x00C0; // (S) Reg selects segment register
Debugger.TYPE_CTLREG = 0x00D0; // (C) Reg selects control register
Debugger.TYPE_DBGREG = 0x00E0; // (D) Reg selects debug register
Debugger.TYPE_TSTREG = 0x00F0; // (T) Reg selects test register
@ -779,7 +779,7 @@ if (DEBUGGER) {
/* 0x8A */ [Debugger.INS.MOV, Debugger.TYPE_REG | Debugger.TYPE_BYTE | Debugger.TYPE_OUT, Debugger.TYPE_MODRM | Debugger.TYPE_BYTE | Debugger.TYPE_IN],
/* 0x8B */ [Debugger.INS.MOV, Debugger.TYPE_REG | Debugger.TYPE_VWORD | Debugger.TYPE_OUT, Debugger.TYPE_MODRM | Debugger.TYPE_VWORD | Debugger.TYPE_IN],
/* 0x8C */ [Debugger.INS.MOV, Debugger.TYPE_MODRM | Debugger.TYPE_VWORD | Debugger.TYPE_OUT, Debugger.TYPE_SEGREG | Debugger.TYPE_WORD | Debugger.TYPE_IN],
/* 0x8D */ [Debugger.INS.LEA, Debugger.TYPE_REG | Debugger.TYPE_VWORD | Debugger.TYPE_OUT, Debugger.TYPE_MEM | Debugger.TYPE_VWORD],
/* 0x8D */ [Debugger.INS.LEA, Debugger.TYPE_REG | Debugger.TYPE_VWORD | Debugger.TYPE_OUT, Debugger.TYPE_MODMEM | Debugger.TYPE_VWORD],
/* 0x8E */ [Debugger.INS.MOV, Debugger.TYPE_SEGREG | Debugger.TYPE_WORD | Debugger.TYPE_OUT, Debugger.TYPE_MODRM | Debugger.TYPE_VWORD | Debugger.TYPE_IN],
/* 0x8F */ [Debugger.INS.POP, Debugger.TYPE_MODRM | Debugger.TYPE_VWORD | Debugger.TYPE_OUT],
@ -841,8 +841,8 @@ if (DEBUGGER) {
/* 0xC1 */ [Debugger.INS.GRP2W, Debugger.TYPE_MODRM | Debugger.TYPE_VWORD | Debugger.TYPE_BOTH | Debugger.TYPE_80186, Debugger.TYPE_IMM | Debugger.TYPE_BYTE | Debugger.TYPE_IN],
/* 0xC2 */ [Debugger.INS.RET, Debugger.TYPE_IMM | Debugger.TYPE_WORD | Debugger.TYPE_IN],
/* 0xC3 */ [Debugger.INS.RET],
/* 0xC4 */ [Debugger.INS.LES, Debugger.TYPE_REG | Debugger.TYPE_VWORD | Debugger.TYPE_OUT, Debugger.TYPE_MEM | Debugger.TYPE_SEGP | Debugger.TYPE_IN],
/* 0xC5 */ [Debugger.INS.LDS, Debugger.TYPE_REG | Debugger.TYPE_VWORD | Debugger.TYPE_OUT, Debugger.TYPE_MEM | Debugger.TYPE_SEGP | Debugger.TYPE_IN],
/* 0xC4 */ [Debugger.INS.LES, Debugger.TYPE_REG | Debugger.TYPE_VWORD | Debugger.TYPE_OUT, Debugger.TYPE_MODMEM | Debugger.TYPE_SEGP | Debugger.TYPE_IN],
/* 0xC5 */ [Debugger.INS.LDS, Debugger.TYPE_REG | Debugger.TYPE_VWORD | Debugger.TYPE_OUT, Debugger.TYPE_MODMEM | Debugger.TYPE_SEGP | Debugger.TYPE_IN],
/* 0xC6 */ [Debugger.INS.MOV, Debugger.TYPE_MODRM | Debugger.TYPE_BYTE | Debugger.TYPE_OUT, Debugger.TYPE_IMM | Debugger.TYPE_BYTE | Debugger.TYPE_IN],
/* 0xC7 */ [Debugger.INS.MOV, Debugger.TYPE_MODRM | Debugger.TYPE_VWORD | Debugger.TYPE_OUT, Debugger.TYPE_IMM | Debugger.TYPE_VWORD | Debugger.TYPE_IN],
@ -913,12 +913,12 @@ if (DEBUGGER) {
Debugger.aaOp0FDescs = {
0x00: [Debugger.INS.GRP6, Debugger.TYPE_MODRM | Debugger.TYPE_WORD | Debugger.TYPE_BOTH],
0x01: [Debugger.INS.GRP7, Debugger.TYPE_MODRM | Debugger.TYPE_WORD | Debugger.TYPE_BOTH],
0x02: [Debugger.INS.LAR, Debugger.TYPE_REG | Debugger.TYPE_WORD | Debugger.TYPE_OUT | Debugger.TYPE_80286, Debugger.TYPE_MEM | Debugger.TYPE_WORD | Debugger.TYPE_IN],
0x03: [Debugger.INS.LSL, Debugger.TYPE_REG | Debugger.TYPE_WORD | Debugger.TYPE_OUT | Debugger.TYPE_80286, Debugger.TYPE_MEM | Debugger.TYPE_WORD | Debugger.TYPE_IN],
0x02: [Debugger.INS.LAR, Debugger.TYPE_REG | Debugger.TYPE_WORD | Debugger.TYPE_OUT | Debugger.TYPE_80286, Debugger.TYPE_MODMEM | Debugger.TYPE_WORD | Debugger.TYPE_IN],
0x03: [Debugger.INS.LSL, Debugger.TYPE_REG | Debugger.TYPE_WORD | Debugger.TYPE_OUT | Debugger.TYPE_80286, Debugger.TYPE_MODMEM | Debugger.TYPE_WORD | Debugger.TYPE_IN],
0x05: [Debugger.INS.LOADALL,Debugger.TYPE_80286],
0x06: [Debugger.INS.CLTS, Debugger.TYPE_80286],
0x20: [Debugger.INS.MOV, Debugger.TYPE_REG | Debugger.TYPE_DWORD | Debugger.TYPE_OUT | Debugger.TYPE_80386, Debugger.TYPE_CTLREG | Debugger.TYPE_DWORD | Debugger.TYPE_IN],
0x22: [Debugger.INS.MOV, Debugger.TYPE_CTLREG | Debugger.TYPE_DWORD | Debugger.TYPE_OUT | Debugger.TYPE_80386, Debugger.TYPE_REG | Debugger.TYPE_DWORD | Debugger.TYPE_IN],
0x20: [Debugger.INS.MOV, Debugger.TYPE_MODREG | Debugger.TYPE_DWORD | Debugger.TYPE_OUT | Debugger.TYPE_80386, Debugger.TYPE_CTLREG | Debugger.TYPE_DWORD | Debugger.TYPE_IN],
0x22: [Debugger.INS.MOV, Debugger.TYPE_CTLREG | Debugger.TYPE_DWORD | Debugger.TYPE_OUT | Debugger.TYPE_80386, Debugger.TYPE_MODREG | Debugger.TYPE_DWORD | Debugger.TYPE_IN],
0x80: [Debugger.INS.JO, Debugger.TYPE_IMMREL | Debugger.TYPE_VWORD | Debugger.TYPE_IN | Debugger.TYPE_80386],
0x81: [Debugger.INS.JNO, Debugger.TYPE_IMMREL | Debugger.TYPE_VWORD | Debugger.TYPE_IN | Debugger.TYPE_80386],
0x82: [Debugger.INS.JC, Debugger.TYPE_IMMREL | Debugger.TYPE_VWORD | Debugger.TYPE_IN | Debugger.TYPE_80386],
@ -962,10 +962,10 @@ if (DEBUGGER) {
0xAC: [Debugger.INS.SHRD, Debugger.TYPE_MODRM | Debugger.TYPE_VWORD | Debugger.TYPE_OUT | Debugger.TYPE_80386, Debugger.TYPE_REG | Debugger.TYPE_VWORD | Debugger.TYPE_IN, Debugger.TYPE_IMM | Debugger.TYPE_BYTE | Debugger.TYPE_IN],
0xAD: [Debugger.INS.SHRD, Debugger.TYPE_MODRM | Debugger.TYPE_VWORD | Debugger.TYPE_OUT | Debugger.TYPE_80386, Debugger.TYPE_REG | Debugger.TYPE_VWORD | Debugger.TYPE_IN, Debugger.TYPE_IMPREG | Debugger.TYPE_CL | Debugger.TYPE_IN],
0xAF: [Debugger.INS.IMUL, Debugger.TYPE_MODRM | Debugger.TYPE_VWORD | Debugger.TYPE_BOTH | Debugger.TYPE_80386, Debugger.TYPE_REG | Debugger.TYPE_VWORD | Debugger.TYPE_IN],
0xB2: [Debugger.INS.LSS, Debugger.TYPE_REG | Debugger.TYPE_VWORD | Debugger.TYPE_OUT, Debugger.TYPE_MEM | Debugger.TYPE_SEGP | Debugger.TYPE_IN],
0xB2: [Debugger.INS.LSS, Debugger.TYPE_REG | Debugger.TYPE_VWORD | Debugger.TYPE_OUT, Debugger.TYPE_MODMEM | Debugger.TYPE_SEGP | Debugger.TYPE_IN],
0xB3: [Debugger.INS.BTR, Debugger.TYPE_MODRM | Debugger.TYPE_VWORD | Debugger.TYPE_OUT | Debugger.TYPE_80386, Debugger.TYPE_REG | Debugger.TYPE_VWORD | Debugger.TYPE_IN],
0xB4: [Debugger.INS.LFS, Debugger.TYPE_REG | Debugger.TYPE_VWORD | Debugger.TYPE_OUT, Debugger.TYPE_MEM | Debugger.TYPE_SEGP | Debugger.TYPE_IN],
0xB5: [Debugger.INS.LGS, Debugger.TYPE_REG | Debugger.TYPE_VWORD | Debugger.TYPE_OUT, Debugger.TYPE_MEM | Debugger.TYPE_SEGP | Debugger.TYPE_IN],
0xB4: [Debugger.INS.LFS, Debugger.TYPE_REG | Debugger.TYPE_VWORD | Debugger.TYPE_OUT, Debugger.TYPE_MODMEM | Debugger.TYPE_SEGP | Debugger.TYPE_IN],
0xB5: [Debugger.INS.LGS, Debugger.TYPE_REG | Debugger.TYPE_VWORD | Debugger.TYPE_OUT, Debugger.TYPE_MODMEM | Debugger.TYPE_SEGP | Debugger.TYPE_IN],
0xB6: [Debugger.INS.MOVZX, Debugger.TYPE_REG | Debugger.TYPE_VWORD | Debugger.TYPE_OUT | Debugger.TYPE_80386, Debugger.TYPE_MODRM | Debugger.TYPE_BYTE | Debugger.TYPE_IN],
0xB7: [Debugger.INS.MOVZX, Debugger.TYPE_REG | Debugger.TYPE_DWORD | Debugger.TYPE_OUT | Debugger.TYPE_80386, Debugger.TYPE_MODRM | Debugger.TYPE_WORD | Debugger.TYPE_IN],
0xBA: [Debugger.INS.GRP8, Debugger.TYPE_MODRM | Debugger.TYPE_VWORD | Debugger.TYPE_BOTH | Debugger.TYPE_80386, Debugger.TYPE_IMM | Debugger.TYPE_BYTE | Debugger.TYPE_IN],
@ -1703,7 +1703,7 @@ if (DEBUGGER) {
Debugger.prototype.hexOffset = function(off, sel, fAddr32)
{
if (sel != null) {
return str.toHex(sel, 4) + ":" + str.toHex(off, (off & (0xffff0000|0)) || fAddr32? 8 : 4);
return str.toHex(sel, 4) + ":" + str.toHex(off, (off & ~0xffff) || fAddr32? 8 : 4);
}
return str.toHex(off);
};
@ -1899,7 +1899,7 @@ if (DEBUGGER) {
if (fGate) {
sDump = "seg=" + str.toHexWord(seg.base & 0xffff) + " off=" + str.toHexWord(seg.limit);
} else {
sDump = "base=" + str.toHex(seg.base, this.cchAddr) + " limit=" + str.toHex(seg.limit, (seg.limit & ~0xffff)? 8 : 4);
sDump = "base=" + str.toHex(seg.base, this.cchAddr) + " limit=" + this.getLimitString(seg.limit);
}
/*
* When we dump the EXT word, we mask off the LIMIT1619 and BASE2431 bits, because those have already
@ -2981,23 +2981,23 @@ if (DEBUGGER) {
};
/**
* addBreakpoint(aBreak, dbgAddr, fTempBreak)
* addBreakpoint(aBreak, dbgAddr, fTemp)
*
* @this {Debugger}
* @param {Array} aBreak
* @param {{DbgAddr}} dbgAddr
* @param {boolean} [fTempBreak]
* @param {boolean} [fTemp]
* @return {boolean} true if breakpoint added, false if already exists
*/
Debugger.prototype.addBreakpoint = function(aBreak, dbgAddr, fTempBreak)
Debugger.prototype.addBreakpoint = function(aBreak, dbgAddr, fTemp)
{
if (!this.findBreakpoint(aBreak, dbgAddr)) {
dbgAddr.fTempBreak = fTempBreak;
dbgAddr.fTempBreak = fTemp;
aBreak.push(dbgAddr);
if (aBreak != this.aBreakExec) {
this.bus.addMemBreak(this.getAddr(dbgAddr), aBreak == this.aBreakWrite);
}
if (fTempBreak) {
if (fTemp) {
/*
* Force temporary breakpoints to be interpreted as linear breakpoints
* (hence the assertion that there IS a linear address stored in dbgAddr);
@ -3008,7 +3008,7 @@ if (DEBUGGER) {
} else {
this.println("breakpoint enabled: " + this.hexAddr(dbgAddr) + " (" + aBreak[0] + ")");
}
this.historyInit();
if (!fTemp) this.historyInit();
return true;
}
return false;
@ -3304,11 +3304,29 @@ if (DEBUGGER) {
if (bModRM < 0) {
bModRM = this.getByte(dbgAddr, 1);
}
if (typeMode >= Debugger.TYPE_REG) {
sOperand = this.getRegOperand((bModRM >> 3) & 0x7, type, dbgAddr);
if (typeMode < Debugger.TYPE_MODREG) {
/*
* This test also encompasses TYPE_MODMEM, which is basically the inverse of the case
* below (ie, only Mod values *other* than 11 are allowed); however, I believe that in
* some cases that's merely a convention, and that if you try to execute an instruction
* like "LEA AX,BX", it will actually do something (on some if not all processors), so
* there's probably some diagnostic value in allowing those cases to be disassembled.
*/
sOperand = this.getModRMOperand(bModRM, type, dbgAddr);
}
else if (typeMode == Debugger.TYPE_MODREG) {
/*
* TYPE_MODREG instructions assume that Mod is 11 (only certain early 80486 steppings
* actually *required* that Mod contain 11) and always treat RM as a register (which we
* could also simulate by setting Mod to 11 and letting getModRMOperand() do its thing).
*/
sOperand = this.getRegOperand(bModRM & 0x7, type, dbgAddr);
}
else {
sOperand = this.getModRMOperand(bModRM, type, dbgAddr);
/*
* All the remaining cases are Reg-centric; getRegOperand() will figure out which case.
*/
sOperand = this.getRegOperand((bModRM >> 3) & 0x7, type, dbgAddr);
}
}
else if (typeMode == Debugger.TYPE_ONE) {
@ -3647,6 +3665,18 @@ if (DEBUGGER) {
return sFlag + (b? '1' : '0') + ' ';
};
/**
* getLimitString(l)
*
* @this {Debugger}
* @param {number} l
* @return {string}
*/
Debugger.prototype.getLimitString = function(l)
{
return str.toHex(l, (l & ~0xffff)? 8 : 4);
};
/**
* getRegString(iReg)
*
@ -3672,7 +3702,7 @@ if (DEBUGGER) {
*/
Debugger.prototype.getSegString = function(seg, fProt)
{
return seg.sName + '=' + str.toHex(seg.sel, 4) + (fProt? '[' + str.toHex(seg.base, this.cchAddr) + ',' + str.toHex(seg.limit, (seg.limit & ~0xffff)? 8 : 4) + ']' : "");
return seg.sName + '=' + str.toHex(seg.sel, 4) + (fProt? '[' + str.toHex(seg.base, this.cchAddr) + ',' + this.getLimitString(seg.limit) + ']' : "");
};
/**
@ -4950,7 +4980,7 @@ if (DEBUGGER) {
}
var fValid = false;
var w = str.parseInt(sValue, 16);
if (!isNaN(w)) {
if (w !== undefined) {
fValid = true;
var sRegMatch = sReg.toUpperCase();
if (sRegMatch.charAt(0) == 'E' && this.cchReg <= 4) {
@ -5110,12 +5140,14 @@ if (DEBUGGER) {
break;
case "CR0":
this.cpu.regCR0 = w;
X86.fnLCR0.call(this.cpu, w);
break;
case "CR2":
this.cpu.regCR2 = w;
break;
case "CR3":
this.cpu.regCR3 = w;
X86.fnLCR3.call(this.cpu, w);
break;
/*
* TODO: Add support for DR0-DR7 and TR6-TR7.

View file

@ -438,8 +438,8 @@ X86CPU.CYCLES_80286 = {
};
/*
* TODO: Except for the cycle counts at the end of this table (ie, those marked "unique to the 80386"), all these
* values were simply copied from the 80286 table and still need to be modified and verified.
* TODO: All these values were simply copied from the 80286 table and still need to be modified and verified.
* Cycle counts for 80386-only instructions are hard-coded in their respective handlers, since those counts don't vary.
*/
X86CPU.CYCLES_80386 = {
nWordCyclePenalty: 0,
@ -554,25 +554,7 @@ X86CPU.CYCLES_80386 = {
nOpCyclesTestMI: 6,
nOpCyclesXchgRR: 3,
nOpCyclesXchgRM: 5,
nOpCyclesXLAT: 5,
/*
* Cycle counts unique to the 80386
*/
nOpCyclesBitScan: 11,
nOpCyclesBitSetR: 6,
nOpCyclesBitSetM: 8,
nOpCyclesBitSetMExtra: 5, // extra cycle cost for non-immediate BTC/BTR/BTS opcodes
nOpCyclesBitTestR: 3,
nOpCyclesBitTestM: 6,
nOpCyclesBitTestMExtra: 6, // extra cycle cost for non-immediate BT opcode
nOpCyclesIMulR: 9,
nOpCyclesIMulM: 12,
nOpCyclesMovXR: 3,
nOpCyclesMovXM: 6,
nOpCyclesSetR: 4,
nOpCyclesSetM: 5,
nOpCyclesShiftDR: 3,
nOpCyclesShiftDM: 7
nOpCyclesXLAT: 5
};
/**
@ -723,6 +705,7 @@ X86CPU.prototype.enablePageBlocks = function()
}
}
this.aBlocksPaged = [];
this.stopCPU();
};
/**
@ -1351,6 +1334,25 @@ X86CPU.prototype.resetRegs = function()
this.setProtMode();
};
/**
* setAddrSize(size)
*
* This is used by opcodes that require a particular ADDRESS size, which we enforce by
* internally simulating an ADDRESS size override, if needed.
*
* @this {X86CPU}
* @param {number} size (2 for 2-byte/16-bit operands, or 4 for 4-byte/32-bit operands)
*/
X86CPU.prototype.setAddrSize = function(size)
{
if (this.addrSize != size) {
this.opPrefixes |= X86.OPFLAG.ADDRSIZE;
this.addrSize = size;
this.addrMask = (size == 2? 0xffff : (0xffffffff|0));
this.updateAddrSize();
}
};
/**
* updateAddrSize()
*

View file

@ -226,7 +226,7 @@ X86.fnBSF = function BSF(dst, src)
n++; // TODO: Determine if n should be incremented before the bailout for an accurate cycle count
}
}
this.nStepCycles -= this.cycleCounts.nOpCyclesBitScan + n * 3;
this.nStepCycles -= 11 + n * 3;
return dst;
};
@ -263,7 +263,7 @@ X86.fnBSR = function BSR(dst, src)
}
}
this.nStepCycles -= this.cycleCounts.nOpCyclesBitScan + n * 3;
this.nStepCycles -= 11 + n * 3;
return dst;
};
@ -278,7 +278,7 @@ X86.fnBSR = function BSR(dst, src)
X86.fnBT = function BT(dst, src)
{
if (dst & (1 << (src & 0x1f))) this.setCF(); else this.clearCF();
this.nStepCycles -= (this.regEA === X86.ADDR_INVALID? this.cycleCounts.nOpCyclesBitTestR : this.cycleCounts.nOpCyclesBitTestM);
this.nStepCycles -= (this.regEA === X86.ADDR_INVALID? 3 : 6);
this.opFlags |= X86.OPFLAG.NOWRITE;
return dst;
};
@ -295,7 +295,7 @@ X86.fnBTC = function BTC(dst, src)
{
var bit = 1 << (src & 0x1f);
if (dst & bit) this.setCF(); else this.clearCF();
this.nStepCycles -= (this.regEA === X86.ADDR_INVALID? this.cycleCounts.nOpCyclesBitSetR : this.cycleCounts.nOpCyclesBitSetM);
this.nStepCycles -= (this.regEA === X86.ADDR_INVALID? 6 : 8);
return dst ^ bit;
};
@ -311,7 +311,7 @@ X86.fnBTR = function BTR(dst, src)
{
var bit = 1 << (src & 0x1f);
if (dst & bit) this.setCF(); else this.clearCF();
this.nStepCycles -= (this.regEA === X86.ADDR_INVALID? this.cycleCounts.nOpCyclesBitSetR : this.cycleCounts.nOpCyclesBitSetM);
this.nStepCycles -= (this.regEA === X86.ADDR_INVALID? 6 : 8);
return dst & ~bit;
};
@ -327,7 +327,7 @@ X86.fnBTS = function BTS(dst, src)
{
var bit = 1 << (src & 0x1f);
if (dst & bit) this.setCF(); else this.clearCF();
this.nStepCycles -= (this.regEA === X86.ADDR_INVALID? this.cycleCounts.nOpCyclesBitSetR : this.cycleCounts.nOpCyclesBitSetM);
this.nStepCycles -= (this.regEA === X86.ADDR_INVALID? 6 : 8);
return dst | bit;
};
@ -1118,7 +1118,7 @@ X86.fnIMULrw = function IMULrw(dst, src)
this.clearCF(); this.clearOF();
}
result &= 0xffff;
this.nStepCycles -= (this.regEA === X86.ADDR_INVALID? this.cycleCounts.nOpCyclesIMulR : this.cycleCounts.nOpCyclesIMulM);
this.nStepCycles -= (this.regEA === X86.ADDR_INVALID? 9 : 12);
return result;
};
@ -1139,7 +1139,7 @@ X86.fnIMULrd = function IMULrd(dst, src)
this.clearCF(); this.clearOF();
}
result |= 0;
this.nStepCycles -= (this.regEA === X86.ADDR_INVALID? this.cycleCounts.nOpCyclesIMulR : this.cycleCounts.nOpCyclesIMulM);
this.nStepCycles -= (this.regEA === X86.ADDR_INVALID? 9 : 12);
return result;
};
@ -2438,7 +2438,7 @@ X86.fnSETcc = function SETcc(fnSet)
{
this.opFlags |= X86.OPFLAG.NOREAD;
this.aOpModMemByte[this.getIPByte()].call(this, fnSet);
this.nStepCycles -= (this.regEA === X86.ADDR_INVALID? this.cycleCounts.nOpCyclesSetR : this.cycleCounts.nOpCyclesSetM);
this.nStepCycles -= (this.regEA === X86.ADDR_INVALID? 4 : 5);
};
/**

View file

@ -200,29 +200,23 @@ X86.opCLTS = function CLTS()
*
* op=0x0F,0x20 (MOV reg,creg)
*
* NOTE: Since the ModRM decoders deal only with general-purpose registers, we must move
* the appropriate control register into a special variable (regXX), which our helper function
* (fnMOVxx) will use to replace the decoder's src operand.
* NOTE: Since this instruction uses only 32-bit general-purpose registers, our ModRM decoders
* are going to be more hindrance than help, so we fully decode and execute the instruction ourselves.
*
* From PCMag_Prog_TechRef, p.476: "The 80386 executes the MOV to/from control registers (CRn)
* regardless of the setting of the MOD field. The MOD field should be set to 0b11, but an early
* 80386 documentation error indicated that the MOD field value was a don't care. Early versions
* of the 80486 detect a MOD != 0b11 as an illegal opcode. This was changed in later versions to
* ignore the value of MOD. Assemblers that generate MOD != 0b11 for these instructions will fail
* on some 80486s."
* From PCMag_Prog_TechRef, p.476: "The 80386 executes the MOV to/from control registers (CRn) regardless
* of the setting of the MOD field. The MOD field should be set to 0b11, but an early 80386 documentation
* error indicated that the MOD field value was a don't care. Early versions of the 80486 detect
* a MOD != 0b11 as an illegal opcode. This was changed in later versions to ignore the value of MOD.
* Assemblers that generate MOD != 0b11 for these instructions will fail on some 80486s."
*
* And in fact, the Compaq DeskPro 386 ROM BIOS executes this instruction with MOD set to 0b00, so we have
* to ignore it.
*
* @this {X86CPU}
*/
X86.opMOVrc = function MOVrc()
{
/*
* We address the MOD field problem (see above) by coercing it to 0b11 (0xc0), regardless.
*
* TODO: One issue not clearly addressed is if, when an assembler/compiler generated a bogus MOD value,
* it also generated the additional displacement bytes, if any, that would typically accompany such a MOD
* value. I assume not.
*/
var bModRM = this.getIPByte() | 0xc0;
var bModRM = this.getIPByte();
if (this.segCS.cpl) {
/*
@ -233,35 +227,54 @@ X86.opMOVrc = function MOVrc()
return;
}
var reg = (bModRM & 0x38) >> 3;
switch(reg) {
var reg;
switch((bModRM & 0x38) >> 3) {
case 0x0:
this.regXX = this.regCR0;
break;
case 0x1:
this.regXX = this.regCR1;
reg = this.regCR0;
break;
case 0x2:
this.regXX = this.regCR2;
reg = this.regCR2;
break;
case 0x3:
this.regXX = this.regCR3;
reg = this.regCR3;
break;
default:
X86.opUndefined.call(this);
return;
}
switch(bModRM & 0x7) {
case 0x0:
this.regEAX = reg;
break;
case 0x1:
this.regECX = reg;
break;
case 0x2:
this.regEDX = reg;
break;
case 0x3:
this.regEBX = reg;
break;
case 0x4:
this.regESP = reg;
break;
case 0x5:
this.regEBP = reg;
break;
case 0x6:
this.regESI = reg;
break;
case 0x7:
this.regEDI = reg;
break;
}
this.nStepCycles -= 6;
/*
* Like other MOV operations, the destination does not need to be read, just written;
* however, it's moot, because we've already restricted this opcode to registers only.
*
* this.opFlags |= X86.OPFLAG.NOREAD;
*
* Another issue, however, is that this instruction always assumes a 32-bit OPERAND size,
* so we must call setDataSize(4) first.
* TODO: Implement BACKTRACK for this instruction....
*/
this.setDataSize(4);
this.aOpModRegWord[bModRM].call(this, X86.fnMOVxx);
};
/**
@ -269,30 +282,23 @@ X86.opMOVrc = function MOVrc()
*
* op=0x0F,0x22 (MOV creg,reg)
*
* NOTE: Since the ModRM decoders deal only with general-purpose registers, we have to make a note
* of which general-purpose register will be overwritten, so that we can restore it after moving the
* modified value to the correct control register.
* NOTE: Since this instruction uses only 32-bit general-purpose registers, our ModRM decoders
* are going to be more hindrance than help, so we fully decode and execute the instruction ourselves.
*
* From PCMag_Prog_TechRef, p.476: "The 80386 executes the MOV to/from control registers (CRn)
* regardless of the setting of the MOD field. The MOD field should be set to 0b11, but an early
* 80386 documentation error indicated that the MOD field value was a don't care. Early versions
* of the 80486 detect a MOD != 0b11 as an illegal opcode. This was changed in later versions to
* ignore the value of MOD. Assemblers that generate MOD != 0b11 for these instructions will fail
* on some 80486s."
* From PCMag_Prog_TechRef, p.476: "The 80386 executes the MOV to/from control registers (CRn) regardless
* of the setting of the MOD field. The MOD field should be set to 0b11, but an early 80386 documentation
* error indicated that the MOD field value was a don't care. Early versions of the 80486 detect
* a MOD != 0b11 as an illegal opcode. This was changed in later versions to ignore the value of MOD.
* Assemblers that generate MOD != 0b11 for these instructions will fail on some 80486s."
*
* And in fact, the Compaq DeskPro 386 ROM BIOS executes this instruction with MOD set to 0b00, so we have
* to ignore it.
*
* @this {X86CPU}
*/
X86.opMOVcr = function MOVcr()
{
var temp;
/*
* We address the MOD field problem (see above) by coercing it to 0b11 (0xc0), regardless.
*
* TODO: One issue not clearly addressed is if, when an assembler/compiler generated a bogus MOD value,
* it also generated the additional displacement bytes, if any, that would typically accompany such a MOD
* value. I assume not.
*/
var bModRM = this.getIPByte() | 0xc0;
var bModRM = this.getIPByte();
if (this.segCS.cpl) {
/*
@ -303,51 +309,55 @@ X86.opMOVcr = function MOVcr()
return;
}
var reg = (bModRM & 0x38) >> 3;
switch(reg) {
var reg;
switch(bModRM & 0x7) {
case 0x0:
temp = this.regEAX;
reg = this.regEAX;
break;
case 0x1:
temp = this.regECX; // TODO: Is setting CR1 actually allowed on an 80386?
reg = this.regECX;
break;
case 0x2:
temp = this.regEDX;
reg = this.regEDX;
break;
case 0x3:
temp = this.regEBX;
reg = this.regEBX;
break;
case 0x4:
reg = this.regESP;
break;
case 0x5:
reg = this.regEBP;
break;
case 0x6:
reg = this.regESI;
break;
case 0x7:
reg = this.regEDI;
break;
}
switch((bModRM & 0x38) >> 3) {
case 0x0:
X86.fnLCR0.call(this, reg);
this.nStepCycles -= 10;
break;
case 0x2:
this.regCR2 = reg;
this.nStepCycles -= 4;
break;
case 0x3:
X86.fnLCR3.call(this, reg);
this.nStepCycles -= 5;
break;
default:
X86.opInvalid.call(this);
X86.opUndefined.call(this);
return;
}
/*
* This instruction always assumes a 32-bit OPERAND size, so we must call setDataSize(4) first.
* TODO: Implement BACKTRACK for this instruction....
*/
this.setDataSize(4);
this.aOpModRegWord[bModRM].call(this, X86.fnMOV);
switch(reg) {
case 0x0:
reg = this.regEAX;
this.regEAX = temp;
X86.fnLCR0.call(this, reg);
break;
case 0x1:
this.regCR1 = this.regECX;
this.regECX = temp;
break;
case 0x2:
this.regCR2 = this.regEDX;
this.regEDX = temp;
break;
case 0x3:
reg = this.regEBX;
this.regEBX = temp;
X86.fnLCR3.call(this, reg);
break;
}
};
/*
@ -883,7 +893,7 @@ X86.opPOPFS = function POPFS()
X86.opBT = function BT()
{
this.aOpModMemWord[this.getIPByte()].call(this, X86.fnBT);
if (this.regEA !== X86.ADDR_INVALID) this.nStepCycles -= this.cycleCounts.nOpCyclesBitTestMExtra;
if (this.regEA !== X86.ADDR_INVALID) this.nStepCycles -= 6;
};
/**
@ -896,7 +906,7 @@ X86.opBT = function BT()
X86.opSHLDn = function SHLDn()
{
this.aOpModMemWord[this.getIPByte()].call(this, this.dataSize == 2? X86.fnSHLDwi : X86.fnSHLDdi);
this.nStepCycles -= (this.regEA === X86.ADDR_INVALID? this.cycleCounts.nOpCyclesShiftDR : this.cycleCounts.nOpCyclesShiftDM);
this.nStepCycles -= (this.regEA === X86.ADDR_INVALID? 3 : 7);
};
/**
@ -909,7 +919,7 @@ X86.opSHLDn = function SHLDn()
X86.opSHLDcl = function SHLDcl()
{
this.aOpModMemWord[this.getIPByte()].call(this, this.dataSize == 2? X86.fnSHLDwCL : X86.fnSHLDdCL);
this.nStepCycles -= (this.regEA === X86.ADDR_INVALID? this.cycleCounts.nOpCyclesShiftDR : this.cycleCounts.nOpCyclesShiftDM);
this.nStepCycles -= (this.regEA === X86.ADDR_INVALID? 3 : 7);
};
/**
@ -948,7 +958,7 @@ X86.opPOPGS = function POPGS()
X86.opBTS = function BTS()
{
this.aOpModMemWord[this.getIPByte()].call(this, X86.fnBTS);
if (this.regEA !== X86.ADDR_INVALID) this.nStepCycles -= this.cycleCounts.nOpCyclesBitSetMExtra;
if (this.regEA !== X86.ADDR_INVALID) this.nStepCycles -= 5;
};
/**
@ -961,7 +971,7 @@ X86.opBTS = function BTS()
X86.opSHRDn = function SHRDn()
{
this.aOpModMemWord[this.getIPByte()].call(this, this.dataSize == 2? X86.fnSHRDwi : X86.fnSHRDdi);
this.nStepCycles -= (this.regEA === X86.ADDR_INVALID? this.cycleCounts.nOpCyclesShiftDR : this.cycleCounts.nOpCyclesShiftDM);
this.nStepCycles -= (this.regEA === X86.ADDR_INVALID? 3 : 7);
};
/**
@ -974,7 +984,7 @@ X86.opSHRDn = function SHRDn()
X86.opSHRDcl = function SHRDcl()
{
this.aOpModMemWord[this.getIPByte()].call(this, this.dataSize == 2? X86.fnSHRDwCL : X86.fnSHRDdCL);
this.nStepCycles -= (this.regEA === X86.ADDR_INVALID? this.cycleCounts.nOpCyclesShiftDR : this.cycleCounts.nOpCyclesShiftDM);
this.nStepCycles -= (this.regEA === X86.ADDR_INVALID? 3 : 7);
};
/**
@ -1013,7 +1023,7 @@ X86.opLSS = function LSS()
X86.opBTR = function BTR()
{
this.aOpModMemWord[this.getIPByte()].call(this, X86.fnBTR);
if (this.regEA !== X86.ADDR_INVALID) this.nStepCycles -= this.cycleCounts.nOpCyclesBitSetMExtra;
if (this.regEA !== X86.ADDR_INVALID) this.nStepCycles -= 5;
};
/**
@ -1113,7 +1123,7 @@ X86.opMOVZXb = function MOVZXb()
this.regEBX = temp;
break;
}
this.nStepCycles -= (this.regEA === X86.ADDR_INVALID? this.cycleCounts.nOpCyclesMovXR : this.cycleCounts.nOpCyclesMovXM);
this.nStepCycles -= (this.regEA === X86.ADDR_INVALID? 3 : 6);
};
/**
@ -1154,7 +1164,7 @@ X86.opMOVZXw = function MOVZXw()
this.regEDI = (this.regEDI & 0xffff);
break;
}
this.nStepCycles -= (this.regEA === X86.ADDR_INVALID? this.cycleCounts.nOpCyclesMovXR : this.cycleCounts.nOpCyclesMovXM);
this.nStepCycles -= (this.regEA === X86.ADDR_INVALID? 3 : 6);
};
/**
@ -1177,7 +1187,7 @@ X86.opGRP8 = function GRP8()
X86.opBTC = function BTC()
{
this.aOpModMemWord[this.getIPByte()].call(this, X86.fnBTC);
if (this.regEA !== X86.ADDR_INVALID) this.nStepCycles -= this.cycleCounts.nOpCyclesBitSetMExtra;
if (this.regEA !== X86.ADDR_INVALID) this.nStepCycles -= 5;
};
/**
@ -1273,7 +1283,7 @@ X86.opMOVSXb = function MOVSXb()
this.regEBX = temp;
break;
}
this.nStepCycles -= (this.regEA === X86.ADDR_INVALID? this.cycleCounts.nOpCyclesMovXR : this.cycleCounts.nOpCyclesMovXM);
this.nStepCycles -= (this.regEA === X86.ADDR_INVALID? 3 : 6);
};
/**
@ -1314,7 +1324,7 @@ X86.opMOVSXw = function MOVSXw()
this.regEDI = ((this.regEDI << 16) >> 16);
break;
}
this.nStepCycles -= (this.regEA === X86.ADDR_INVALID? this.cycleCounts.nOpCyclesMovXR : this.cycleCounts.nOpCyclesMovXM);
this.nStepCycles -= (this.regEA === X86.ADDR_INVALID? 3 : 6);
};
X86.aOps0F = new Array(256);
@ -1333,14 +1343,26 @@ X86.aOps0F[0x06] = X86.opCLTS;
X86.aOps0F[0x0B] = X86.opInvalid;
/*
* NOTE: Any other opcode slots NOT explicitly initialized above with either a dedicated function OR opInvalid()
* will be set to opUndefined() when initProcessor() finalizes the opcode tables. If the processor is an 80386,
* initProcessor() will also incorporate all the handlers listed below in aOps0F386.
* The following 0x0F opcodes are of no consequence to us, since they were all introduced post-80386;
* 0x0F,0xA6 and 0x0F,0xA7 were introduced on some 80486 processors (and then deprecated), while 0x0F,0xB0
* and 0x0F,0xB1 were introduced on 80586 (aka Pentium) processors.
*
* A call to opUndefined() implies something serious has occurred that merits our attention (eg, perhaps someone
* is using an undocumented opcode that we haven't implemented yet), whereas a call to opInvalid() may or may not.
* CMPXCHG r/m8,reg8 ; 0F B0 /r [PENT]
* CMPXCHG r/m16,reg16 ; o16 0F B1 /r [PENT]
* CMPXCHG r/m32,reg32 ; o32 0F B1 /r [PENT]
* CMPXCHG486 r/m8,reg8 ; 0F A6 /r [486,UNDOC]
* CMPXCHG486 r/m16,reg16 ; o16 0F A7 /r [486,UNDOC]
* CMPXCHG486 r/m32,reg32 ; o32 0F A7 /r [486,UNDOC]
*
* For example, when Windows initializes in protected-mode, it sets a DPMI exception handler for UD_FAULT and
* So why are we even mentioning them here? Only because some software (eg, Windows 3.00) attempts to execute
* 0x0F,0xA6, so we need to explicitly mark it as invalid. TODO: Purely out of curiosity, I would like to
* eventually learn *why* Windows 3.00 does this; is it hoping to use the CMPXCHG486 opcode, or is it performing
* a CPU/stepping check to detect/work-around some errata, or....?
*/
X86.aOps0F[0xA6] = X86.opInvalid;
/*
* When Windows 95 Setup initializes in protected-mode, it sets a DPMI exception handler for UD_FAULT and
* then attempts to generate that exception with undefined opcode 0x0F,0xFF. Apparently, whoever wrote that code
* (davidw?) didn't get the Intel memo regarding the preferred invalid opcode (0x0F,0x0B, aka UD2), or perhaps Intel
* hadn't written that memo yet -- although if that's the case, then Intel should have followed Microsoft's lead and
@ -1350,6 +1372,15 @@ X86.aOps0F[0x0B] = X86.opInvalid;
*/
X86.aOps0F[0xFF] = X86.opInvalid;
/*
* NOTE: Any other opcode slots NOT explicitly initialized above with either a dedicated function OR opInvalid()
* will be set to opUndefined() when initProcessor() finalizes the opcode tables. If the processor is an 80386,
* initProcessor() will also incorporate all the handlers listed below in aOps0F386.
*
* A call to opUndefined() implies something serious has occurred that merits our attention (eg, perhaps someone
* is using an undocumented opcode that we haven't implemented yet), whereas a call to opInvalid() may or may not.
*/
if (I386) {
X86.aOps0F386 = [];
X86.aOps0F386[0x20] = X86.opMOVrc;

View file

@ -380,21 +380,44 @@ testROM:
;
movzx eax,byte [0xfffff]
cmp eax,0x00000080
jne error
jne near error
;
; Test moving a word to a 32-bit register with zero-extension
;
movzx eax,word [0xffffe]
cmp eax,0x000080fc
jne error
jne near error
;
; More assorted ZX and SX tests
;
mov esp,0x40000
mov edx,[esp] ; save word at scratch address 0x40000
add esp,4
push -128 ; NASM refuses to use opcode 0x6A ("PUSH imm8")
pop ebx ; verify EBX == 0xFFFFFF80
and ebx,0xff ; verify EBX == 0x00000080
movsx bx,bl ; verify EBX == 0x0000FF80
movsx ebx,bx ; verify EBX == 0xFFFFFF80
movzx bx,bl ; verify EBX == 0xFFFF0080
movzx ebx,bl ; verify EBX == 0x00000080
not ebx ; verify EBX == 0xFFFFFF7F
movsx bx,bl ; verify EBX == 0xFFFF007F
movsx ebx,bl ; verify EBX == 0x0000007F
not ebx ; verify EBX == 0xFFFFFF80
movzx ebx,bx ; verify EBX == 0x0000FF80
movzx bx,bl ; verify EBX == 0x00000080
movsx bx,bl
neg bx
neg bx
movsx ebx,bx
neg ebx
neg ebx
;
; Test assorted 32-bit addressing modes
;
mov ax,SSEG_PROT32 ; we're not going to use the stack, but we want SS != DS for the next tests
mov ax,SSEG_PROT32 ; we want SS != DS for the next tests
mov ss,ax
sub esp,esp
mov edx,[0x40000] ; save word at scratch address 0x40000
mov eax,0x11223344
mov [0x40000],eax ; store a known word at the scratch address

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long