Hi.
I noticed that Civilization 2 has several problems under Wine. First, the game wants to access memory using segment register value zero, which causes protection exception since that is not allowed in protected mode. Second problem is that the game uses segment register value 0xf8, which Wine does not like.
If I drop null-pointer protection [call to DOSMEM_Init(TRUE)], emulate cmp and mov commands so that they work even if using segment register value zero [added stuff to memory/instr.c] and make Wine accept segment register value 0xf8 [by hacking INSTR_ReplaceSelector], Civilization 2 starts to work without any problems.
There are several possible reasons why the above changes make the game work: Wine corrupts segment registers somewhere, Civilization 2 wants to use privileged commands and Windows emulates them or the game runs in VM86 mode under Windows.
So, I would like to get some ideas what should be done with Wine in order to get the game working.
Oh, the above modifications fix protection faults that happen when the game tries to access the following addresses: 0x22, 0xc8, 0xf6, 0xf07c and 0xf0aa.
P.S. Civilization 2 seems to work almost perfectly but it is painfully slow. I am pretty certain that I know the reason for this, but I would like to get the game working under official Wine before trying to make it run faster.
On Mon, 19 Nov 2001, Jukka Heinonen wrote:
I noticed that Civilization 2 has several problems under Wine. First, the game wants to access memory using segment register value zero, which causes protection exception since that is not allowed in protected mode.
It doesn't really *want* to, but there's some bug or unimplemented feature in Wine that causes it to fail to initialize a certain pointer. From what I recall, this pointer would be stored as extra window data using Get/SetWindowLong, but I didn't find out why it didn't get initialized.
Second problem is that the game uses segment register value 0xf8, which Wine does not like.
Couldn't this be a result of the uninitialized pointer?
It doesn't really *want* to, but there's some bug or unimplemented feature in Wine that causes it to fail to initialize a certain pointer. From what I recall, this pointer would be stored as extra window data using Get/SetWindowLong, but I didn't find out why it didn't get initialized.
I guess you mean the place where the program wants to call GetWindowLong16 using offset value 10 even though there are only 12 bytes of data available? If I convert offset to 8 in this case, I get rid of a single memory fault. Unfortunately, this does not have any impact at all to the rest of the about dozen memory faults... Looking at relay traces, I see no indication that the program gets other invalid pointers from GetWindowLong.
It would be possible to trace the program execution backward from the faulting instruction and find out the exact place where the illegal segment value gets defined. I'm not sure that I want to do something that boring and tidious, though. I just wish that I didn't have a handful of other games that need to be played using hacked Wine versions because I haven't found out what the real problem is :(
Oh, DeusEx, Pharaoh, Colonization and Civilization 2 do work under Wine after some hacks, but I feel a bit depressed that I have no idea what the real problem with those games is. And I have utterly failed to get half a dozen other games work.