VOGONS


Compaq Deskpro 386 CPU emulation issues?

Topic actions

Reply 40 of 163, by superfury

User metadata
Rank l33t++
Rank
l33t++

Looking at the source code of the disassembled BIOS, I'm questioning the saneness of the BIOS itself: why would it overwrite the function number, which is used to properly execute a FDC/DMA command combination, with the unchanging value 4? Thus it would be executing a sort of Verify command each time it's trying to read anything from the disk?

The ROM I'm using is supposed to be the original Compaq Deskpro 386/16 BIOS(J.2 BIOS revision). Why would it fail on my emulation?

Look at https://www.pcjs.org/devices/pcx86/rom/compaq … /1988-01-28.asm for the actual code it's executing. Look for [bp+1],4 within the FDC part, right below the earlier mentioned label. It overwrites the current command and another byte in the table, then proceeds to use it(incorrectly) instead of the original AH function number(02h) that's stored at that location(DS:[BP+01]) until the mov. Then it reads the wrong entry from the table(#4 instead of #2) and sets up the DMA transfer incorrectly because of that? Can anyone see what's causing this error?

One better question: Why is it reaching F000:90E8 for a read sector(function 02h) operation, setting it to verify(04h) instead?
Anyone knows what's causing it to get to this strange code? Or is there a bug in there? Vladstamate? Jepael?

Edit: Just tried a simple PCJS test machine using the same ROM: https://www.pcjs.org/devices/pcx86/machine/co … 096kb/debugger/
It seems to suffer from problems as well(screen issues, failing to boot MS-DOS 6.22 properly from the floppy disk(disk 1 of the 1.44MB set)).

Edit: Trying again using that PCjs build to boot the PC-DOS 3.30 disk causes it to boot properly? So maybe it has the same kind of bug too?
Edit: MS-DOS 6.22(1.2M boot) seems to fail greatly on the PCJS machine(not displaying text properly, seemingly random locations on the cursor)?

Edit: Just converted the whole 80386/80486 cores (0F core for 80386, normal core for 80486) to use the instruction lookup table to determine modr/m parameter order. That might fix some bugs in those cores regarding faulting instruction orders etc. that go undetected by the normal execution(due to instruction sizes being unmodified, just the behaviour of the instructions changes). Verified with the test386.asm testsuite by Hottobar.

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

Reply 41 of 163, by superfury

User metadata
Rank l33t++
Rank
l33t++

Manually forcing the Verify mode on the DMA channel for the FDC to become a Write memory mode(mode 1) makes it properly boot from the floppy disk(MS-DOS 3.3)? So it's only a problem with the CPU somehow being incorrect somewhere along the way? As far as I can see, the instruction that loads the invalid value as a replacement of the function number always gets executed in one way or another? So somewhere along the path, it's supposed to be changed back?

Vladstamate, can you run the Compaq Deskpro 386/16 BIOS in your emulator(do you have the 80386 implemented)? Does the same problem with floppy disks happen in your case?

Edit: Just tried running MS-DOS 6.22 from a floppy disk on the Compaq Deskpro 386 emulation with a breakpoint on segment 70(The location of IO.SYS). It very soon reads a byte at 0000:xxxx, which is a static address(encoded in the modr/m byte itself, using mod=00, r/m=4), so it should be correct. It loads that value in DL before reading the disk again(probably the reset of the IO.SYS driver), and eventually tries to jump to it.

But the value that's read before issuing INT 13h to read the disk is actually 0xFD, so it's reading an invalid disk, goes through some looped piece of code, eventually jumping to offset FFEx(odd address), where the sector was supposed to be loaded, and starts running uninitialized memory(ADD DS:[BX+SI],AL) until faulting when reading offset FFFFh, causing an infinite loop to occur with faulting.

So the drive number that's supposed to be written by the boot sector isn't there, or has the wrong value? Seems like a clue to what's going wrong?

Filename
debugger_DOS6.22_IO.SYS.zip
File size
469.88 KiB
Downloads
81 downloads
File comment
MS-DOS 6.22 IO.SYS running on Compaq Deskpro 386 with the FDD DMA hack enabled.
File license
Fair use/fair dealing exception

Luckily I've still got a source link of that boot sector(of MS-DOS 6.2, which I doubt has changed on 6.22): http://www.intel-assembler.it/portale/5/Disas … Boot-Sector.asp

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

Reply 42 of 163, by vladstamate

User metadata
Rank Oldbie
Rank
Oldbie
superfury wrote:

Vladstamate, can you run the Compaq Deskpro 386/16 BIOS in your emulator(do you have the 80386 implemented)? Does the same problem with floppy disks happen in your case?

I don't mind trying that. Compaq does have some strangeness which likely I am not emulating but I am willing to give it a try. The problem is I am having a hard time locating the J.2 version of the Deskpro 386 that you are using. In fact even later ones I cannot find. Can you PM me information of where I can obtain the BIOS dump?

And yes I do support 386.

YouTube channel: https://www.youtube.com/channel/UC7HbC_nq8t1S9l7qGYL0mTA
Collection: http://www.digiloguemuseum.com/index.html
Emulator: https://sites.google.com/site/capex86/
Raytracer: https://sites.google.com/site/opaqueraytracer/

Reply 43 of 163, by superfury

