VOGONS


i430fx/i440fx motherboard emulation issues?

Topic actions

First post, by superfury

User metadata
Rank l33t++
Rank
l33t++

Is it possible to make it support more than 16MB RAM? For example, if I install 512MB RAM into the emulated machine, is it possible for the software to see the full 512MB?
Perhaps some option ROM to extend the RAM detection to 3GB?

Last edited by superfury on 2020-11-06, 23:09. Edited 2 times in total.

Author of the UniPCemu emulator.
UniPCemu Git repository
UniPCemu for Android, Windows, PSP, Vita and Switch on itch.io

Reply 1 of 71, by superfury

User metadata
Rank l33t++
Rank
l33t++

Just looked at other emulators. The PCem's Award 430VX PCI configuration supports 256MB of RAM. Is there an easy way to implement this in UniPCemu?
What are the minimum hardware that needs to be emulated for this to work?

Author of the UniPCemu emulator.
UniPCemu Git repository
UniPCemu for Android, Windows, PSP, Vita and Switch on itch.io

Reply 2 of 71, by superfury

User metadata
Rank l33t++
Rank
l33t++

Just implemented the i430fx chipset support based on PCem-X's i430fx.c.

Would that be enough to get a modern(ish) BIOS booting with more than 512MB? It now uses the Compaq memory mapping and hardware(with PS/2 instead of serial mouse) combined with the i430fx's BIOS ROM mapping registers being implemented.
It's essentially the Compaq Deskpro 386 with PS/2 mouse and i430fx BIOS ROM mapping implemented on a legacy PCI I/O port(3C8-3CF).

Author of the UniPCemu emulator.
UniPCemu Git repository
UniPCemu for Android, Windows, PSP, Vita and Switch on itch.io

Reply 3 of 71, by superfury

User metadata
Rank l33t++
Rank
l33t++

Tried booting with some BIOS ROMs(using a 3MIPS Pentium without FPU), but all I seem to see is some routine that seems to keep polling port 60h/64h(bit 4) infinitely it seems?

Is more needed than just the TDC(on legacy PCI) and the bit 4 and 2 bit combination on port 3f9? Does any other chip need to be present for such a BIOS to POST?

Edit: It seems that with the latest bugfixes, it now seems to be extracting the BIOS? I see the PAM registers being enabled one by one(at least checked until the upper half of the PAM registers got enabled to read from RAM and write to PCI). 😁

It's now using the 5728P.ROM file from https://sourceforge.net/p/bochs/feature-requests/468/?page=0 (https://sourceforge.net/p/bochs/feature-reque … /468/#32f2/ba89)

Edit: It seems to infinitely be executing some JNZ AB7C instruction at F000:AB7C. So it's somehow determined that something is done incorrectly? Could it be the RAM detection that's not implemented? The DRAM registers(60-64h) all contain the value 02h.

Author of the UniPCemu emulator.
UniPCemu Git repository
UniPCemu for Android, Windows, PSP, Vita and Switch on itch.io

Reply 4 of 71, by superfury

User metadata
Rank l33t++
Rank
l33t++

Anyone knows how those DRAM row registers work? How are they used to detect RAM?

Edit: Just added support for enabling SMRAM(which is just redirected to the same DRAM as the PAM registers redirect to). Although I still need to figure out how the CPU opens the window to SMRAM when not in System Management Mode.
Anyone knows how it does that?

Edit: Managed to figure it out and implemented the SMRAM register and functionality as documented. It just looked complicated, while it's actually quite simple.

Implemented a simple memory limiting scheme on the DRAM registers(60h-64h of the 82437FX TSC PCI space). It will simply revert a written value when it's resulting in the memory being above the emulated memory size for now.
This results in it detecting the 16MB RAM as 8MB, however?
Anyone knows how such a detection works? How does real hardware respond to it? What happens to the values that are written?

Edit: Just continued implementing some basic stuff (APM register storage still without SMI handling and the PIIX PCI interface and PIIX IDE interface(leveraging the existing IDE PCI interface with different PCI headers(ID etc.))).
Although stuff like Bus Mastering DMA transfers for the PCI device still won't work due to it not being supported yet.

Edit: Just added a bit more, namely the APM and ELCR registers.

The BIOS still isn't POSTing, though?

Edit: Still hanging at F000:AB7C's JNZ $-2.

