Starting work on disambiguating PCjs the emulator from PCjs the project/website; the emulator will become PCx86
This commit is contained in:
parent
7c3aab2a7e
commit
288f28055d
1519 changed files with 16242 additions and 6939 deletions
|
|
@ -5,17 +5,17 @@ date: 2015-07-17 11:00:00
|
|||
category: Windows 95
|
||||
permalink: /blog/2015/07/17/
|
||||
machines:
|
||||
- type: pc
|
||||
- type: pcx86
|
||||
id: deskpro386
|
||||
debugger: true
|
||||
state: /disks/pc/windows/win95/4.00.950/deskpro386.json
|
||||
config: /devices/pc/machine/compaq/deskpro386/vga/4096kb/debugger/machine.xml
|
||||
drives: '[{name:"68Mb Hard Disk",type:4,path:"http://archive.pcjs.org/disks/pc/fixed/68mb/win95.json"}]'
|
||||
state: /disks/pcx86/windows/win95/4.00.950/deskpro386.json
|
||||
config: /devices/pcx86/machine/compaq/deskpro386/vga/4096kb/debugger/machine.xml
|
||||
drives: '[{name:"68Mb Hard Disk",type:4,path:"http://archive.pcjs.org/disks/pcx86/fixed/68mb/win95.json"}]'
|
||||
autoMount: ''
|
||||
---
|
||||
|
||||
This week (July 14, 2015) was the 20th anniversary of Windows 95 RTM ("Release To Manufacturing"). So I decided to
|
||||
throw a PCjs party and try running Windows 95 Setup inside a PCjs machine for the first time.
|
||||
throw a PCjs party and try running Windows 95 Setup inside a PCx86 machine for the first time.
|
||||
|
||||
Sadly, it immediately failed:
|
||||
|
||||
|
|
@ -52,17 +52,17 @@ The failing code:
|
|||
0E36:0927 07 POP ES
|
||||
0E36:0928 C3 RET
|
||||
|
||||
was easily fixed with a change to [x86cpu.js](/modules/pcjs/lib/x86cpu.js), allowing the IOPL bits to be
|
||||
was easily fixed with a change to [x86cpu.js](/modules/pcx86/lib/x86cpu.js), allowing the IOPL bits to be
|
||||
modified in real-mode on an 80386. When I had previously tweaked setPS() to accomodate 80286/80386 discrimination
|
||||
logic in OS/2 1.0, there was no 80386 support in PCjs at that time, so it was sufficient to *never* allow the
|
||||
logic in OS/2 1.0, there was no 80386 support in PCx86 at that time, so it was sufficient to *never* allow the
|
||||
IOPL bits to be altered in real-mode.
|
||||
|
||||
The next problem was triggered by Setup's CAB ("Diamond") decompression code, which uses all 32 bits
|
||||
of the 80386's 32-bit registers. That in itself was not a problem, but by leaving stray bits in the upper halves of
|
||||
registers like EDX, it exposed a bug in the PCjs I/O instruction handlers, which neglected to mask EDX with 0xFFFF before
|
||||
registers like EDX, it exposed a bug in the PCx86 I/O instruction handlers, which neglected to mask EDX with 0xFFFF before
|
||||
performing port lookups, causing mysterious I/O failures that usually manifested themselves as hard disk I/O errors.
|
||||
|
||||
Then PCjs crashed in the middle of the decompression of the first CAB file (MINI.CAB). It turned out the stack
|
||||
Then PCx86 crashed in the middle of the decompression of the first CAB file (MINI.CAB). It turned out the stack
|
||||
had been improperly adjusted because a "RETF n" instruction mistakenly believed that a stack switch had occurred.
|
||||
This was, in fact, a left-over condition from a protected-mode stack-switch. That was easily cleared.
|
||||
|
||||
|
|
@ -75,7 +75,7 @@ fixed by flagging the opcode as genuinely invalid.
|
|||
|
||||
> SIDEBAR
|
||||
|
||||
> By default, PCjs marks opcodes as invalid *only* if they have been confirmed invalid. PCjs considers the vast
|
||||
> By default, PCx86 marks opcodes as invalid *only* if they have been confirmed invalid. PCx86 considers the vast
|
||||
majority of unused/undocumented opcodes to be merely "undefined" until I've seen them in the wild. An instruction will
|
||||
be marked invalid if I either discover that real hardware treats it as an Invalid Opcode (by throwing the exception)
|
||||
*or* that real software expects it to. For opcode 0x0F,0xFF, it was the latter.
|
||||
|
|
@ -86,9 +86,9 @@ I consider it a misnomer to refer to any invalid instruction as "undefined".
|
|||
|
||||
The other recent Windows 95 oddity I ran into was an instruction with multiple address-override (0x67) prefixes; the
|
||||
first prefix changed the instruction's addressing mode from 16-bit to 32-bit, and the second prefix changed it back to
|
||||
16-bit. PCjs should have simply ignored the second prefix.
|
||||
16-bit. PCx86 should have simply ignored the second prefix.
|
||||
|
||||
With all of the above changes in place, PCjs v1.18.4 is able to run Windows 95 Setup a bit farther, but still far from
|
||||
With all of the above changes in place, PCx86 v1.18.4 is able to run Windows 95 Setup a bit farther, but still far from
|
||||
completion. If you want to give it a spin yourself, start the machine below (click the "Run" button) and once it has
|
||||
finished booting, run SETUP from drive B, where the first Windows 95 diskette is already loaded.
|
||||
|
||||
|
|
@ -103,9 +103,9 @@ diskette.
|
|||
August 13, 2015 Update
|
||||
---
|
||||
|
||||
PCjs v1.18.8 has made a little more progress running Windows 95 Setup, but CAB decompression still fails almost
|
||||
PCx86 v1.18.8 has made a little more progress running Windows 95 Setup, but CAB decompression still fails almost
|
||||
immediately. To monitor DOS calls until the first 36-byte read of PRECOPY1.CAB, try setting the following
|
||||
breakpoint and then starting the machine, using the PCjs Debugger *input* field next to the **Enter** button:
|
||||
breakpoint and then starting the machine, using the PCx86 Debugger *input* field next to the **Enter** button:
|
||||
|
||||
m dos off
|
||||
bp 1ED4:16B4 "set fn=ah;dos;if fn!=3f||cx!=24"
|
||||
|
|
@ -132,7 +132,7 @@ second breakpoint can check the value on exit.
|
|||
|
||||
Regarding the other Debugger commands shown above, the `dos` command describes the current DOS operation
|
||||
(alternatively, you could use the `m int on; m dos on` commands to turn on DOS interrupt messages). The `di`
|
||||
command dumps PCjs BACKTRACK(tm) information, to help you visually confirm which INT 0x21 calls are reading
|
||||
command dumps PCx86 BACKTRACK(tm) information, to help you visually confirm which INT 0x21 calls are reading
|
||||
PRECOPY1.CAB. Finally, the `if` command evaluates the given expression, and if the result is non-zero ("true"),
|
||||
all subsequent commands are executed, up to to any `else` command; otherwise, only commands after the `else`
|
||||
command will be executed, and if there is no `else` command, execution will stop.
|
||||
|
|
@ -142,17 +142,17 @@ are evaluated using traditional operator precedence (ie, the same as C or JavaSc
|
|||
parentheses, assignment operators, and unary or ternary operators, are not supported in expressions.
|
||||
|
||||
This test machine below has been updated to load WDEB386.EXE prior to starting B:SETUP.EXE, if you prefer using
|
||||
WDEB386. Make sure the machine is running (ie, click the **Run** button, or use the PCjs Debugger "g" command),
|
||||
WDEB386. Make sure the machine is running (ie, click the **Run** button, or use the PCx86 Debugger "g" command),
|
||||
and then click on the Debugger *output* control to give it focus and press CTRL-C to trigger WDEB386.
|
||||
|
||||
The Debugger *input* field is used exclusively for PCjs Debugger commands, whereas the *output* textarea combines
|
||||
all Debugger output *and* WDEB386 COM2 serial port I/O. You can even use the PCjs Debugger to debug
|
||||
The Debugger *input* field is used exclusively for PCx86 Debugger commands, whereas the *output* textarea combines
|
||||
all Debugger output *and* WDEB386 COM2 serial port I/O. You can even use the PCx86 Debugger to debug
|
||||
the WDEB386 debugger; just make sure the appropriate text control has focus before typing a command.
|
||||
|
||||
To help reduce confusion, the PCjs Debugger displays a double-character command prefix, to differentiate its commands
|
||||
To help reduce confusion, the PCx86 Debugger displays a double-character command prefix, to differentiate its commands
|
||||
from WDEB386's single-character command prompt -- but it's still easy to get confused.
|
||||
|
||||
A quick recap of those command prefixes (which you won't see until AFTER you've typed a PCjs command):
|
||||
A quick recap of those command prefixes (which you won't see until AFTER you've typed a PCx86 command):
|
||||
|
||||
* `>>` indicates real-mode
|
||||
* `##` indicates protected-mode
|
||||
|
|
@ -165,7 +165,7 @@ A quick recap of those command prefixes (which you won't see until AFTER you've
|
|||
August 21, 2015 Update
|
||||
---
|
||||
|
||||
PCjs v1.19.1 has finally solved a number of nagging bugs. The CAB decompression code itself was running
|
||||
PCx86 v1.19.1 has finally solved a number of nagging bugs. The CAB decompression code itself was running
|
||||
fine; it would crash after loading a 32-bit value into EAX *and* a timer interrupt occurred. A path
|
||||
through the interrupt handler was trashing the upper bits of EAX. The culprit: any of the MOV instructions
|
||||
that move an immediate value into one of the "high" 8-bit registers (AH, BH, CH, or DH). Those instructions
|
||||
|
|
|
|||
Loading…
Reference in a new issue