VOGONS


IBM PC AT emulation crashing?

Topic actions

Reply 100 of 151, by superfury

User metadata
Rank l33t++
Rank
l33t++

I've modified UniPCemu's CMOS to now be moved to the main thead(which contains CPU timings, as well as other cycle accurate hardware timings). It now creates a '128kHz' signal (65536Hz square wave). This is divided by the two clocks on the CMOS chip (as specified by Status Register A) to generate periodic interrupts and square wave output(not connected on PCs?). It's used directly for updating the time values in the RTC(based on real timing), as well as any interrupts that result from any updating (Update Ended Interrupt and Alarm Interrupt). Thus time is updated at a rate of 65536Hz('128kHz' divided by 2), the other different signals are the results of the 128kHz signal (in the case of the Square Wave generator) directly.

Strange enough, when I try to boot with my normal hard disk image, the BIOS just hangs when reaching the point to boot drive C?

I see it properly executing the interrupt 13h read boot sector call, but it doesn't seem to return from it properly?

So it doesn't seem to finish that call for some reason?

Edit: It seems to end up at the 0xFFFF undefined instruction again (GRP 5 opcode /7 when decoded, which doesn't exist on any x86 CPU, according to http://ref.x86asm.net/coder32.html#xFF ). This time I've gotten a log with all the instructions executed from the first INT 19 up to the #UD instruction, which locks the entire BIOS into an endless loop.

https://www.dropbox.com/s/qypl9oitt1p98ho/deb … 0_1150.zip?dl=0

Looking at the RETN return address reveals that it's return address is actually overwritten with the address of an #UD instruction?

I also see this (seemingly infinite) instruction being executed over and over until just before the #UD(which seems to be the cause for some reason):

00:06:32:58.03808: Writing to memory: 000AF807=12 ()
00:06:32:58.03872: Writing to memory: 000AF808=1C ()
00:06:32:58.03904: F000:1C0F (E863FD)CALL 1975
00:06:32:58.03904: Registers:
00:06:32:58.03968: AX: FF00, BX: FFFF, CX: 006D, DX: 0000
00:06:32:58.04000: CS: F000, DS: 9FC0, ES: 07C0, SS: 9FC0
00:06:32:58.04064: SP: FC09, BP: FE11, SI: 1058, DI: 01F1
00:06:32:58.04096: IP: 1C0F, FLAGS: 0046
00:06:32:58.04160: FLAGSINFO:c1P0a0Zstido00n0
00:06:32:58.04224: Interrupt status: 0000000000000000
00:06:32:58.04256: VGA@88,303(CRT:115,337)
00:06:32:58.04288: Display=801,446

Looking at the INT calls before it, the last INT was an INT13h request to read the boot sector from the first harddrive:

00:06:32:15.02960: Writing to memory: 00007EF8=46 (F)
00:06:32:15.03024: Writing to memory: 00007EF9=02 ()
00:06:32:15.03088: Writing to memory: 00007EF6=00 ( )
00:06:32:15.03120: Writing to memory: 00007EF7=C6 (Æ)
00:06:32:15.03152: Writing to memory: 00007EF4=CF (Ï)
00:06:32:15.03216: Writing to memory: 00007EF5=0B ()
00:06:32:15.03248: C600:0BCD (CD13)INT 13
00:06:32:15.03248: Registers:
00:06:32:15.03344: AX: 0201, BX: 7C00, CX: 0001, DX: 0080
00:06:32:15.03376: CS: C600, DS: 9FC0, ES: 0000, SS: 0000
00:06:32:15.03440: SP: 7EFA, BP: 7EF2, SI: 00F8, DI: 0003
00:06:32:15.03472: IP: 0BCD, FLAGS: 0246
00:06:32:15.03504: FLAGSINFO:c1P0a0ZstIdo00n0
00:06:32:15.03600: Interrupt status: 0000000000000000
00:06:32:15.03632: VGA@599,249(CRT:626,283)
00:06:32:15.03664: Display=801,446

Anyone can see what's going wrong?

Edit: Looking at the disassembly I see something strange:

00:06:32:21.00624: Writing to memory: 0009FFD8=B2 (²)
00:06:32:21.00688: Writing to memory: 0009FFD9=00 ( )
00:06:32:21.00720: C600:15FC (68B214)PUSH 00B2
00:06:32:21.00752: Registers:
00:06:32:21.00784: AX: 2001, BX: FF08, CX: 0001, DX: 0080
00:06:32:21.00848: CS: C600, DS: 9FC0, ES: 0000, SS: 9FC0
00:06:32:21.00880: SP: 03DA, BP: 03DA, SI: 7C00, DI: 0018
00:06:32:21.00912: IP: 15FC, FLAGS: 0256
00:06:32:21.00976: FLAGSINFO:c1P0A0ZstIdo00n0
00:06:32:21.01040: Interrupt status: 0000000000000000
00:06:32:21.01072: VGA@870,256(CRT:0,290)
00:06:32:21.01104: Display=801,446

The disassembly and stack push tells me the immediate operand was 00B2, so the instruction bytes should be 68B200. But the instruction actually reads 68B214, which is a "PUSH 14B2" instruction? This doesn't match the disassembly nor the data pushed on the stack?

Looking at the Visual C++ debugger:

void CPU186_OP68()
{
word val = immw; //PUSH Iz
debugger_setcommand("PUSH %04X",val);
CPU_PUSH16(&val);
}

immw contains 14B2, which matches the instruction read from memory. But val contains 00B2? So all other places use the value 00B2 instead of 14B2? Is this the Visual Studio profiler messing with stuff?

Edit: Looking at the top of the 80186/NEC V20/V30 core:

extern byte immw; //Immediate word!

All other locations using that same variable (which is shared among all CPU cores):

extern word immw; //Immediate word!

Strange enough, the Visual C++ compiler won't complain that the value isn't linked correctly(it doesn't exist in that form anywhere) and just silently and happily truncates it when read at any point. It does show the full value in the debugger though(16-bits unsigned integer)?

Edit: Having fixed this bug, it now seems to properly start booting! It reads the first sector from the hard disk to 0000:7C00(actually 7C0:0) and jumps to it. Now the boot sector properly starts executing it's instructions! 😁

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

Reply 101 of 151, by superfury

User metadata
Rank l33t++
Rank
l33t++

Now, even though the boot sector is correctly loaded and starting to run, it will trigger a hard reset(cold reboot) for some reason. Anyone knows what's going wrong? The XT with XT-IDE and Generic Super PC/Turbo XT BIOS work without problems, the AT simply reboots after jumping and starting the boot loader program from the hard disk?

Edit: This is the dump of the boot loader executing (right after it's first STI instruction, at 0000:7C01):
https://www.dropbox.com/s/118ate9z45hw1i2/deb … 0_1445.zip?dl=0

It also contains the floppy disk log made during debugging. Anyone can see what's going wrong?

Edit: I've made an improved log using the latest UniPCemu commit:
https://www.dropbox.com/s/eqa09bt5z0i99vu/deb … 1_1147.zip?dl=0

This adds logging and debugger information generation and improved display of all registers in both real and protected mode (adding Control register and debug registers, as well as CPU reset support(R reporting instead of a H for HLT state. This is put at the end of the flags state) of 80286 and 80386+ CPU emulation.

Anyone can see what's going wrong here?

Edit: Looking at the log file with LogExpert, it seems to show the last interrupt fired was:

C600:0CCA (CD15)INT 15
Registers:
AX:86F6 BX:0051 CX:0000 DX:0006
CS:C600 DS:9FC0 ES:0000 SS:9FC0
SP:03C6 BP:03DA SI:15CD DI:0018
IP:0CCA, FLAGS:0246
CR0:FFF0
FLAGSINFO:c1P0a0ZstIdo00n0
Interrupt status:0000000000000000

Thus this might be that timing function failing to work somehow? It's at line 17165 of the log file(the 00:07:24:15.02960(The format is hour:minute:second:100thsecond.nanoseconds).

I've made a new log file which also logs interrupts and traps interrupts fired:
https://www.dropbox.com/s/50prlwwyq5vri2l/deb … 1_1515.zip?dl=0

It looks like IRQ8 does fire once, but it isn't acnowledged(the places where "HW interrupt: 70" is logged before the first instruction of the handler)? Anyone? Shouldn't CMOS register C to be able to raise new CMOS interrupts(IRQ8)? Acnowledging and lowering the IRQ8 is done by reading status register C? That also clears it's bits 4-6(and with ~0x70)?

Edit: Just tried again with modified CMOS bit 7 (register C). It now continues running until crashing on a line at line 8564 with an INT 13 call at C600:14CD to a bogus entry point (F000:EC59, which contains bytes FFFF, which causes an infinite and corrupted loop it seems(GRP5 /7 doesn't exist, execute interrupt 6(#UD), which crashes the whole boot loader(or MS-DOS in general). It's commit 2016/10/11 16:59.

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

Reply 102 of 151, by superfury

User metadata
Rank l33t++
Rank
l33t++

This is the latest log of commit 2016/10/11 16:59
https://www.dropbox.com/s/8yxgupodcw5g5rr/deb … 1_1659.zip?dl=0

The location of the error is posted at the previous post's end. Anyone can see what's going wrong here? Jepael?

Btw warning: the log file is huge(1.08GB of pure MS-DOS line-ending&ASCII text). Be careful trying to open it with Wordpad or Notepad(Notepad will priodically hang for every little thing you do, Wordpad is slow as well. I'm using LogExpert to view it).

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

Reply 103 of 151, by superfury

User metadata
Rank l33t++
Rank
l33t++

Looking at the log, it seems the RTC timer times out immediately after a STI instruction is executed? How does timing on a real CMOS chip work? Is it simply a counter that's counting down from the value set, or does it count up until it gets at the value set, which then resets and fires an IRQ8? Does clearing and/or setting the various interrupt bits affect this timer in any way? Does clearing the timer bit (e.g. bit 6 of register B) reset the counter of that timer?

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

Reply 104 of 151, by Jepael

User metadata
Rank Oldbie
Rank
Oldbie
superfury wrote:

Looking at the log, it seems the RTC timer times out immediately after a STI instruction is executed? How does timing on a real CMOS chip work? Is it simply a counter that's counting down from the value set, or does it count up until it gets at the value set, which then resets and fires an IRQ8? Does clearing and/or setting the various interrupt bits affect this timer in any way? Does clearing the timer bit (e.g. bit 6 of register B) reset the counter of that timer?

Based on your questions, you need to read the RTC datasheet.
It's not a timer as you might think of it (a counter?). It is a real time clock, like one on the wall.

It runs with battery, with 32768Hz watch crystal, and with the control registers you control if you want alarm interrupts, time update interrupts and periodic interrupts.

Reply 105 of 151, by superfury

User metadata
Rank l33t++
Rank
l33t++

But the time, like on the wall, runs at 1Hz, but the periodic interrupt can be set at a rate up to 32 kHz with something called a 22-stage divider?

Also is the square wave output connected to anything?

Edit: According to https://www.google.nl/url?sa=t&source=web&rct … nr-CIoyKtoFxYVA it's simply 22 flipflops that are placed serially to each other(and read in parallel), each stage dividing the input signal by 2(stage 1 divides by 2, stage 2 divides stage 1 by 2, stage 3 divides stage 2 by 2 etc). Thus the 22-stage counter is essentially a 22-bit binary number that keeps incrementing and rolling over? And the number set at the low 4 bits of register A are simply the amount of bits that must roll over to 0 to trigger an IRQ8(Starting from the LSB)? Thus setting it to 1 makes it trigger an interrupt if bit 0 rolls over to 0? Thus every 2 65536Hz ticks? So register A basically specifies the bit number(+1) that needs to roll over to 0 to trigger an IRQ8?

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

Reply 106 of 151, by superfury

User metadata
Rank l33t++
Rank
l33t++

I've modified the CMOS chip to use a '23-bit' counter to emulate a 22-bit counter(with one extra bit used for generating a 64kHz signal(65536 state changes per second for a 32kHz square wave) to drive the 32kHz square wave). The Periodic Interrupt divides this signal by 2(essentially shift left the bit used to check for interrupts and state changes by 1 to run at half the speed).

Now MS-DOS boots properly? Eventually I tried booting Windows 3.0(although it still seems to use Real mode instead). Trying to get system information by opening the About program manager dialog it seems to crash Windows.

Edit: Just trying to run the data from the IBM Setup disk (settup program) from MS-DOS 5.0(floppy disk is still non-functional afaik). It clears the screen and shows the cursor at the top left, then does nothing anymore?

Edit: Trying to run DOTT.EXE(Day of the Tentacle) brings up the Setup menu. I enter settings and press escape to try to save and quit, it brings up the confirmation dialog and then doesn't repond anymore?

Edit: Just restored a copy of the old system hard disk image. It now boots correctly again and works without problems on NEC V30 XT configuration. But when selecting 80286 AT configuration, all valid system commands executed executed in the MS-DOS prompt cause a "Divide overflow"? Also trying to execute play.exe and then sbfmdrv locks the system up at the command prompt directly after it(keyboard messes up it seems, as it's still slightly reponsive). Trying to load software from the second mounted hard disk gives "Cannot execute D:\DOTT\DOTT.EXE"? Anyone can see what's going wrong?

https://bitbucket.org/superfury/unipcemu.git

24.jpg
Filename
24.jpg
File size
60.44 KiB
Views
928 views
File comment
Error after every MS-DOS command, if it succeeds at all.
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 107 of 151, by Jepael

User metadata
Rank Oldbie
Rank
Oldbie
superfury wrote:

But the time, like on the wall, runs at 1Hz, but the periodic interrupt can be set at a rate up to 32 kHz with something called a 22-stage divider?

Not on a PC, because it runs at 32kHz crystal, you can't reach 32kHz periodic interrupt rate. (The datasheet would tell the timings and how it works when using a 32kHz crystal).

superfury wrote:

Also is the square wave output connected to anything?

No, CKOUT and SQW are not connected (but that info would be in AT schematics).

Besides, this works wit 32kHz tick rate, so there's no point emulating a 64kHz tick rate first.

Reply 108 of 151, by superfury

User metadata
Rank l33t++
Rank
l33t++

Not quite: if I'm using a 32kHz tick rate to emulate the Square Wave output, it can only process 32768 changes per second, so only up to a 16kHz square wave(https://en.wikipedia.org/wiki/Nyquist%E2%80%9 … ampling_theorem). It needs at least double the square wave frequency sampled(64kHz) in order to create the square wave without errors at 32kHz(which needs 64kHz sampling frequency). When a 32 kHz signal is generated on a 32 kHz sampling rate, the result would be always 1 or always 0(depending on what point sampling starts). Since sampling starts at 0 with an output of 0 it would never become 1(which timepoint is at every half sample, which is impossible in sample based generation, every whole sample will have 0, thus it's always zero).

t = SQUAREWAVE[32MHz]
t output
0 0
0.5 1
1.0 0
1.5 1
2.0 0
2.5 1

Thus output is:
t output
0 0
1 0
2 0
etc.

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

Reply 109 of 151, by Jepael

User metadata
Rank Oldbie
Rank
Oldbie

Well, my main point was, since the SQW and CKOUT outputs are not used (they are not connected to anything), so does it really make sense to use host CPU resources to simulate unused stuff? (Simulating it in hardware like FPGA would come almost free so there could be a debug output for that...)

Since RTC chip runs with 32kHz clock, the SQW pin has anyway max 8kHz rate, not 32kHz, and the CKOUT would be 32kHz on a PC. The periodic interrupt rate is also max 8kHz.

If yes, I see your point about Nyquist - you need to toggle at 64kHz to generate 32kHz, and 32kHz is anyway needed for emulation of RTC, no doubt about that, so do as you wish 😀

Reply 110 of 151, by superfury

User metadata
Rank l33t++
Rank
l33t++

Even so, any clue what might cause the command prompt to fail? Trying to execute any programs will give errors(it won't start the program). Using dir on any directory makes it print the directory, then finish with a divide overflow(see screen capture). Anyone knows what might cause the divide overflow?

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

Reply 111 of 151, by superfury

User metadata
Rank l33t++
Rank
l33t++

Well, now the divide error and hardware interrupts are fixed(there was a problem with the keyboard handling, as well as the way interrupts were detected and processed, causing an invalid IRQ to become interrupt 0h, which is the divide by zero exception, causing the division errors). This also fixes some hard disk problems.

The problem still left is that software (I'm testing with Day of the Tentacle) is simply crashing. It doesn't respond to any input. MS-DOS 5.0 starts without problems (although the XT-IDE AT BIOS seems to do something on the floppy, which is incorrect). The DOTT setup menu starts correctly, although it uses the wrong Sound Blaster IRQ (IRQ 7 instead of 5 used in the emulator). Trying to change it to 5 and exit saving changes causes the program to hang?

Edit: Eventually, confirming the change of the IRQ to IRQ5(instead of 7) brings up the "Not ready writing drive D" prompt in the middle of the program:

27-DOTT_NotReadyWritingStorageDrive.jpg
Filename
27-DOTT_NotReadyWritingStorageDrive.jpg
File size
124.12 KiB
Views
838 views
File comment
Drive not ready writing the settings to the program?
File license
Fair use/fair dealing exception

So that means there's a problem with my IDE hard disk emulation?
https://bitbucket.org/superfury/unipcemu/src/ … ide.c?at=master

Can anyone see what might be going wrong? Why does MS-DOS think the drive isn't ready?

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

Reply 112 of 151, by superfury

User metadata
Rank l33t++
Rank
l33t++

There might be a problem with the commandstatus(current read/write command state) and/or STATUSREGISTER(Drive status register)? Anyone can see if there's something wrong there(Set incorrectly etc)?

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

Reply 113 of 151, by superfury

User metadata
Rank l33t++
Rank
l33t++

I've just tried to run the DSETTUP.COM from MS-DOS 5.0 (not booted from the 360K floppy disk) on the hard disk. It crashes executing opcode 65h(GS segment prefix)? This doesn't exist on the 80286 CPU, or does it? It's executing at 0000:0436(Real mode). Trying to run DDIAG.COM executes opcode 64h(FS segment prefix)? These don't exist on a 80286?

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

Reply 114 of 151, by superfury

User metadata
Rank l33t++
Rank
l33t++

According to https://www.google.ch/patents/US5822778 the 80286 uses the FS and GS segments (just like the 80386), even though most documentations (like http://ref.x86asm.net/coder32.html#x65 ) mark the instructions prefixes as 80386+? I've modified the CPU core to use and allow the FS and GS prefixes, as well as handle invalid modr/m parameters(reg=7 on segment registers). Thus FS and GS should now work, even on the 80286. Invalid ModR/M instructions will now be handled on a 80186+. The 808X still ignores them.

Edit: I've implemented the FS and GS registers on the 80286 emulation. 32-bit operand and address size overrides are still 80386+ only. Strange enough, tring to execute DIAGS.COM tries to execute one of the address size prefixes, thus #UD is fired, which gets into an infinite loop by returning to the opcode triggering #UD infinitely.

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

Reply 115 of 151, by superfury

User metadata
Rank l33t++
Rank
l33t++

With the latest registers applied, DOTT showing the save confirmation now, but becomes unresponsive, due to some loop reading port 0007(DMA channel 3 word count)? So it's waiting for some DMA channel 3 device, which isn't connected on my AT emulation?

According to https://www.manualslib.com/manual/75265/Ibm-C … 2.html?page=151 it's the parallel port?

It seems to be waiting for the timer to clear/set the count? But the count won't advance, since there's nothing connected?

Edit: I seem to have the disk mounted as read-only, thus all writes (one write it seems) to sector 65 fails.

Edit: Having modified the configuration to use IRQ5 using Dosbox, then stating the game again on UniPCemu, it gets to some 0xFFFF instruction once again:

00:06:04:22.00736: Read from memory: 0003C8CF=A3 (£)
00:06:04:22.01312: Read from memory: 0003C8D0=CB (Ë)
00:06:04:22.01312: F000:1C1D (58)POP AX
00:06:04:22.01312: Registers:
00:06:04:22.01312: AX: FF00, BX: 14AF, CX: 0000, DX: 0000
00:06:04:22.01344: CS: F000, DS: 0000, ES: A000, SS: 3867
00:06:04:22.01344: SP: 425F, BP: 6244, SI: 0003, DI: 000A
00:06:04:22.01344: IP: 1C1D, FLAGS: 0046
00:06:04:22.01344: CR0: FFF0
00:06:04:22.01344: FLAGSINFO:c1P0a0Zstido00n0
00:06:04:22.01344: Interrupt status: 0000000000000001
00:06:04:22.01344: VGA@202,75(CRT:234,109)
00:06:04:22.01376: Display=712,446

00:06:10:31.00720: Read from memory: 0003C8D1=40 (@)
00:06:10:31.00720: Read from memory: 0003C8D2=1D ()
00:06:10:31.00720: Read from memory: 0003C8D3=20 ( )
00:06:10:31.00752: Read from memory: 0003C8D4=00 ( )
00:06:10:31.00752: Read from memory: 0003C8D5=03 ()
00:06:10:31.00752: Read from memory: 0003C8D6=08 ()
00:06:10:31.01008: F000:1C1E (CF)IRET
00:06:10:31.01040: Registers:
00:06:10:31.01072: AX: CBA3, BX: 14AF, CX: 0000, DX: 0000
00:06:10:31.01072: CS: F000, DS: 0000, ES: A000, SS: 3867
00:06:10:31.01104: SP: 4261, BP: 6244, SI: 0003, DI: 000A
00:06:10:31.01104: IP: 1C1E, FLAGS: 0046
00:06:10:31.01104: CR0: FFF0
00:06:10:31.01136: FLAGSINFO:c1P0a0Zstido00n0
00:06:10:31.01136: Interrupt status: 0000000000000001
00:06:10:31.01168: VGA@243,75(CRT:274,109)
00:06:10:31.01168: Display=712,446

00:06:11:14.01632: Writing to memory: 0003C8D5=03 ()
00:06:11:14.01632: Writing to memory: 0003C8D6=08 ()
00:06:11:14.01632: Writing to memory: 0003C8D3=20 ( )
00:06:11:14.01632: Writing to memory: 0003C8D4=00 ( )
00:06:11:14.01664: Writing to memory: 0003C8D1=40 (@)
00:06:11:14.01888: Writing to memory: 0003C8D2=1D ()
00:06:11:14.01920: 0020:1D40 (FFFF)<NECV20/V30+ #UD>
00:06:11:14.01920: Registers:
00:06:11:14.01920: AX: CBA3, BX: 14AF, CX: 0000, DX: 0000
00:06:11:14.01952: CS: 0020, DS: 0000, ES: A000, SS: 3867
00:06:11:14.01952: SP: 4267, BP: 6244, SI: 0003, DI: 000A
00:06:11:14.01952: IP: 1D40, FLAGS: 0803
00:06:11:14.01952: CR0: FFF0
00:06:11:14.01952: FLAGSINFO:C1p0a0zstidO00n0
00:06:11:14.01952: Interrupt status: 0000000000000001
00:06:11:14.01984: VGA@247,75(CRT:278,109)
00:06:11:14.01984: Display=712,446

00:07:28:04.02048: Writing to memory: 0003C8CF=A3 (£)
00:07:28:04.02080: Writing to memory: 0003C8D0=CB (Ë)
00:07:28:04.02080: F000:1BD0 (50)PUSH AX
00:07:28:04.02080: Registers:
00:07:28:04.02080: AX: CBA3, BX: 14AF, CX: 0000, DX: 0000
00:07:28:04.02080: CS: F000, DS: 0000, ES: A000, SS: 3867
00:07:28:04.02336: SP: 4261, BP: 6244, SI: 0003, DI: 000A
00:07:28:04.02368: IP: 1BD0, FLAGS: 0803
00:07:28:04.02368: CR0: FFF0
00:07:28:04.02368: FLAGSINFO:C1p0a0zstidO00n0
Show last 290 lines
00:07:28:04.02368: Interrupt status: 0000000000000001
00:07:28:04.02400: VGA@407,75(CRT:438,109)
00:07:28:04.02400: Display=712,446

00:07:28:36.00704: Writing to memory: 0003C8CD=AF (¯)
00:07:28:36.00704: Writing to memory: 0003C8CE=14 ()
00:07:28:36.00704: F000:1BD1 (53)PUSH BX
00:07:28:36.00736: Registers:
00:07:28:36.00736: AX: CBA3, BX: 14AF, CX: 0000, DX: 0000
00:07:28:36.00736: CS: F000, DS: 0000, ES: A000, SS: 3867
00:07:28:36.00736: SP: 425F, BP: 6244, SI: 0003, DI: 000A
00:07:28:36.00992: IP: 1BD1, FLAGS: 0803
00:07:28:36.00992: CR0: FFF0
00:07:28:36.01024: FLAGSINFO:C1p0a0zstidO00n0
00:07:28:36.01024: Interrupt status: 0000000000000001
00:07:28:36.01024: VGA@465,75(CRT:496,109)
00:07:28:36.01056: Display=712,446

00:07:28:62.00736: F000:1BD2 (B00B)MOVB AL, 0B
00:07:28:62.00736: Registers:
00:07:28:62.00768: AX: CBA3, BX: 14AF, CX: 0000, DX: 0000
00:07:28:62.00768: CS: F000, DS: 0000, ES: A000, SS: 3867
00:07:28:62.00768: SP: 425D, BP: 6244, SI: 0003, DI: 000A
00:07:28:62.00768: IP: 1BD2, FLAGS: 0803
00:07:28:62.00768: CR0: FFF0
00:07:28:62.01056: FLAGSINFO:C1p0a0zstidO00n0
00:07:28:62.01088: Interrupt status: 0000000000000001
00:07:28:62.01088: VGA@486,75(CRT:518,109)
00:07:28:62.01088: Display=712,446

00:07:28:86.00736: F000:1BD4 (E620)OUT 20,AL
00:07:28:86.00768: Registers:
00:07:28:86.00768: AX: CB0B, BX: 14AF, CX: 0000, DX: 0000
00:07:28:86.00768: CS: F000, DS: 0000, ES: A000, SS: 3867
00:07:28:86.01024: SP: 425D, BP: 6244, SI: 0003, DI: 000A
00:07:28:86.01056: IP: 1BD4, FLAGS: 0803
00:07:28:86.01056: CR0: FFF0
00:07:28:86.01056: FLAGSINFO:C1p0a0zstidO00n0
00:07:28:86.01056: Interrupt status: 0000000000000001
00:07:28:86.01056: VGA@491,75(CRT:522,109)
00:07:28:86.01056: Display=712,446

00:07:29:10.00736: F000:1BD6 (EB00)JMP 1BD8
00:07:29:10.00736: Registers:
00:07:29:10.00768: AX: CB0B, BX: 14AF, CX: 0000, DX: 0000
00:07:29:10.00800: CS: F000, DS: 0000, ES: A000, SS: 3867
00:07:29:10.00800: SP: 425D, BP: 6244, SI: 0003, DI: 000A
00:07:29:10.00800: IP: 1BD6, FLAGS: 0803
00:07:29:10.00800: CR0: FFF0
00:07:29:10.01088: FLAGSINFO:C1p0a0zstidO00n0
00:07:29:10.01120: Interrupt status: 0000000000000001
00:07:29:10.01120: VGA@513,75(CRT:544,109)
00:07:29:10.01120: Display=712,446

00:07:29:34.01696: F000:1BD8 (E420)IN AL, 20
00:07:29:34.01696: Registers:
00:07:29:34.01696: AX: CB0B, BX: 14AF, CX: 0000, DX: 0000
00:07:29:34.01696: CS: F000, DS: 0000, ES: A000, SS: 3867
00:07:29:34.01728: SP: 425D, BP: 6244, SI: 0003, DI: 000A
00:07:29:34.01728: IP: 1BD8, FLAGS: 0803
00:07:29:34.01728: CR0: FFF0
00:07:29:34.01952: FLAGSINFO:C1p0a0zstidO00n0
00:07:29:34.01984: Interrupt status: 0000000000000001
00:07:29:34.01984: VGA@519,75(CRT:550,109)
00:07:29:34.01984: Display=712,446

00:07:29:57.05104: F000:1BDA (8AE0)MOVB AH,AL
00:07:29:57.05104: Registers:
00:07:29:57.05136: AX: CB00, BX: 14AF, CX: 0000, DX: 0000
00:07:29:57.05136: CS: F000, DS: 0000, ES: A000, SS: 3867
00:07:29:57.05136: SP: 425D, BP: 6244, SI: 0003, DI: 000A
00:07:29:57.05136: IP: 1BDA, FLAGS: 0803
00:07:29:57.05136: CR0: FFF0
00:07:29:57.05392: FLAGSINFO:C1p0a0zstidO00n0
00:07:29:57.05424: Interrupt status: 0000000000000001
00:07:29:57.05424: VGA@547,75(CRT:578,109)
00:07:29:57.05424: Display=712,446

00:07:29:87.05008: F000:1BDC (0AC4)ORB AL,AH
00:07:29:87.05008: Registers:
00:07:29:87.05040: AX: 0000, BX: 14AF, CX: 0000, DX: 0000
00:07:29:87.05040: CS: F000, DS: 0000, ES: A000, SS: 3867
00:07:29:87.05040: SP: 425D, BP: 6244, SI: 0003, DI: 000A
00:07:29:87.05040: IP: 1BDC, FLAGS: 0803
00:07:29:87.05040: CR0: FFF0
00:07:29:87.05296: FLAGSINFO:C1p0a0zstidO00n0
00:07:29:87.05296: Interrupt status: 0000000000000001
00:07:29:87.05328: VGA@556,75(CRT:588,109)
00:07:29:87.05328: Display=712,446

00:07:30:18.00704: F000:1BDE (7504)JNZ 1BE4
00:07:30:18.00736: Registers:
00:07:30:18.00736: AX: 0000, BX: 14AF, CX: 0000, DX: 0000
00:07:30:18.00736: CS: F000, DS: 0000, ES: A000, SS: 3867
00:07:30:18.00800: SP: 425D, BP: 6244, SI: 0003, DI: 000A
00:07:30:18.00800: IP: 1BDE, FLAGS: 0046
00:07:30:18.00800: CR0: FFF0
00:07:30:18.00800: FLAGSINFO:c1P0a0Zstido00n0
00:07:30:18.01056: Interrupt status: 0000000000000001
00:07:30:18.01088: VGA@557,75(CRT:588,109)
00:07:30:18.01088: Display=712,446

00:07:30:42.00736: F000:1BE0 (B4FF)MOVB AH, FF
00:07:30:42.00768: Registers:
00:07:30:42.00768: AX: 0000, BX: 14AF, CX: 0000, DX: 0000
00:07:30:42.00768: CS: F000, DS: 0000, ES: A000, SS: 3867
00:07:30:42.00800: SP: 425D, BP: 6244, SI: 0003, DI: 000A
00:07:30:42.00800: IP: 1BE0, FLAGS: 0046
00:07:30:42.01024: CR0: FFF0
00:07:30:42.01024: FLAGSINFO:c1P0a0Zstido00n0
00:07:30:42.01088: Interrupt status: 0000000000000001
00:07:30:42.01088: VGA@592,75(CRT:624,109)
00:07:30:42.01088: Display=712,446

00:07:30:74.02016: F000:1BE2 (EB2F)JMP 1C13
00:07:30:74.02016: Registers:
00:07:30:74.02016: AX: FF00, BX: 14AF, CX: 0000, DX: 0000
00:07:30:74.02016: CS: F000, DS: 0000, ES: A000, SS: 3867
00:07:30:74.02048: SP: 425D, BP: 6244, SI: 0003, DI: 000A
00:07:30:74.02048: IP: 1BE2, FLAGS: 0046
00:07:30:74.02048: CR0: FFF0
00:07:30:74.02272: FLAGSINFO:c1P0a0Zstido00n0
00:07:30:74.02272: Interrupt status: 0000000000000001
00:07:30:74.02272: VGA@595,75(CRT:626,109)
00:07:30:74.02304: Display=712,446

00:07:30:99.00784: Read from memory: 0003C8CD=AF (¯)
00:07:30:99.00784: Read from memory: 0003C8CE=14 ()
00:07:30:99.00784: F000:1C13 (5B)POP BX
00:07:30:99.00816: Registers:
00:07:30:99.00816: AX: FF00, BX: 14AF, CX: 0000, DX: 0000
00:07:30:99.01104: CS: F000, DS: 0000, ES: A000, SS: 3867
00:07:30:99.01136: SP: 425D, BP: 6244, SI: 0003, DI: 000A
00:07:30:99.01136: IP: 1C13, FLAGS: 0046
00:07:30:99.01168: CR0: FFF0
00:07:30:99.01168: FLAGSINFO:c1P0a0Zstido00n0
00:07:30:99.01200: Interrupt status: 0000000000000001
00:07:30:99.01200: VGA@642,75(CRT:674,109)
00:07:30:99.01200: Display=712,446

00:07:31:43.00720: Writing to memory: 0003C8CD=00 ( )
00:07:31:43.00720: Writing to memory: 0003C8CE=00 ( )
00:07:31:43.00720: F000:1C14 (1E)PUSH DS
00:07:31:43.00752: Registers:
00:07:31:43.00752: AX: FF00, BX: 14AF, CX: 0000, DX: 0000
00:07:31:43.00752: CS: F000, DS: 0000, ES: A000, SS: 3867
00:07:31:43.00976: SP: 425F, BP: 6244, SI: 0003, DI: 000A
00:07:31:43.01008: IP: 1C14, FLAGS: 0046
00:07:31:43.01008: CR0: FFF0
00:07:31:43.01040: FLAGSINFO:c1P0a0Zstido00n0
00:07:31:43.01040: Interrupt status: 0000000000000001
00:07:31:43.01072: VGA@648,75(CRT:680,109)
00:07:31:43.01072: Display=712,446

00:07:31:88.00768: Writing to memory: 0003C8CB=18 ()
00:07:31:88.00768: Writing to memory: 0003C8CC=1C ()
00:07:31:88.00768: F000:1C15 (E861FD)CALL 1979
00:07:31:88.00768: Registers:
00:07:31:88.00800: AX: FF00, BX: 14AF, CX: 0000, DX: 0000
00:07:31:88.00800: CS: F000, DS: 0000, ES: A000, SS: 3867
00:07:31:88.01024: SP: 425D, BP: 6244, SI: 0003, DI: 000A
00:07:31:88.01056: IP: 1C15, FLAGS: 0046
00:07:31:88.01056: CR0: FFF0
00:07:31:88.01056: FLAGSINFO:c1P0a0Zstido00n0
00:07:31:88.01056: Interrupt status: 0000000000000001
00:07:31:88.01088: VGA@649,75(CRT:681,109)
00:07:31:88.01088: Display=712,446

00:07:32:26.00736: Read from memory: 000F197F=40 (@)
00:07:32:26.00736: Read from memory: 000F1980=00 ( )
00:07:32:26.00736: ModR/M address: F000:197F=000F197F
00:07:32:26.00768: F000:1979 (2E8E1E7F19)MOVW DS,[CS:197F]
00:07:32:26.00768: Registers:
00:07:32:26.00960: AX: FF00, BX: 14AF, CX: 0000, DX: 0000
00:07:32:26.00992: CS: F000, DS: 0000, ES: A000, SS: 3867
00:07:32:26.00992: SP: 425B, BP: 6244, SI: 0003, DI: 000A
00:07:32:26.01024: IP: 1979, FLAGS: 0046
00:07:32:26.01024: CR0: FFF0
00:07:32:26.01024: FLAGSINFO:c1P0a0Zstido00n0
00:07:32:26.01024: Interrupt status: 0000000000000001
00:07:32:26.01056: VGA@722,76(CRT:0,110)
00:07:32:26.01056: Display=712,446

00:07:32:82.00704: Read from memory: 0003C8CB=18 ()
00:07:32:82.00704: Read from memory: 0003C8CC=1C ()
00:07:32:82.00736: F000:197E (C3)RET
00:07:32:82.00736: Registers:
00:07:32:82.00736: AX: FF00, BX: 14AF, CX: 0000, DX: 0000
00:07:32:82.00736: CS: F000, DS: 0040, ES: A000, SS: 3867
00:07:32:82.00960: SP: 425B, BP: 6244, SI: 0003, DI: 000A
00:07:32:82.00960: IP: 197E, FLAGS: 0046
00:07:32:82.00992: CR0: FFF0
00:07:32:82.00992: FLAGSINFO:c1P0a0Zstido00n0
00:07:32:82.00992: Interrupt status: 0000000000000001
00:07:32:82.00992: VGA@790,76(CRT:22,110)
00:07:32:82.00992: Display=712,446

00:07:33:18.00736: Writing to memory: 0000046B=FF (ÿ)
00:07:33:18.00768: ModR/M address: 0040:006B=0000046B
00:07:33:18.00768: F000:1C18 (88266B00)MOVB [DS:006B],AH
00:07:33:18.00768: Registers:
00:07:33:18.00768: AX: FF00, BX: 14AF, CX: 0000, DX: 0000
00:07:33:18.00768: CS: F000, DS: 0040, ES: A000, SS: 3867
00:07:33:18.01056: SP: 425D, BP: 6244, SI: 0003, DI: 000A
00:07:33:18.01056: IP: 1C18, FLAGS: 0046
00:07:33:18.01056: CR0: FFF0
00:07:33:18.01088: FLAGSINFO:c1P0a0Zstido00n0
00:07:33:18.01088: Interrupt status: 0000000000000001
00:07:33:18.01088: VGA@4,76(CRT:36,110)
00:07:33:18.01088: Display=712,446

00:07:33:69.00720: Read from memory: 0003C8CD=00 ( )
00:07:33:69.00752: Read from memory: 0003C8CE=00 ( )
00:07:33:69.00752: F000:1C1C (1F)POP DS
00:07:33:69.00752: Registers:
00:07:33:69.00784: AX: FF00, BX: 14AF, CX: 0000, DX: 0000
00:07:33:69.00784: CS: F000, DS: 0040, ES: A000, SS: 3867
00:07:33:69.01040: SP: 425D, BP: 6244, SI: 0003, DI: 000A
00:07:33:69.01072: IP: 1C1C, FLAGS: 0046
00:07:33:69.01072: CR0: FFF0
00:07:33:69.01104: FLAGSINFO:c1P0a0Zstido00n0
00:07:33:69.01104: Interrupt status: 0000000000000001
00:07:33:69.01104: VGA@7,76(CRT:38,110)
00:07:33:69.01104: Display=712,446

00:07:34:17.05168: Read from memory: 0003C8CF=A3 (£)
00:07:34:17.05168: Read from memory: 0003C8D0=CB (Ë)
00:07:34:17.05168: F000:1C1D (58)POP AX
00:07:34:17.05168: Registers:
00:07:34:17.05200: AX: FF00, BX: 14AF, CX: 0000, DX: 0000
00:07:34:17.05424: CS: F000, DS: 0000, ES: A000, SS: 3867
00:07:34:17.05424: SP: 425F, BP: 6244, SI: 0003, DI: 000A
00:07:34:17.05456: IP: 1C1D, FLAGS: 0046
00:07:34:17.05456: CR0: FFF0
00:07:34:17.05456: FLAGSINFO:c1P0a0Zstido00n0
00:07:34:17.05488: Interrupt status: 0000000000000001
00:07:34:17.05488: VGA@104,76(CRT:136,110)
00:07:34:17.05488: Display=712,446

00:07:34:66.00736: Read from memory: 0003C8D1=40 (@)
00:07:34:66.00736: Read from memory: 0003C8D2=1D ()
00:07:34:66.00736: Read from memory: 0003C8D3=20 ( )
00:07:34:66.00768: Read from memory: 0003C8D4=00 ( )
00:07:34:66.00768: Read from memory: 0003C8D5=03 ()
00:07:34:66.00768: Read from memory: 0003C8D6=08 ()
00:07:34:66.00960: F000:1C1E (CF)IRET
00:07:34:66.00992: Registers:
00:07:34:66.01024: AX: CBA3, BX: 14AF, CX: 0000, DX: 0000
00:07:34:66.01024: CS: F000, DS: 0000, ES: A000, SS: 3867
00:07:34:66.01056: SP: 4261, BP: 6244, SI: 0003, DI: 000A
00:07:34:66.01056: IP: 1C1E, FLAGS: 0046
00:07:34:66.01056: CR0: FFF0
00:07:34:66.01056: FLAGSINFO:c1P0a0Zstido00n0
00:07:34:66.01088: Interrupt status: 0000000000000001
00:07:34:66.01088: VGA@158,76(CRT:190,110)
00:07:34:66.01088: Display=712,446

00:07:35:21.00752: Writing to memory: 0003C8D5=03 ()
00:07:35:21.00752: Writing to memory: 0003C8D6=08 ()
00:07:35:21.00752: Writing to memory: 0003C8D3=20 ( )
00:07:35:21.00752: Writing to memory: 0003C8D4=00 ( )
00:07:35:21.00752: Writing to memory: 0003C8D1=40 (@)
00:07:35:21.00784: Writing to memory: 0003C8D2=1D ()
00:07:35:21.01040: 0020:1D40 (FFFF)<NECV20/V30+ #UD>
00:07:35:21.01040: Registers:
00:07:35:21.01072: AX: CBA3, BX: 14AF, CX: 0000, DX: 0000
00:07:35:21.01104: CS: 0020, DS: 0000, ES: A000, SS: 3867
00:07:35:21.01104: SP: 4267, BP: 6244, SI: 0003, DI: 000A
00:07:35:21.01104: IP: 1D40, FLAGS: 0803
00:07:35:21.01104: CR0: FFF0
00:07:35:21.01104: FLAGSINFO:C1p0a0zstidO00n0
00:07:35:21.01136: Interrupt status: 0000000000000001
00:07:35:21.01136: VGA@188,76(CRT:220,110)
00:07:35:21.01136: Display=712,446

00:07:36:94.01728: Writing to memory: 0003C8CF=A3 (£)
00:07:36:94.01728: Writing to memory: 0003C8D0=CB (Ë)
00:07:36:94.01728: F000:1BD0 (50)PUSH AX
00:07:36:94.01728: Registers:
00:07:36:94.01728: AX: CBA3, BX: 14AF, CX: 0000, DX: 0000
00:07:36:94.01760: CS: F000, DS: 0000, ES: A000, SS: 3867
00:07:36:94.01984: SP: 4261, BP: 6244, SI: 0003, DI: 000A
00:07:36:94.01984: IP: 1BD0, FLAGS: 0803
00:07:36:94.02016: CR0: FFF0
00:07:36:94.02016: FLAGSINFO:C1p0a0zstidO00n0
00:07:36:94.02016: Interrupt status: 0000000000000001
00:07:36:94.02016: VGA@196,76(CRT:228,110)
00:07:36:94.02016: Display=712,446

Anyone knows how it even can get to this strange location? It seems it's still in real mode?

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

Reply 116 of 151, by crazyc

User metadata
Rank Member
Rank
Member
superfury wrote:

According to https://www.google.ch/patents/US5822778 the 80286 uses the FS and GS segments (just like the 80386), even though most documentations (like http://ref.x86asm.net/coder32.html#x65 ) mark the instructions prefixes as 80386+? I've modified the CPU core to use and allow the FS and GS prefixes, as well as handle invalid modr/m parameters(reg=7 on segment registers).

That's an error. FS and GS don't exist on the 286.

Reply 117 of 151, by superfury

User metadata
Rank l33t++
Rank
l33t++

Hmmm... Then why do all of the AT diagnostics disks I can find try to execute FS:, GS: or 32-bit (operand/address size) prefixes? Even the one that's supposed to be for the IBM 5170. Why would a program intended for the 5170(80286-8) use 80386+ instructions, causing it to enter an infinite loop(#UD) on a IBM PC AT, which is the diagnostic disk's intended PC to be used on?

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

Reply 118 of 151, by Jepael

User metadata
Rank Oldbie
Rank
Oldbie
superfury wrote:

Hmmm... Then why do all of the AT diagnostics disks I can find try to execute FS:, GS: or 32-bit (operand/address size) prefixes? Even the one that's supposed to be for the IBM 5170. Why would a program intended for the 5170(80286-8) use 80386+ instructions, causing it to enter an infinite loop(#UD) on a IBM PC AT, which is the diagnostic disk's intended PC to be used on?

Isn't it more likely that the programs don't use 386+ instruction and your emulator has a bug that ends up executing at incorrect address (code or data) that would look like 386+ instructions?

Reply 119 of 151, by superfury

User metadata
Rank l33t++
Rank
l33t++

That could be, but if so, how would I find the offending instruction? Since even advanced 8086 instructions run without error, it has to be a 80186+ instruction that causes it?

8086 instructions: https://bitbucket.org/superfury/unipcemu/src/ … 086.c?at=master
80186 instructions: https://bitbucket.org/superfury/unipcemu/src/ … V30.c?at=master
80286 instructions: https://bitbucket.org/superfury/unipcemu/src/ … 286.c?at=master

Each of those cores is built to be simply adding instructions and/or modifications to the parent CPU. So 8086 is also used by 80186+, 80186 is also used by 80286+, 80286 is also used by 80386+ etc. This applies until a CPU specifies it's own version in the jumptable, which overrides it's parent.

E.g.
8086 has JZ(Base)
80186+ have the pointer set to NULL, which then uses the 8086 JZ

But (in the 0F jumptable):
80286 has unkOP0F_286(Base #UD handler)
80386 has NULL(Use 80286 function)
80486 has CPUID(New Base, overrides 80286 version)
80586 has CPUID(New Base, overrides 80486 version)

Basically the table is parsed by starting at the CPU to be emulated(in this case the 80286 entries), then walking back one CPU at a time while the pointer is NULL and the current CPU isn't the first CPU(The 8086). This is done seperately for each instruction and operand size(16 and 32-bit).
When the emulator starts, the CPU core processes the big pointer table with pointers to each CPU's base function(First definition) or override(which is the new base function for all newer CPU's as well) into one table with 16-bit and 32-bit(operand size) functions to be called by the main CPU execution(after processing prefixes and reading the opcodes).

Essentially NULL uses the parent CPU's version of the 16-bit or 32-bit instruction and a function pointer sets a new base from that CPU onwards.

The main table:
https://bitbucket.org/superfury/unipcemu/src/ … bls.c?at=master

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