User metadata
Rank l33t++
Rank
l33t++

This is what I currently get when booting MS-DOS 6.22 on the Compaq Deskpro with the FDD DMA hack enabled(incorrectly setting the DMA mode register to 0x42 instead of 0x46, causing the DMA to perform a self-test(no I/O or memory transactions) instead of FDC to memory transfer):

Filename
debugger.log
File size
371.03 KiB
Downloads
52 downloads
File comment
UniPCemu running the MS-DOS 6.22 boot sector, transferring to IO.SYS(0070:00000000), after which an invalid jump to offset FFDx is crashing eventually at 0070:FFFF).
File license
Fair use/fair dealing exception

Correction: it's the J.4 ROM I'm using, not J.2 ROM.

Edit: Just downloaded a fresh MS-DOS 6.22 boot disk from allbootdisks.com. Now MS-DOS 6.22 properly continues booting? It seems the disk was somehow corrupted?
Edit: It also seems that during FDC booting, the old waiting-for-the-HDD-to-become-busy ridiculously long loop is back?

Edit: Although MS-DOS 6.22 seems to boot, when I try to launch fdisk to partition the newly createn hdd images, it crashes on the FDC(probably because the seek times out somehow? (in IPS mode)).
Edit: It seems to work fine in IPS mode. It seems that, like the IBM AT, the Compaq Deskpro 386 BIOS seems to require cycle-accuracy to time it's loops?

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

Reply 44 of 163, by superfury

User metadata
Rank l33t++
Rank
l33t++

Now trying MS-DOS 7.0(Windows 95a bootdisk) on the Compaq Deskpro 386.

The VGA is rendering nothing and is pretty impossible set-up:
X resolution: 1008 raster pixels(horizontal total origin). Horizontal display start: 0(end 729). Horizontal blanking start: 819(end 10), Horizontal retrace start: 288(end 6). Horizontal total: 1062. Seems good and within each other's ranges.

