Just added a bit of extra checks(making floppy disk image creation and hard disk image creation check if the destination disk image is currently mounted. In the case of hard disk comversion, it'll now force a reboot of the emulated client(hard disk image is overwritten by another one, thus invalid for the currently emulated system(esp. Windows/linux, which may have parts cached in memory)). In the case of a mounted floppy it'll force a remount of the disk image(just unmount and remount it, making the FDC think the disk is ejected, changed on another PC and reinserted after that, because remounting it sets the disk changed flag(or drive door opened flag in bit 7 of the HDD-shared I/O port)).
I've also added an option to create empty, unformatted(only single 0-type 128-byte sectors on tracks) IMD disk images.
Just tried running PC-Check 6.21 on my 80486 emulation. It seems to display the GUI with the logo, then hang on some instructions from 5BF0:6454, which mostly consists of 0x0000 bytes being executed by the CPU?
The logo displays fine, while the bottom of the screen says:
1Pc-Check 6.21, Loading Drive Library... (rights side of the screen)10001
OK. It seems that the location MS-DOS 6.22 setup crashes from is starting at F000:8985, executing an IRET. So that's address 985h in the BIOS ROM itself(the two ROMs combined).
The last interrupt fired was a single-step interrupt(INT 01h) it seems.
Edit: OK, interesting... Tracing the BIOS disassembly back, I see that it might actually be a INT 13h call from MS-DOS 6.22 that went awry, somehow setting the Trap flag along the way?
OK. So, according to the Compaq Deskpro 386 technical reference manual, it uses a "B237A-5 Byte DMA Controller" (taken from https://www.pcjs.org/machines/pcx86/compaq/deskpro386/ , the COMPAQ DeskPro 386 Technical Reference Guide
(Volume I, Sep 1986) page 2-38.
It is indeed a normal DMA controller according to what follows in the documentation(it also explains something about the DMA page registers' working). Apparently it even has a second PIT at 48h-4Bh, although I have no idea how said " Failsafe Clock" actually works, but it's probably just a normal NMI(according to page 4-67). So it's the normal failsafe timer. That's not actually implemented in UniPCemu yet.
Edit: Having fixed the DMA controller to behave as intended(at least it's intended that way with the FDC), MS-DOS 6.22 setup now properly loads and doesn't crash(because the data to write to memory is discarded by the DMA controller since it's in verify mode during that part). 😁
I've also now implemented the "Failsafe Clock" from the documentation. It now ticks and triggers an NMI (when it's enabled), replacing the memory I/O NMI, as documented in the Compaq Deskpro 386 technical reference guide.
So now, the motherboard is fully emulated(according to that documentation on it's I/O ports and peripherals). The only thing I actually left out and didn't implement is the Numeric Coprocessor part, but no 80387 or 80*87 is implemented, so it shouldn't be a problem, right?
OK. Just reinstalled Windows 95 RTM. Now the explorer.exe seems to be hanging itself somehow?
When opening the Start menu or This PC, it starts hanging until you terminate it using the task manager?
Something went quite wrong in those last builds... I doubt it's the DMA controller, though.
It's happening quite strangely: when Windows 95 RTM boots, it loads the desktop(OK), then proceeds to load the first time boot message(that What's new in Windows 95 program), then about right after that the mouse still responds, but all applications pretty much start doing nothing at all?
Anyone knows what might be the cause? I ran wincheckit 4's bootdisk, but it immediately crashes with a "Divide error"?
OK. It might be that either explorer.exe(which contains all that hangs) is damaged, or it's actually not running in the correct way.
Would there be an easy way to verify this?
OK. Running the program manager as the shell in Windows 95 doesn't crash. So it's clearly a problem with Explorer.exe.
And while debugging the issue in Visual Studio, once again the debugger took Visual Studio along it to hang... Getting pretty annoying by now, trying to debug only to have Visual Studio hang on me while doing so...
But at least the Program Manager seemed to work fine. So that's at least something to test the Windows 95 kernel with! 😁
OK. I just tried to run the File Manager application from the Windows 95 Main program group. It seems to hang as well?
Edit: Yup. Windows 95's Winfile.exe also seems to stop responding when starting up, just like Explorer.exe.
Edit: Tried running Hyperterminal to check if the COM port was functioning properly, which opened the folder for the Hyperterminal programs. Then running Hyperterminal itself ran fine(other than it not being able to propely send any dial commands to the serial modem. I see it modifying RTS and DTR, but since the modem is setup for having CTS and DSR always set(default settings), it seems that Hyperterminal(and Windows for that matter) don't like it?
I do see the modem responding to DTR being lowered, by resetting the modem to it's default settings, though.
Anyone knows something about how the serial modem's default settings are supposed to be like?
The current defaults are:
1 modem.communicationstandard = 0; //Default communication standard! 2 modem.echomode = 1; //Default: echo back! 3 //Speaker controls 4 modem.speakervolume = 3; //Max level speaker volume! 5 modem.speakercontrol = 1; //Enabled speaker! 6 //Result defaults 7 modem.verbosemode = 1; //Text-mode verbose! 8 modem.callprogressmethod = 4; 9 //Default handling of the Hardware lines is also loaded: 10 modem.DCDisCarrier = 1; //Default: DCD=Set Data Carrier Detect (DCD) signal according to remote modem data carrier signal.. 11 modem.DTROffResponse = 2; //Default: Hang-up and Goto AT command mode?! 12 modem.flowcontrol = 3; //Default: Enable RTS/CTS flow control! 13 modem.communicationsmode = 5; //Default: communications mode 5 for V-series system products, &Q0 for Smartmodem products! So use &Q5 here! 14 modem.CTSAlwaysActive = 1; //Default: CTS controlled by flow control! 15 modem.DSRisConnectionEstablished = 0; //Default: DSR always ON! 16 //Finish up the default settings! 17 modem.datamode = 0; //In command mode!
Are those default settings correct?
UniPCemu sets the lines as follows:
1 //0: Clear to Send(Can we buffer data to be sent), 1: Data Set Ready(Not hang up, are we ready for use), 2: Ring Indicator, 3: Carrrier detect 2 if (modem.communicationsmode && (modem.communicationsmode < 4)) //Synchronous mode? CTS is affected! 3 { 4 switch (modem.CTSAlwaysActive) 5 { 6 case 0: //Track RTS? 7 result |= ((modem.effectiveline >> 1) & 1); //Track RTS! 8 break; 9 case 1: //Depends on the buffers! 10 result |= ((modem.datamode == 1) ? ((modem.connectionid >= 0) ? (fifobuffer_freesize(modem.outputbuffer[modem.connectionid]) ? 1 : 0) : 1) : 1); //Can we send to the modem? 11 break; 12 case 2: //Always on? 13 result |= 1; //Always on! 14 break; 15 } 16 } 17 else 18 { 19 //Hayes documentation says it doesn't control CTS and RTS functions! 20 result |= ((modem.effectiveline >> 1) & 1); //Always on! &Rn has no effect according to Hayes docs! But do this anyways! 21 } 22 //DSRisConnectionEstablished: 0:1, 1:DTR 23 if ((modem.communicationsmode) && (modem.communicationsmode < 5)) //Special actions taken? 24 { 25 //((modem.outputline & 1) << 1) 26 switch (modem.DSRisConnectionEstablished) //What state? 27 { 28 default: 29 case 0: //S0? 30 case 1: //S1? 31 //0 at command state and idle, handshake(connected) turns on, lowered when hanged up. 32 if ((modem.connected == 1) && (modem.datamode != 2)) //Handshaked? 33 { 34 result |= 2; //Raise the line! 35 } 36 //Otherwise, lower the line! 37 break; 38 case 2: //S2? 39 //0 at command state and idle, prior to handshake turns on, lowered when hanged up. 40 if ((modem.connected == 1) && (modem.datamode)) //Handshaked or pending handshake? 41 { 42 result |= 2; //Raise the line! 43 } 44 //Otherwise, lower the line! 45 break; 46 } 47 } 48 else //Q0/5/6? 49 { 50 switch (modem.DSRisConnectionEstablished) //What state? 51 { 52 default: 53 case 0: //S0? 54 result |= 2; //Always raised! 55 break; 56 case 1: //S1? 57 result |= ((modem.outputline & 1) << 1); //Follow handshake! 58 break; 59 case 2: //S2? 60 result |= ((modem.outputline & 1) << 1); //Follow handshake!
…Show last 7 lines
61 break; 62 } 63 } 64 result |= (((modem.ringing&1)&((modem.ringing)>>1))?4:0)| //Currently Ringing? 65 (((modem.connected==1)||(modem.DCDisCarrier==0))?8:0); //Connected or forced on? 66 return result; //Give the resulting line status! 67}
OK. Reinstalling Windows 95 RTM from scratch(with a cleared harddisk) seemed to have fixed the Start menu problem at least! 😁 Haven't checked the explorer yet, though(File explorer in the 3.1 interface, Explorer.exe as well as This PC). System properties works fine, though! 😁
Although I noticed I had to configure various hardware devices(primarily IRQ settings) manually from the System Properties? Those devices are incorrectly detecting things like IRQ settings(mainly).
Those are:
- Sound Blaster IRQ somehow set to 3. This is actually the IRQ of the second COM port. It's supposed to be 5(which is what the hardware raises and lowers).
- The serial mouse is detected twice and the duplicate has to be removed? Why would this happen? It's only responding on one UART(COM1) at 3F8?
- It only detects one of the two CD-ROM drives by default? It's set up for drive n-n, where n=n, so only one drive is visible(two drives on the secondary slave are present)?
- The UARTs have the FIFO enabled, while they have none.
There's also something I don't know:
- "IO read data port for ISA Plug and Play enumerator". Looking at it's automatic settings says 270h,370h,238h,338h(4 ports each at said address).
Anyone knows what this is?
The MPU-401(whose Intellingent version is a slightly adjusted version of Dosbox's, with my own MIDI softsynth connected to it(either my softsynth or passed through to Windows, setup by the Soundfont setting and passthrough setting in the emulator settings)) is currently not enabled in the emulation settings. It's the only device still unlisted.
When running the add new hardware wizard, I actually see the IRR register setting it's IR bits when handling the interrupt, until the Sound Blaster status register is read, which clears the IR line.
Since the IRR register is still set then, that would mean the IRQ5(Of the Sound Blaster) is masked off or not raised yet due to cleared interrupt flag? Anyone knows how Windows 95 detects hardware IRQs?
Just found a tiny bug in the multithreading code(the code that's responsible for all threads starting, parameters and finishing/deleting and registration of threads). When a thread was requested to be started, it would immediately return with the unstarted thread(thread pool allocated and request given to start, but the thread itself hasn't marked it as being running or terminated yet(which is done from the thread itself)) in some cases. So when the main thread after starting another thread(or the debugger thread starting another thread), it would see the thread as not running anymore and delete the thread pointer(set it to NULL, blindly assuming the thread has ended).
I've now added some bit of code to the multithreading thread start handler(which is called for starting a new thread) that does some synchronization with the thread, waiting for it to start executing and mark itself as running or terminated, only returning after that is detected(or the thread has been deleted by finishing the thread from within the thread itself, in which case no problem occurs with the caller(it's terminated anyway)).
Just found a bug in the ATAPI bytes left detection(for partial transfers). When a transfer had exactly 64K as the amount of bytes to transfer in one go, it would report 0x10000 bytes to use, which would be truncated to 0 bytes because it's stored in a 16-bit variable(for example, with the cylinder high/low registers). I've just fixed it to become 0xFFFE bytes instead in that case(which IS a valid value to transfer) instead of 0 in that case. The same case was happening for the end-of-transfer detection, which was being truncated to 0 in that case(and invalid 16-bit truncated values for anything larger than 64K becoming modulo 64K, which is incorrect). Now it's properly handling those cases as 0xFFFE bytes instead(the largest that can be transferred in one go).
That seems to get rid of all the Status=0x48 IRQ time out messages on Debian Bo.
Lol. Although I was testing the hardware and CPU emulation with Debian Bo, I also found out how it archieves it's 'screen saver' functionality: simply have the start of rendered characters at a window's end address(at least one window of characters worth) through the start address registers, then set the cursor location within that window's addresses(so it won't display at all), and fill the entire wndow with black(attribute 0 for foreground and background) 'space'(0x20) characters. So in that way, it creates a black display area without cursor, simulating the display being off!
Wouldn't it be easier to just set the Sequencer Clocking Mode register bit 5(SD -- Screen Disable) bit?
Just tried running Windows 95 OSR 2.5 again(aka Windows 95C).
It seems to end up at address 1E:xxxxh, executing a FFFFh instruction, which is GRP5 /7, which doesn't exist?
This seems to fault directly to the BIOS, causing the entire thing to come crashing down(hanging with infinite #UD faults at the same address)?
Edit: OK. The first opcode at that segment being executed is this:
That's kind of a strange way to start a program or driver? What software starts with a JNZ to a ridiculously high address? Also, segment 1Eh in real mode is in the middle of the IVT? So that shouldn't happen to begin with?
This is what happens(full common emulator format log with extra details):
The attachment debugger_Windows95C_crash_UniPCemu_20200504_2047.7z is no longer available
Interestingly, the previous instruction was at 0070:00000378. 378h is the port of the LPT1? Or perhaps some weird address being addressed inside the IO.SYS?
Although it's outside the 64K barrier(address 10085h).
Just tried running some games for verifying if they still run properly(various MS-DOS 32-bit games).
I noticed, when running Discworld, that there were still a lot of DPMI(or what seemed like it) processes loaded in memory, according to "mem /D /p"?
Is that supposed to happen? Aren't those supposed to be cleaned up and unloaded once the game is terminated?
With the latest commits, UniPCemu now keeps most of it's previous machine settings(Emulated CPU, Data bus size, (Turbo) CPU speed, Turbo CPU speed mode, clocking mode) in the architecture-specific section. The architecture, execution mode, show CPU speed, BIOS ROM mode and inboard initial waitstates are still a global setting.
Said architecture-specific settings are now(together with other settings like emulated memory, CMOS state, timekeeping and mode as well as the floppy drive type without any disk inserted) only set for the currently selected architecture. Said architecture is selected when the emulator is started(the architecture setting). You can change the architecture setting to be loaded when the emulator restarts or is started, but it won't apply until the emulator is actually rebooted or started again(which makes said architecture active).
Perhaps I'll add a little text in the Settings menu that shows the currently active architecture to show which one is currently being changed...
Edit: Just added said marker just below the Settings menu text, above the current menu title.
Just tried Comanche: Maximum Overkill on UniPCemu's latest commit. It seems to run without visible issues.
Windows 95 B and up still hang during boot at real mode segment 1Eh executing opcode FFFFh?
Edit: Privateer still hangs(at least with Sound Blaster being setup for both effects and music)? Anyone knows if this is a software issue or some CPU emulation issue itself that must have a problem?
Just added a new little feature to UniPCemu's parameters:
You can now direct added joysticks(by plugging them in when using SDL2 builds) to make UniPCemu only start connecting to it when it has focus(so only the active window receives the input event that tells it to connect to the joystick).
Said feature also adds a little extra: when a joystick is connected while the parameter is used, UniPCemu will even respond to it when it doesn't have focus, allowing for multiplayer using multiple joysticks connected to multiple instances of UniPCemu(each joystick on one instance).
Said parameter is multiplayerjoysticks .
So, to start such a multiplayer session, simply open up one instances of UniPCemu with said parameter added to the command line(or using a shortcut to UniPCemu's executable on Windows) for each of the players.
Then follow the following steps to associate a joystick with an instance:
1. Give window focus to the instance to associate it with
2. Connect the controller to associate with the instance.
These steps are repeated for each controller to associate with an instance (no more than 1 controller for each instance).
Although it currently still only supports XBox 360 controllers (Using the old pre-SDL2 gamecontroller method).
So if you have multiple XBox 360 controllers, you can now use them to play multiplayer joystick games using, for example, two UniPCemu instances running a mulitplayer game over the modem! 😁
Last edited by superfury on 2020-08-17, 16:41. Edited 1 time in total.