Author of the UniPCemu emulator.
UniPCemu Git repository
UniPCemu for Android, Windows, PSP, Vita and Switch on itch.io

Reply 5 of 71, by superfury

User metadata
Rank l33t++
Rank
l33t++

OK. Looking at what it's basing the infinite loop on: it's done something to the 8042 controller and requires the value read from port 60h(PS/2 keyboard, PS/2 controller or PS/2 mouse) to have bit 6 cleared for some reason(it's read 0xEC from the 8042).

Filename
debugger_UniPCemu_PS2_i430fxBIOS_bootfailing.7z
File size
1.25 MiB
Downloads
63 downloads
File comment
i430fx failing to boot.
File license
Fair use/fair dealing exception

Edit: After replacing all ",60" with ",ii60" and "60," with "ii60," and the same for the value "64", I see something interesting when searching for "ii" through the code. It seems to do some normal startup stuff with the 8042, but eventually reads the Input Port on the 8042. This returns the value 0xEC, which has bit 6 set(some unknown bit currently).

Edit: Just made it behave the same as PCem-X, so it will pass said test now it seems 😁
Now more extraction of the BIOS seems to occur(I see the PAM registers keep getting written with different mapping values(write=PCI vs write=RAM)).

Edit: OK. I see it issuing command 0xFF to the 8042 command/status port? Followed by c0 and a1 twice? Is a1 supposed to do something?
Edit: Ah. That behaviour is triggered by sending command A1(AMI version command) and receiving 4D or lower as a result! So it needs to return 4E at least?

Author of the UniPCemu emulator.
UniPCemu Git repository
UniPCemu for Android, Windows, PSP, Vita and Switch on itch.io

Reply 6 of 71, by superfury

User metadata
Rank l33t++
Rank
l33t++

OK. Now, having implemented the 8042 AMI read keyboard mode(0xCA), command A1 returning 0x4E as a result, command 0xCB to make the next write set the keyboard mode byte(unused, except for the result of command 0xCA), it once again performs command 0xFF.

Now, having the 0xFF command give a result of 0x52(as the BIOS seems to expect for some reason), I now see it starting to copy the BIOS ROMs to 0x2000(copy of segment E000) and 0x4000(copy of segment F000), eventually jumping to code within segment 2000h and it jumping tox 4000h:0 to execute some weird DIV BX instruction infinitely(it's silled with 0xF7FF values or something like that)?

Edit: Interesting, searching for the original BIOS ROM filename(S728P.ROM) on google reveals this: https://ami.com/ami_downloads/Apollo_S728_Users_Guide.pdf

So it's apparently a AMI Apollo Pentium PCI ISA motherboard BIOS I'm trying to run? At least I now know what I'm dealing with 😁
Unfortunately it mentions nothing specific about the boot process(it does about the flashing of the BIOS in a normal user manual guide way, though). That's probably the source of the BIOS ROM I'm trying to use atm for testing(Said BIOS update floppy itself).

So said memory is filled with F7,F3 bytes following each other for at least 256 bytes or more.
Edit: I've made a log of the BIOS running after sending the 0xFF byte to port 64h:

Filename
debugger_UniPCemu_20200714_1851_i430fxBIOS.7z
File size
1.29 MiB
Downloads
58 downloads
File comment
UniPCemu after receiving the 0xFF 8042 command.
File license
Fair use/fair dealing exception

It runs until reaching segment 4000h.

Edit: Hmmm... The interesting stuff starts at f000:0000efa5, where it will start to copy 64K of data from address e0000h(the start of the BIOS ROM) to adress 10000h, making a simple copy of it in lower RAM at f000:0000efa7.
That seems to be mostly zeroes?
So, looking at it running, f000:0000efa0 contains a simple routine for block copying 64K of data from ds:si to es:di.

So, having copied the full 128K of BIOS ROM to lower memory, it reaches f000:000071e6.
It then jumps to the BIOS copied to lower RAM, at 2000:000071eb, which is immediately past the RETF, but the BIOS running from segment 2000h instead and the BIOS ROMs having been relocated/copied to segment 1000h-2FFFh from segment E000h.
At 2000:000071ec, an PIT0 IRQ seems to have intervened.
Edit: Nope. That's just the previous RETF to segment 2000h.
It then returns for some more.
At 2000:00000b8e, it might be the start of the BIOS decompressing routine?
It starts by CLI(to prevent BIOS interrupts), then clearing 3E8 words at address 40000h, so a total of 2000 bytes.
AX is set to F3F7 just before (at 2000:000013f9), which is stored in said memory. So that's the cause of the invalid instructions that are executing. Now, why is such data left in that place or jumped to incorrectly?
It fills the next byte of RAM with a CBh value, so at 47D00, at location 2000:00001403.
It then restores AX to F3F7, decreases it for F3F6(opcode F6F3?) for 3E8 words(7D0 bytes again) at address 40800h with said value.
Perhaps it's some table of some kind?
So then it finishes it up with another CBh value at 40FD0.
It then reaches 2000:00001414.
It sets 4f804(data segment offset f804h) to the value of port 61h's read value(=20h).
It then clears bit 0&1 of port 61h(the PC speaker output line mask and gate).
It sets PIT timer 2(the PC speaker) to 18.2Hz and returns to the caller.
It then turns on the timer by setting the gate at port 61h to 1?
It then calls the just initialized 4000 segment directly?

Is it just some obscure way to set some timer in a weird way?
So it's deliberately executing DIV BX 2024 times and then performing an RETF to the calling segment? BX=FFFFh at that point, so it won't fault.
Said call happens at 2000:000014a2.
Edit: It indeed returns from said function, reaching 2000:000014a7.
It then stops the PC speaker gate(timer 2 gate) by clearing it again. And jumps to 2000:000014b0.
It stores the PC speaker counter after being negated using NEG(which was starting at 0h), becoming 18Fh, at address 4f800h.
It then stores port 61h's value(30h) at address 4F804h. It then does the same counter with address 4000:0800h(the second block it created, with the same size). This time returning to 2000:000014CD.
That block once again returns 18Fh as a result after negating the PIT2 timer's clock.
It then substracts that calculated value(18Fh) from the value stored at 4f800(thus clearing it).
It did something with segment F000h, after which it called the 4000h segment once again, timing it.
It's once again resulting in a value of 18Fh. And then calls the routine at 4000:800h again. It ends up at 2000:000014CD again?

So it seems to be pretty much infinitely calling the block of code again?
It seems to be comparing the timings between the two blocks of execution somehow? This seems to go on pretty much infinitely?

So it's comparing DIV BL timing (the higher block at 40800h) against DIV BX timing (the lower block at 40000h). And they always execute equally fast, causing the infinite loop?
It seems to store it in some table? It's looping around calculating the DIV BL vs DIV BX timing differences?
Edit: It seems to do some math on the calculated speed. At 2000:0000146f, it doesn't jump 10 bytes ahead(the comparison against some constant wasn't equal. SI=9D98).
It then clears the memory it just used with zeroes.
It sends 24h to port 80h. So it's reached the next step?
Edit: It fills the IVT with F000:5E40 entries and reaches 2000:0000719E.
It seems to be initializing the IVT, but doing so from segment 2000h still?
It seems to finish, then send 25h to port 80h(that's probably some kind of diagnostics port, like Compaq also uses)?
Edit: It sets the initial video mode to 3 in the BDA (at 2000:BC6). It then updates the POST code to 27h. Then some more calling, resulting in it becoming 28h.

Interesting: the first interrupt is called: interrupt 10h function 07h, from 2000:00000be1. That resolves to F000:F065, which is the BIOS video interrupt handler? Why isn't the VGA BIOS used?
Edit: The i430fx handles the video interrupt and returns.
It then requests video mode 01h to be set by the BIOS.

Edit: OK. It looks like it's somehow programming the ET4000 like a CGA for some reason? Why doesn't it use the ET4000 BIOS ROM?
Edit: OK. It copies the BIOS ROM from lower memory back to the mapped write(read=PCI) RAM at F000:0000.
It then switches it back to read=RAM, write=PCI(register 59h=1Fh).
It eventually returs to the BIOS at 2000:71F5 to F000:71F6. So the BIOS should be ready for use, with it being remapped to lower RAM.
It sets the POST to code 2Ah and reaches F000:00000C0A.

Author of the UniPCemu emulator.
UniPCemu Git repository
UniPCemu for Android, Windows, PSP, Vita and Switch on itch.io

Reply 7 of 71, by superfury

User metadata
Rank l33t++
Rank
l33t++

Well, at least it's returning from segment 2000 to segment F000, but somewhere after that(I see it doing some kind of I/O port check on the parallel port), it issues a reset once again eventually.

Just fixed the PIIX class fields to report correctly, while making the IDE controller report not supporting bus mastering yet(bit 7 not set).

One good thing I also see is that it's checksumming the CMOS, which seems to get a OK from the BIOS.

OK. I see it keeps writing 01h to port 279h. But no second parallel port is emulated?
Edit: Then I see it reading port 223h(the sound blaster card)?
Edit: The last PCI address register accessed was 800003920h. Then it writes 8000f800h to port CF8 and resets the system this way(CPU and PCI i430's 5Fh register being reset only).
Perhaps that's a clue as to what's going wrong?
Edit: Interesting. I see it going down from above 80009800 down to 0 in multiples of 0x800.
I see it reaching 80000800, which resolves as the PIIX ID registers!
Edit: It reads the Header Type(0x80). Immediately after that, it writes a PCI address of 80000f00, causing a PCI hard reset to occur? Is this supposed to happen during a 32-bit PCI write.

OK. It seems to have been a mistake with the PCI configuration space method #1. When it was detecting the number of functions of the PIIX PCI device, it was checking the first, then the last. This caused the PCI to change bit 2 of the PCI address register to be raised, causing the emulator to think it required a hard reset(the second byte transferred went from 0x8 to 0xF!). While in fact, it wasn't requesting any. It should only perform such a reset apparently, when a direct request by the CPU is made to port 3C9 specifically, without any other ports? So port 3C8-3CB for a dword transfer doesn't have such an effect!

Edit: Yay! After having fixed that, I finally see the BIOS displaying stuff on screen! 😁

Author of the UniPCemu emulator.
UniPCemu Git repository
UniPCemu for Android, Windows, PSP, Vita and Switch on itch.io

Reply 8 of 71, by superfury

User metadata
Rank l33t++
Rank
l33t++

It seems to get to POSTing, but not booting yet? It also says only 640KB base memory and no Ext. Memory Size is detected(both in the memory count and the screen displaying the hardware is). It says:

Base Memory Size : 640KB
Ext. Memory Size : 0KB

It also says the display type is an EGA/VGA(which is roughly correct: it's an Tseng ET4000AX that's emulated).

The machine currently has 16MB RAM installed. Perhaps an issue with memory detection?

Edit: The HDD(two HDD drives) seem to be setup using PCI for port 170/370 and secondary for port FFE4 and FFE0?

Edit: Interestingly, it seems to be executing some code at segment 2000h again after the BIOS has cleared the screen and shows the AMIBIOS System Configuration?
Edit: Said BIOS after configuration(just normal motherboard settings without anything fancy) now reports there are 'Resource conflicts' directly before the visible memory check?

Author of the UniPCemu emulator.
UniPCemu Git repository
UniPCemu for Android, Windows, PSP, Vita and Switch on itch.io

Reply 9 of 71, by superfury

User metadata
Rank l33t++
Rank
l33t++

Found a small bug in the upper memory(A0000-FFFFF) memory map. It managed to include the 100000h address, while it should've stopped at FFFFFh, causing address 100000h to be mapped to nothing! That might explain the memory count only returning 640K of RAM (while 16MB is installed to test).

Edit: After testing said bugfix, it at least now properly detects 16000K of RAM during the memory test 😁

Edit: It only seems to see 16MB of RAM, even with 32MB installed? Perhaps an issue with the 16MB memory hole?

Author of the UniPCemu emulator.
UniPCemu Git repository
UniPCemu for Android, Windows, PSP, Vita and Switch on itch.io

Reply 10 of 71, by superfury

User metadata
Rank l33t++
Rank
l33t++

One interesting thing I see happening: when I set the Onboard Triton IDE to Primary, Secondary or Both, it will give a Resource Conflict error. When setting it to Disabled, it won't give any such error?

Author of the UniPCemu emulator.
UniPCemu Git repository
UniPCemu for Android, Windows, PSP, Vita and Switch on itch.io

Reply 11 of 71, by superfury

User metadata
Rank l33t++
Rank
l33t++

OK. Having the Onboard Triton IDE set to , with the 8042 command 0xFF to do nothing again(instead of giving 0x52, which is counted as INS being pressed, making it enter the BIOS always) it now gives the following info:

16000KB OK

WAIT...

Pri Master HDD Error
Pri Slave HDD Error
Sec Master CDROM Drive - ATAPI Incompatible
Sec Slave CDROM Drive - ATAPI Incompatible
Cache Memory Error

RUN SETUP
Press F1 to Resume

Author of the UniPCemu emulator.
UniPCemu Git repository
UniPCemu for Android, Windows, PSP, Vita and Switch on itch.io

Reply 12 of 71, by superfury

User metadata
Rank l33t++
Rank
l33t++

After implementing the DRBA values from Bochs for the different memory sizes, it gave a setting error once, then after clearing the CMOS it still detected 16MB RAM only, even with the new DRBA values loaded when they're written (128MB).

Although when disabling the IDE and enabling all other hardware it won't detect the HDD/CD-ROM anymore, but does boot the floppy drive correctly 😁

Author of the UniPCemu emulator.
UniPCemu Git repository
UniPCemu for Android, Windows, PSP, Vita and Switch on itch.io

Reply 13 of 71, by superfury

User metadata
Rank l33t++
Rank
l33t++

After implementing the DRBA values from Bochs for the different memory sizes, it gave a setting error once, then after clearing the CMOS it still detected 16MB RAM only, even with the new DRBA values loaded when they're written (128MB).

Although when disabling the IDE and enabling all other hardware it won't detect the HDD/CD-ROM anymore, but does boot the floppy drive correctly 😁
Was able to run CheckIt! Diagnostics from there. All 16MB RAM checked out. But anything past that is undetected both by the BIOS and CheckIt!

Placing a simple software(in code) breakpoint(because Visual Studio is somehow very slow with conditional breakpoints on much addressed instructions), I somehow see that the memory address is weirdly substracted with a large (0x40000000) address before being compared against the installed RAM size and being valid. Because address 0x1000000 then maps to real memory address 0xC1000000, which is past 0x2000000(32MB RAM installed), it counts said address and up as invalid RAM? That's not supposed to happen, so there's some error in the memory module itself when addressing more than 16MB RAM? It's not supposed to substract anything in this case(until the 3GB barrier at least)!

So I just fixed the third memory block(from 16MB to 3GB) to behave properly, and the writes past 16MB(past address 0xFFFFFF) should now properly end up in RAM!

Edit: Yay! It now properly detected 32384KB of RAM!
It now properly detects 31744KB extended RAM! 😁
So it's finally detecting all RAM now! 😁

Author of the UniPCemu emulator.
UniPCemu Git repository
UniPCemu for Android, Windows, PSP, Vita and Switch on itch.io

Reply 14 of 71, by superfury

User metadata
Rank l33t++
Rank
l33t++

Somthing that somehow still needs fixing is the i430fx's PCI IDE hardware. For some reason, it won't handle the I/O ports correctly it seems? The primary port(BAR0 and BAR1) are set to 171h and 375h for the primary IDE drive, while secondary port(BAR2 and BAR3) are set to FFE1h and FF9Dh.

Shouldn't those normally be set to 1F0/3F4(BAR0/1), 170/374(BAR2/3)? For a PC compatible interface?

Author of the UniPCemu emulator.
UniPCemu Git repository
UniPCemu for Android, Windows, PSP, Vita and Switch on itch.io

Reply 15 of 71, by superfury

User metadata
Rank l33t++
Rank
l33t++

Now running Memtest86 from a boot floppy on the i430fx. It's almost at 50% of test #7(total 48% so far). No memory errors are reported.

Now, why does the IDE controller not work? Anyone knows more about the i430fx IDE controller's workings? Why can't it handle it properly(it's based on the osdev article on it(a generic PCI IDE adapter documentation))?

Edit: The Memtest86 application has just completed it's memory checking and checks out without errors(1 pass), apparently.
So the memory seems to have no errors in it's emulation?

15-Memtestcompleted.jpg
Filename
15-Memtestcompleted.jpg
File size
58.66 KiB
Views
2077 views
File comment
Memtest86 completed it's checks without errors.
File license
Fair use/fair dealing exception

Author of the UniPCemu emulator.
UniPCemu Git repository
UniPCemu for Android, Windows, PSP, Vita and Switch on itch.io

Reply 16 of 71, by superfury

User metadata
Rank l33t++
Rank
l33t++

I've been reading through the i430fx piix manuals, and I've found two possible settings which may affect the decoding of the IDE 1F0/3F4,170/374 addresses:

PCICMD(PCI command register 04h) bit 0: 1=Enable I/O space registers
Register 41h bit 7: Primary channel: 1=PCI positive decode, 0=ISA substractively decode
Register 43h bit 7: Secondary channel: 1=PCI positive decode, 0=ISA substractively decode

Anyone can tell me more about what those settings do exactly? How do they affect the addresses set in the BAR0-3(defaulting to 1F0/3F4 and 170/374 when set to 0(16-bit registers containing a 14-bit value to use(lower bits are always 01b))) and BAR4-5(which isn't implemented)?
As far as I understand from osdev, the value in the BARs have their defaults when set to 0, but said values when set to any non-zero value(upper 14 bits non-zero only)?

Edit: Just found the PCI IDE controller specification at the bottom of https://wiki.osdev.org/PCI_IDE_Controller (https://www.bswd.com/pciide.pdf).
I then implemented the special bits in the PCI IDE ProgIF byte(byte #9 of the configuration space).
So it should properly support that now(with the added functionality of moving the secondary controller to use the first PCI settings when the first is in compatiblity mode and the second controller is in PCI mode).
It now also allows disabling the PCI IDE controller (minus the interrupts, which aren't configurable yet, mainly due to lack of PCI IRQ(M) emulation). The IDE DMA Busmastering controller also isn't emulated (yet).

Author of the UniPCemu emulator.
UniPCemu Git repository
UniPCemu for Android, Windows, PSP, Vita and Switch on itch.io

Reply 17 of 71, by superfury

User metadata
Rank l33t++
Rank
l33t++

Just triend Hiren's bootCD 7.8 CD-ROM on the newly emulated hardware with i430fx motherboard emulation and the 5728P ROM (Apollo S728P Pentium I motherboard).

It booted without visible issues on the newly improved PCI IDE hardware with Plop boot ROM installed.

It manages to extract and start the Eurosoft PC-Check testsuite for a bit, only to end up hanging because it's waiting for the BDA offset 6C(Daily timer counter, equal to zero at midnight; incremented by INT 8), but it will never overflow and always get a difference (what it's waiting for) of 0 ticks, because interrupts are disabled(The interrupt flag is cleared)?

It's in protected mode with paging enabled, at a loop at 218D:B80D in Virtual 8086 mode. Pentium's VME extensions aren't enabled, so it's in a normal 80386-compatible V86 mode.

Now the question: why is it in Virtual 8086 mode waiting for something that obviously never happens because interrupts are disabled?

Last edited by Stiletto on 2020-08-11, 00:43. Edited 1 time in total.

Author of the UniPCemu emulator.
UniPCemu Git repository
UniPCemu for Android, Windows, PSP, Vita and Switch on itch.io

Reply 18 of 71, by superfury

User metadata
Rank l33t++
Rank
l33t++

Now, PC-Doctor from that test suite CD-ROM says that the IRQ controller (which is probably the PIC)'s Poll command failed?

Author of the UniPCemu emulator.
UniPCemu Git repository
UniPCemu for Android, Windows, PSP, Vita and Switch on itch.io

Reply 19 of 71, by superfury

User metadata
Rank l33t++
Rank
l33t++

Added some new features since the last post:
- Improved PS/2 mouse and keyboard responses a bit(enable/disable port, reset and power-on behaviour). BAT response for PS/2 mouse isn't sent anymore(causes BIOS hang).
- Implemented 8259 PIC polling mode.
- Improved i430fx reset PCI configuration space defaults.
- Implemented i430fx PIIX and PIIX IDE command and status register behaviour, according to the manual.
- Implemented i430fx PIIX command register bit 3 to affect the special cycles(in this case: the CPU shutdown cycle is ignored and the CPU is hanged when it's cleared).

The i430fx Pentium BIOS now detects the secondary master/slave CD-ROM drives without visible issues(although it displays the slave as a HDD when booting?).
It now reports "Pri Master HDD Error" when booting and asking for F1 to be pressed? Triton IDE settings are setup for "Both".

Author of the UniPCemu emulator.
UniPCemu Git repository
UniPCemu for Android, Windows, PSP, Vita and Switch on itch.io