The vertical parameters, however, are messed up:
Y resolution: Never determined(current row: 15, looks fine, although like the vertical total, way too small?). Vertical display end: 144 (a bit on the short side, only 9 characters vertically on a 9x16 font?), Vertical blanking start: 406(end 57) looks fine, Vertical retrace start: 312(end: 😎 looks fine, Vertical total: 26(seems oddly programmed)?

Retraces and blanking is never hit, because the vertical total is so low(it's out of range)?

The OS on the other hand is at some strange segment in real mode, executing a 0xFF /7 instruction(probabbly 0xFFFF in memory)?

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

Reply 45 of 163, by vladstamate

User metadata
Rank Oldbie
Rank
Oldbie

I finally got it loading. It seems it exposed a bug in CAPE related to entering protected mode. The BIOS seems to do something (legit) that other BIOSes don't do. I'll report after I fix that and I make progress.

YouTube channel: https://www.youtube.com/channel/UC7HbC_nq8t1S9l7qGYL0mTA
Collection: http://www.digiloguemuseum.com/index.html
Emulator: https://sites.google.com/site/capex86/
Raytracer: https://sites.google.com/site/opaqueraytracer/

Reply 46 of 163, by superfury

User metadata
Rank l33t++
Rank
l33t++

That wouldn't be, by accident, be the 'common' bug of entering protected mode setting the PM bit? Thus reloading all segment registers? Nothing is reloaded after all, everything works like in real mode, until interrupts(protected-mode style) and segment register loads(protected-mode style) occur.

Now I'm curious, what does it do that other BIOSes don't?

Currently having trouble using fdisk on the second hard disk image(100MB image), which seems to make it(the XT-IDE AT BIOS) hang reading the HDD status register(which has value 0x40 in it, being ready to process a new command?)? Maybe a problem with the way multiple mode reads? There might have been a bug with the DSC bit(which should always be set on my emulation, since it's always done seeking?), except for ATAPI devices(Not being used as the service bit)?
I see the last executed command is 0xC4(Read multiple), while the XT-IDE AT BIOS is seemingly waiting for something to appear on the status register(It gives 0x50(Ready for command(0x40) and 0x10(Drive seek complete)) and is ready to receive a new command)?

FDisk on the first drive seems fine. Then switching to the second drive and trying to make a partition I see it executing a read verify sectors and then a write multiple, then entering a huge delay after each write multiple command?
Edit: The multiple mode is disabled somehow, executing the write multiple commands, causing the controller to error out(read/write multiple without multiple mode set is illegal, thus reporting an invalid command and erroring out)?
Edit: Just found out a little thing: ATA/ATAPI reset doesn't reset the multiple mode setting, when the appropriate feature setting(0x66/0xCC) is preventing it from being cleared(it seems during the 0x66 command, the multiple mode setting isn't cleared to defaults)?

Edit: Looking at the executed commands, I see a read multiple that works, followed by one that fails(because it's disabled)? This happens multiple times?
Edit: It seems to have set the multiple mode correctly for the primary master, but not for the primary slave? That's what's causing the huge delays?

Edit: It seems to execute a Set Multiple mode for the primary master, but not for the primary slave, which also receives invalid read multiple commands, and is thus erroring out, causing large delays as a result of that?

Edit: Just changed the Set multiple mode command to affect both Master and Slave drives. It now will boot a lot faster(without those long read/write delays because of invalid read/write multiple commands). From minutes to seconds:D (Although incorrect from a hardware perspective(ATA documentation))

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

Reply 47 of 163, by superfury

User metadata
Rank l33t++
Rank
l33t++

Just tried running xtidecfg.com on the AT motherboard emulation(80286 CPU). I notice now that practically EVERY keyboard key press/release is followed by the software disabling and enabling the PS/2 keyboard port, causing a reset of the buffers in the middle of reading the scancodes from the PS/2 keyboard(with translation)? It's executing commands 0xAD then 0xAE on the 8042 each time getting an IRQ from the PS/2 keyboard, having received a scancode byte from the PS/2 keyboard. This causes a messing up of the scancodes received, causing e.g. up/down/left/right to not be able to receive their scancodes as they should?

Edit: Having disabled that behaviour, it now doesn't seem to be set to scancode set 2(which should be the default after power-up/reset), causing the 8042 to translate incorrectly?

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

Reply 48 of 163, by superfury

User metadata
Rank l33t++
Rank
l33t++

Having fixed the PS/2 keyboard to not reset when disabled and enabled makes it POST OK still, while fixing the double inputs 😁

Just flashed the new XT and AT XT-IDE ROMs. All that's left is to check if it still programs the master drive only for Block mode. According to the source code on xtifeuniversalbios.org, it should do so to both drives using two call instructions following each other. If it only does one, then maybe there's an error somewhere in the CPU? Or a problem with that part handling the function Ah call?

Edit: Just removed the master/slave shared setting on the IDE drive emulation: the most recent BIOS from the official website(http://www.xtideuniversalbios.org/binaries/, using r591) uses it correctly and sets up both drives correctly(instead of just one drive) 😁

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

Reply 49 of 163, by vladstamate

User metadata
Rank Oldbie
Rank
Oldbie

So the Compaq Deskpro 386 BIOS helped me fix 2 bugs in my emulator (mov cr, reg is always 2 register instruction - ignore the mode - and an issue entering PM from a jump [address] instruction).

However now I am stumped that it enters PM after loading the GDT from F0778h which is...0 because the BIOS seems to be only 32Kb in size and therefore only loads from F8000 to FFFFF.

@superfury. The first lgdt instruction when you execute your BIOS what does it load the GDT from?

f000:00008796 2E 0F 01 16 78 07 lgdt [cs:0778]
f000:0000879c 0F 20 00 mov eax,cr0
f000:0000879f 0D 01 00 or ax,1
f000:000087a2 0F 22 00 mov cr0,eax
f000:000087a5 2E jmp far [0xf878a]

YouTube channel: https://www.youtube.com/channel/UC7HbC_nq8t1S9l7qGYL0mTA
Collection: http://www.digiloguemuseum.com/index.html
Emulator: https://sites.google.com/site/capex86/
Raytracer: https://sites.google.com/site/opaqueraytracer/

Reply 50 of 163, by superfury

User metadata
Rank l33t++
Rank
l33t++
	ret				; 0000872F  C3  '.'

romgdt: ; 00008730
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0xFF,0xFF,0x00,0x00,0xC0,0x92,0x00,0x80
db 0xFF,0xFF,0x00,0x00,0x00,0x92,0x00,0x00, 0xFF,0xFF,0x00,0x00,0x0F,0x9A,0x00,0x00
db 0xFF,0xFF,0x00,0x00,0x00,0x92,0x00,0xC0, 0xFF,0xFF,0x00,0x00,0xFF,0x9A,0x00,0x00
db 0xFF,0xFF,0x00,0x00,0xFF,0x92,0x00,0x00, 0xFF,0xFF,0x00,0x00,0x0E,0x92,0x00,0x00
db 0xFF,0xFF,0x00,0x00,0xFD,0x92,0x00,0x00

gdtr_lo: ; accessed via offset 0x0778 (and also 0x8778)
dw 0x0047,0x0730,0x000F ; 00008778 ; GDTR referencing the above GDT in the 0th Mb
gdtr_hi: ; accessed via offset 0x077E
dw 0x0047,0x0730,0x00FF ; 0000877E ; GDTR referencing the above GDT in the 15th Mb
idtr_lo: ; accessed via offset 0x0784
dw 0xFFFF,0x0000,0x0000 ; 00008784 ; IDTR

db 0xAA,0x87,0x18,0x00,0xF8,0x87
db 0x18,0x00,0x28,0x88,0x18,0x00

x8796: lgdt [cs:0x0778] ; 00008796 2E0F01167807; load [gdtr_lo] into GDTR
mov eax,cr0 ; 0000879C 0F2000
or ax,0x1 ; 0000879F 0D0100
mov cr0,eax ; 000087A2 0F2200
jmp far [cs:0x878a] ; 000087A5 2EFF2E8A87

mov ax,0x8 ; 000087AA B80800 '...'
mov es,ax ; 000087AD 8EC0 '..'
mov al,0x2f ; 000087AF B02F './'
mov [es:di],bl ; 000087B1 26881D '&..'
out 0x84,al ; 000087B4 E684 '..'
cld ; 000087B6 FC '.'
cld ; 000087B7 FC '.'
cld ; 000087B8 FC '.'
cld ; 000087B9 FC '.'
cld ; 000087BA FC '.'
cld ; 000087BB FC '.'
cld ; 000087BC FC '.'
cld ; 000087BD FC '.'
cld ; 000087BE FC '.'
cld ; 000087BF FC '.'
cld ; 000087C0 FC '.'
cld ; 000087C1 FC '.'
cld ; 000087C2 FC '.'
cld ; 000087C3 FC '.'
cld ; 000087C4 FC '.'
cld ; 000087C5 FC '.'
x87c6: mov ax,0x10 ; 000087C6 B81000
mov es,ax ; 000087C9 8EC0
mov eax,cr0 ; 000087CB 0F2000
and eax,0x7ffffffe ; 000087CE 6625FEFFFF7F
mov cr0,eax ; 000087D4 0F2200
jmp 0xf000:x87dc ; 000087D7 EADC8700F0

x87dc: lidt [cs:0x0784] ; 000087DC 2E0F011E8407; load [idtr_lo] into IDTR
jmp bp ; 000087E2 FFE5

x87e4: lgdt [cs:0x0778] ; 000087E4 2E0F01167807; load [gdtr_lo] into GDTR
mov eax,cr0 ; 000087EA 0F2000
or ax,0x1 ; 000087ED 0D0100
mov cr0,eax ; 000087F0 0F2200
Show last 2 lines
	jmp	far [cs:0x878e]		; 000087F3  2EFF2E8E87

Do you have the RAM/ROM relocation register/status register implemented properly at memory location 0x80C00000? Since it's cleared (RAM (un)protected ?, or invalidly (re)mapped ROM?) might be wrong there? Do you have your ROMs properly mapped at both first and second half of the addresses? So once at 0xF0000-F7FFF and another at F8000-FFFFF? Of course they must be mapped out as the RAM relocation dictates etc. :

;
; ROM BIOS for COMPAQ DeskPro 386-16
; Rev J.4, from parts 109592-001 and 109591-001, dated '01/28/88'
; (C)Copyright COMPAQ Computer Corporation 1982,83,84,85,86,87-All rights reserved.
;
; Listing produced by NDISASM, 2015-Apr-04
; Additional post-processing performed by the PCjs TextOut module
; All post-processing, comments, etc., copyright © 2012-2017 Jeff Parsons <Jeff@pcjs.org>
;
; This file is part of PCjs, a computer emulation software project at <http://pcjs.org/>.
;
; PCjs is free software: you can redistribute it and/or modify it under the terms of the
; GNU General Public License as published by the Free Software Foundation, either version 3
; of the License, or (at your option) any later version.
;
; PCjs is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
; even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
; GNU General Public License for more details.
;
; You should have received a copy of the GNU General Public License along with PCjs. If not,
; see <http://www.gnu.org/licenses/gpl.html>.
;
; Overview
; --------
; This 32Kb ROM image is ORG'ed at 0x8000, because most of its code is designed to run
; at real-mode addresses F000:8000 through F000:FFFF.
;
; And even though the 80386 resets with CS:IP set to F000:FFF0, the physical base address
; of CS is set to %FFFF0000, which means the ROM must also be mapped at physical addresses
; %FFFF8000 through %FFFFFFFF.
;
; Additionally, DeskPro 386 systems mirror this 32Kb ROM at real-mode address F000:0000
; through F000:7FFF. And that region is similarly mirrored at physical addresses %FFFF0000
; through %FFFF7FFFF.
;
; In other words, both 32Kb halves of the last 64Kb of both the first and last megabyte
; of the 80386's 4Gb address space are physically mapped to this ROM image.
;
; Finally, the DeskPro 386 has a "RAM Relocation" feature that allows 128Kb of RAM at
; %00FE0000 through %00FFFFFF to be mapped to %000E0000 through %000FFFFF, effectively
; replacing the ROM in the first megabyte with write-protected RAM; the top 64Kb of that
; RAM must first be initialized with the 64Kb at %000F0000 prior to remapping. It's also
; possible to copy external ROMs from %000C0000 through %000EFFFF into the bottom 64Kb of
; that RAM, but this is only done for ROMs known to contain relocatable code; eg, a COMPAQ
; Video Graphics Controller (VGC) Board.
;
; Every DeskPro 386 system must have a MINIMUM of 1Mb of RAM, of which either 256Kb,
; 512Kb, or 640Kb can be physically mapped as conventional memory (at the bottom of the
; first megabyte), with the remainder (either 768Kb, 512Kb, or 384Kb) physically mapped
; to the top of the 16th megabyte (ending at address %00FFFFFF), the last 128Kb of which
; is used by the "RAM Relocation" feature. The remaining memory immediately below that
; 128Kb (ie, below %00FE0000) can only be accessed by special system software, such as CEMM.
;
; COMPAQ refers to that remaining memory as "Compaq Built-in Memory".
;
; As the COMPAQ 386/25 TechRef explains:
;
; A data structure in memory indicates how much of the COMPAQ Built-in Memory (F40000h
; to FE0000h) is [available and] in use. This memory is allocated downward (decreasing
; addresses) starting at address FE0000h. Applications developed specifically for the
Show last 22 lines
;	COMPAQ DESKPRO	386/25 Personal Computer, such as CEMM, read and modify this data
; structure to allocate and deallocate portions of the COMPAQ Built-in Memory for their
; use. The built-in memory data structure is located in write-protected memory at segment
; F000h. The offset is specified by the word at F000:FFE0.
;
; The format of the data structure is given [below]. Because the data structure resides
; in write-protected memory, the write-protection must be disabled when updating the data
; structure.
;
; Word Description
; ---- -----------
; 0 FFFFh indicates that no COMPAQ Built-in Memory is available. Otherwise, words
; 1, 2, and 3 define the amount of memory available.
;
; 1 Total COMPAQ Built-in Memory size in 16-byte blocks.
;
; 2 Available built-in memory in 16-byte blocks.
;
; 3 Address for the last-used byte. The byte below (lower address) this byte is the
; first free byte in the COMPAQ Built-in Memory.
;

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

Reply 51 of 163, by superfury

User metadata
Rank l33t++
Rank
l33t++

So E0000-FFFFF ROM is enabled always, with remapping(write-through when mapped below 1MB, without write protection) to 286 reboot location accordingly, with write protect on/off:

	if (unlikely((realaddress==0x80C00000) && (EMULATED_CPU>=CPU_80386) && (is_Compaq==1))) //Compaq special register?
{
memoryprotect_FE0000 = ((~value)&2); //Write-protect 128KB RAM at 0xFE0000?
if (value&1) //128KB RAM only addressed at FE0000? Otherwise, relocated to (F(general documentation)/0(IOPORTS.LST)?)E0000.
{
BIOSROM_LowMemoryBecomesHighMemory = BIOSROM_DisableLowMemory = 0; //Normal low memory!
}
else
{
BIOSROM_LowMemoryBecomesHighMemory = 1; BIOSROM_DisableLowMemory = 0; //Low memory becomes high memory! Leave the BIOS ROM in place!
}
MoveLowMemoryHigh = 7; //Move all memory blocks high when needed?
MMU.maxsize = MMU.size-(0x100000-0xA0000); //Limit the memory size!
}

So, if I understand the code correctly:
0xFE0000-0xFFFFFF contains the actual RAM(640K-1MB RAM reserved(substracted from total RAM, which is 1MB+ always) area in my case). This is always present at that location. It can be write-protected by clearing bit 1 of the register at 80C00000.
Clearing bit 0 of said register causes it to map address 0xE0000-0xFFFFF to said area(and disable the low ROM mapping), allowing said area to be used as a ROM(when write-protected).

Last edited by superfury on 2018-02-13, 00:05. 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 52 of 163, by vladstamate

User metadata
Rank Oldbie
Rank
Oldbie

Ohh thank you! This is good information, I did not know that. May I ask where on the PCJs website I can find that documentation (and the listing)?

YouTube channel: https://www.youtube.com/channel/UC7HbC_nq8t1S9l7qGYL0mTA
Collection: http://www.digiloguemuseum.com/index.html
Emulator: https://sites.google.com/site/capex86/
Raytracer: https://sites.google.com/site/opaqueraytracer/

Reply 53 of 163, by superfury

User metadata
Rank l33t++
Rank
l33t++

https://www.pcjs.org/devices/pcx86/rom/compaq/deskpro386/

Look for the 1988-01-28.asm file mentioned at the end of the text, below the how-to-disassemble and before the manual cleanup stuff.

The result, 1988-01-28.asm, after a small amount of manual cleanup, can now be successfully reassembled

Edit: Thinking about it, I might have (had) a little problem unmapping the low BIOS ROM with using the remapping feature. Atm, the ROM in low memory(E0000-FFFFF) is always mapped, but it shouldn't be when it's remapped(bit 1 cleared?)?

OPTINLINE void applyMemoryHoles(uint_32 *realaddress, byte *nonexistant, byte iswrite)
{
uint_32 originaladdress = *realaddress; //Original address!
INLINEREGISTER byte memloc; //What memory block?
INLINEREGISTER byte memoryhole;
memloc = 0; //Default: first memory block: low memory!
memoryhole = 0; //Default: memory unavailable!
if (*realaddress>=LOW_MEMORYHOLE_START) //Start of first hole?
{
if (*realaddress<LOW_MEMORYHOLE_END) //First hole?
{
memoryhole = 1; //First memory hole!
}
else //Mid memory?
{
memloc = 1; //Second memory block: mid memory!
if (*realaddress>=MID_MEMORYHOLE_START) //Start of second hole?
{
if (*realaddress<MID_MEMORYHOLE_END) //Second hole?
{
memoryhole = 2; //Second memory hole!
}
else //High memory?
{
memloc = 2; //Third memory block!
if ((*realaddress>=HIGH_MEMORYHOLE_START) && ((uint_64)*realaddress<(uint_64)HIGH_MEMORYHOLE_END)) //Start of third hole?
{
memoryhole = 3; //Third memory hole!
}
else
{
memloc = 3; //Fourth memory block!
}
}
}
}
}

if (memoryhole) //Memory hole?
{
*nonexistant = 1; //We're non-existant!
if (BIOSROM_LowMemoryBecomesHighMemory && (memoryhole==1) && BIOSROM_LowMemoryBecomesHighMemory) //Compaq remaps RAM from E0000-FFFFF to FE0000-FFFFFF.
{
if ((originaladdress>=0xE0000) && (originaladdress<=0xFFFFF)) //Low memory hole to remap to the available memory hole memory? This is the size that's defined in MMU_RESERVEDMEMORY!
{
memloc = 2; //We're the second block instead!
originaladdress |= 0xF00000; //Patch to physical FE0000-FFFFFF reserved memory range to use!
}
}
}
else //Plain memory?
{
*nonexistant = 0; //We're to be used directly!
if ((MoveLowMemoryHigh&1) && (memloc)) //Move first block lower?
{
*realaddress -= (LOW_MEMORYHOLE_END - LOW_MEMORYHOLE_START); //Patch into memory hole!
}
if ((MoveLowMemoryHigh&2) && (memloc>=2)) //Move second block lower?
{
*realaddress -= (MID_MEMORYHOLE_END - MID_MEMORYHOLE_START); //Patch into memory hole!
Show last 22 lines
		}
if ((MoveLowMemoryHigh&4) && (memloc>=3)) //Move third block lower?
{
*realaddress -= (uint_32)((uint_64)HIGH_MEMORYHOLE_END - (uint_64)HIGH_MEMORYHOLE_START); //Patch into memory hole!
}
}
//Implemented (According to PCJs): Compaq has 384Kb of RAM at 0xFA0000-0xFFFFFF always. The rest of RAM is mapped low and above 16MB. The FE0000-FFFFFF range can be remapped to E0000-FFFFF, while it can be write-protected.
if ((originaladdress>=0xFA0000) && (originaladdress<=0xFFFFFF)) //Special area addressed?
{
if (memoryprotect_FE0000 && iswrite && (originaladdress>=0xFE0000)) //Memory protected?
{
*nonexistant = 1; //We're non-existant!
return; //Abort!
}
//Reading or not protected?
if (((EMULATED_CPU==CPU_80386) && is_XT) || (is_Compaq==1)) //Compaq or XT reserved area?
{
*realaddress += MMU.size-(0xFA0000+(0x100000-0xA0000)); //Patch to physical FE0000-FFFFFF reserved memory range to use, at the end of the physical memory!
*nonexistant = 3; //Reserved memory!
}
}
}

Edit: After enabling it(disabling the low memory BIOS ROM when mapping the high memory (un)protected area to the upper memory area's top 128KB), I now see the BIOS enabling and disabling it some times before/during the boot procedure, which seems to indicate(since it isn't crashing as before) that it's(the memory protection at (0/F)E0000-(0/F)FFFFF as well as the remapping) working properly now 😁

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

Reply 54 of 163, by superfury

User metadata
Rank l33t++
Rank
l33t++

Hmmmm.. Just looking at the Bochs DMA implementation:

if (BX_DMA_THIS s[ma_sl].chan[channel].mode.transfer_type == 1) { // write
708 // DMA controlled xfer of bytes from I/O to Memory
709
710 if (!ma_sl) {
711 if (BX_DMA_THIS h[channel].dmaWrite8)
712 len = BX_DMA_THIS h[channel].dmaWrite8(buffer, maxlen);
713 else
714 BX_PANIC(("no dmaWrite handler for channel %u.", channel));
715
716 DEV_MEM_WRITE_PHYSICAL_DMA(phy_addr, len, buffer);
717
718 BX_DBG_DMA_REPORT(phy_addr, len, BX_WRITE, buffer[0]); // FIXME
719 } else {
720 if (BX_DMA_THIS h[channel].dmaWrite16)
721 len = BX_DMA_THIS h[channel].dmaWrite16((Bit16u*)buffer, maxlen / 2);
722 else
723 BX_PANIC(("no dmaWrite handler for channel %u.", channel));
724
725 DEV_MEM_WRITE_PHYSICAL_DMA(phy_addr, len, buffer);
726
727 BX_DBG_DMA_REPORT(phy_addr, len * 2, BX_WRITE, buffer[0] | (buffer[1] << 16)); // FIXME
728 }
729 } else if (BX_DMA_THIS s[ma_sl].chan[channel].mode.transfer_type == 2) { // read
730 // DMA controlled xfer of bytes from Memory to I/O
731
732 if (!ma_sl) {
733 DEV_MEM_READ_PHYSICAL_DMA(phy_addr, maxlen, buffer);
734
735 if (BX_DMA_THIS h[channel].dmaRead8)
736 len = BX_DMA_THIS h[channel].dmaRead8(buffer, maxlen);
737
738 BX_DBG_DMA_REPORT(phy_addr, len, BX_READ, buffer[0]); // FIXME
739 } else {
740 DEV_MEM_READ_PHYSICAL_DMA(phy_addr, maxlen, buffer);
741
742 if (BX_DMA_THIS h[channel].dmaRead16)
743 len = BX_DMA_THIS h[channel].dmaRead16((Bit16u*)buffer, maxlen / 2);
744
745 BX_DBG_DMA_REPORT(phy_addr, len * 2, BX_READ, buffer[0] | (buffer[1] << 16)); // FIXME
746 }
747 } else if (BX_DMA_THIS s[ma_sl].chan[channel].mode.transfer_type == 0) {
748 // verify
749
750 if (!ma_sl) {
751 if (BX_DMA_THIS h[channel].dmaWrite8)
752 len = BX_DMA_THIS h[channel].dmaWrite8(buffer, 1);
753 else
754 BX_PANIC(("no dmaWrite handler for channel %u.", channel));
755 } else {
756 if (BX_DMA_THIS h[channel].dmaWrite16)
757 len = BX_DMA_THIS h[channel].dmaWrite16((Bit16u*)buffer, 1);
758 else
759 BX_PANIC(("no dmaWrite handler for channel %u.", channel));
760 }
761 } else {
762 BX_PANIC(("hlda: transfer_type 3 is undefined"));
763 }

From: http://bochs.sourceforge.net/cgi-bin/lxr/source/iodev/dma.cc

It seems(compare block at 747 with block 707), that the DMA verify actually does the same as the mode 1(write to memory)? So my FDC controller hack is actually not a hack: it's a feature of the DMA controller(although incorrect according to the many manuals on the 8237A DMA chips?)?

Edit: Just modified my emulation to do the same(as it fixes FDC emulation anyways on Compaq Deskpro 386). I've also added the DREQ inputs to the Status Register's high bits, thus enabling software to detect Pending DMA transfers correctly(if it looks for that, e.g. a driver testing the hardware by monitoring the bits while having the channel itself disabled to test hardware requests).

Edit: Implementing the DREQ into the Status Register seems to have also fixed the Compaq Deskpro 386 setting up the DMA? The FDC channel is now properly set to 0x46, which is the correct setting 😁 Talking about killing two birds with one stone!

If I'm not mistaken, it's first incorrectly programmed for mode 0x42, then executes a read(which fails?), then before executing the 2nd reads and onwards, it sets the mode register to 0x46, causing the transfer to succeeds from that point and onwards.

Also, since this hack is now no longer needed and the HDC hack has been solved by using a more current BIOS ROM(and flashing it again, which fixes the bugs), the emulator now doesn't require hacks anymore to run it's ROMs! 😁

Edit: Now trying to run the Compaq Deskpro 386 diagnostics(setup) disk(sp0316). It seems to crash somewhere in segment 0061h?
Edit: Looks like some custom IO.SYS that's located at that segment? It executes a few instruction, then jumps to some high address and starts executing 0000h instructions?

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

Reply 55 of 163, by superfury

User metadata
Rank l33t++
Rank
l33t++

I'm now trying to create the two 360K disks(which should work fine on the uninitialized Compaq BIOS, due to only having 40 tracks instead of 80 tracks), but every time I try to execute the disk creation program it tells me it doesn't detect the correct floppy drive? I've tried mounting 360K disks(two in total to create) using Virtualbox as well as Dosbox(The SP0316 disk image set).

Edit: Managed to create the disks by booting into MS-DOS 3.3 using Dosbox Daum, mounting a(dos 3.3 1.44MB with qrst files) directly and the disk to create with "imgmount 1 ./compaq~1.img -t floppy -fs none" and "imgmount 1 ./compaq~2.img -t floppy -fs none".

Then it's just boot -l a and run qrst and write to drive b, restart Dosbox and mount disk 2 instead and then repeat for disk 2 normally.

Now I have two (hopefully bootable) disk images in 360K format(so 40 tracks afaik?), which should have no problems booting on the Compaq Deskpro 386(even when just using a 40-track drive)?

Of course that's assuming they're bootable at all?

Edit: Just found out that the x86 real-mode IRET on all CPUs wasn't running in a cycle-accurate way in real mode(unlike the INT instruction and all other normal instructions), thus running out-of-sync with the other instructions. So it had the potential to finish an instruction while the BIU was still handling something(even reading memory while the BIU wasn't finished writing it). Of course the protected mode variant always runs out of sync, as it doesn't use the BIU for it's work yet.

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

Reply 56 of 163, by superfury

User metadata
Rank l33t++
Rank
l33t++

OK. Having fixed the IRET instruction to use the BIU(in real mode only), the booting of the Compaq 360K disk image created by executing Dosbox Daum with qrst goes very wrong somehow?

CS:IP=FFFF:FFFF
EAX=EBX=ECX=EDX=EBP=FFFF
ESI=8995
EDI=7610
FLAGS=vr0N11ODITSZ0A0P1C(7FD7)
CR0=FFF0
GDTR=Base=F0730h, limit 0047h
IDTR=Base=0, limit=FFFF

Something's going very wrong booting that disk somehow?

Edit: Hmmmm.... Loading the disk1 disk on the PCjs emulator seems to end up in a "Load failure"?

https://www.pcjs.org/devices/pcx86/machine/co … 386/vga/4096kb/

So there might be a problem with the disk somehow? Dosbox 0.74 flat out crashes and quits?

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

Reply 57 of 163, by superfury

User metadata
Rank l33t++
Rank
l33t++

Just tried the image on the latest official PCem version. It also seems to do nothing when booting the disk? So the disk itself is invalid somehow? I've gotten the disk from the original location on the HP website? ftp://ftp.hp.com/pub/softpaq/sp0000-0500/sp0316.zip

There's also the 720KB version(ftp://ftp.hp.com/pub/softpaq/sp0000-0500/sp0308.zip), but that wouldn't run due to issues with the default FDC configuration(it's configured for 40 tracks afaik, since 80 tracks times out seeking).

The 360KB version is the one I'm using now, but it doesn't seem to boot? If even PCem fails booting(and Dosbox quits without any message), does that mean the disk is invalid to boot from?

Edit: Just tried booting a MS-DOS 3.3 boot disk(360K, which boots fine), then on the B drive(diagnostics 360K disk 1) run test.com, which shows the app, eventually shows that three settings aren't set up(memory fail, date/time not set and another one that disappears after reboot. The BIOS itself doesn't give any errors during booting(except uninitialized and needs diagnostic disk for setup):

469-Deskpro 386 diagnostics disk 1.jpg
Filename
469-Deskpro 386 diagnostics disk 1.jpg
File size
32.38 KiB
Views
1629 views
File comment
First screen of the diagnostics(after test.com white screen with loading text or launching setup program directly).
File license
Fair use/fair dealing exception
469-Deskpro 386 diagnostics disk 1-part2.jpg
Filename
469-Deskpro 386 diagnostics disk 1-part2.jpg
File size
28.1 KiB
Views
1629 views
File comment
Pressing enter reveals this.
File license
Fair use/fair dealing exception
469-Deskpro 386 diagnostics disk 1-part3-thenreboots.jpg
Filename
469-Deskpro 386 diagnostics disk 1-part3-thenreboots.jpg
File size
35.11 KiB
Views
1629 views
File comment
Final screen, then reboots with normal BIOS and request for diagnostic disk.
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 58 of 163, by superfury

User metadata
Rank l33t++
Rank
l33t++

OK. Running the Compaq VGA configuration on the PCjs machine, with the disk in the B-drive and executing the test.com then inspect.com will display proper information there and won't reboot. Although it's setup.exe(or launched from test.com) will give some warnings about memory layout somehow.

But at least that means that, although the disk image isn't bootable(afaik), it's files are valid(although giving different results on UniPCemu at least, maybe due to CPU bugs?).

In UniPCemu, the inspect.com tells me to run setup.exe only, while the setup.exe complains about the memory device, then reboots(resolving nothing)?

Edit: Just tried running qrst to create the drives properly within UniPCemu. It tells me it doesn't have a valid drive to write to(even through it's an emulated 40-track drive in the B-drive)?

I'm now reconfiguring the AT from scratch(using the diagnostics disk that I originally used with it). So far, trying to answer N at the initial prompt causes it to give an error and execute an interrupt, triple faulting, then hanging somehow after that(executing past offset FFFF)?

Although, the part it's executing executing that(after answering 'n' on the intial question of the setup wizard), is executing in protected mode(CR0=0001)?

Answering y(es) will somehow now result in a infinite(/hanging) system board error(s)?

472-AT System error 0152 on Diagnostics.jpg
Filename
472-AT System error 0152 on Diagnostics.jpg
File size
52.64 KiB
Views
1624 views
File comment
Diagnostics on the AT (v2.00).
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 59 of 163, by superfury

User metadata
Rank l33t++
Rank
l33t++

Now comparing the commit of 20180129_1124 to the current commit. Somewhere in there, the above error must be caused somehow?

Edit: I see the following changes:
- BIU redesign on waitstates(Timings change a bit).
- IRET becoming cycle-accurate(Same as above).
- Minimized headers included(Reducing changes vs compile times and compilation overhead).
- MMU([.|_])invaddr removed(due to hanging fix).
- 80386+ improving table lookups.
- Improved IRET cycles(Changing timings in real mode IRET a bit).
- Improved POP (E)SP(32-bit support vs 16-bit support and stack).
- ModR/M once checking only(Improving speed theoretically).
- Improved RTC hour encoding/decoding and 12-hour format and century encoding to allow non-BCD values(cleaned up XT code).
- Improved DMA with high 4 bits of the status register(DREQ inputs), applied unknown(default) cases, Verify becoming write to memory(according to Bochs).
- Floppy command set has been completed with missing 82072AA commands(Scan, Verify, Read/Write Deleted Data(same as normal commands), Lock up conditions(Sense Interrupt without interrupt).
- ATA Drive Seek Complete status bit improved, Features 0x66(Reset doesn't set Defaults)/0xCC(Reset sets Defaults(multiple sectors becoming 0)) conditions added.
- Keyboard PS/2 port enable/disable improved not to reset the keyboard itself(clearing it's output buffer, causing loss of data reading the scancodes(it was clearing buffer after each byte read)).
- 32-bit instructions improved and fixed according to/using the tables.
- Unused header removed.
- Improved Compaq BIOS ROM vs protected memory area at FE0000-FFFFFF and E0000-FFFFF to work fully.

Those are all the changes that I've implemented since then(when I reported it was working somehow).
Edit: Just tried the commit from back then: it crashes, oddly enough, as well?
Edit: Just found a setting in the Settings menu that was configured oddly(probably since messing with the Compaq Deskpro 386 emulation): The video synchronization was set to be depending on the old host synchonization method(maximizing the refresh rate depending on the emulated CPU speed VS realtime speed, old synchronization method(the new method does a better job, actually granting the CPU 50% of the time available and 50% to the VGA for maximum emulation speed(theoretically), by automatically determining how many pixel clocks per second to execute on the video card emulation to allow the CPU to reach at least 50% speed)).
Edit: It seems that setting wasn't the cause. Maybe just the new method of emulating the BIU?

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