joncampbell123 / dosbox-x

DOSBox-X fork of the DOSBox project
GNU General Public License v2.0
2.77k stars 381 forks source link

a game cannot run #2971

Closed 280696516 closed 3 years ago

280696516 commented 3 years ago

Code of Conduct & Contributing Guidelines

Have you checked that no other similar bug report(s) already exists?

What operating system(s) this bug have occurred on?

win10

What version(s) of DOSBox-X have this bug?

0.83.18 SDL

Describe the bug

liao.zip execute play.bat, then black screen.

Expected behavior

No response

Steps to reproduce the behaviour

dosbox.conf [autoexec]

Lines in this section will be run at startup.

You can put your MOUNT lines here.

mount c ./liao c: PLAY.BAT

Used configuration

No response

Emulator log

No response

Additional context

No response

grapeli commented 3 years ago

Does not work with intermittent settings. I was curious because even with dosbox-0.65 it works fine.

The (very) old versions of dosbox-x work fine. Has stopped working since this commit.

f986c6cfb4e60afeb7f37015f5883fad35d662cf bad #v0.801 f1d10dbea0294b4fdf50f4cb18ab544934f80592 bad #mount command now accepts -q option to not print anything unless error. 45ab8926c7aac8712df3af2fab5a27916c851fb0 bad #-debug switch at startup ec382ea9ffa2ee9784b05765ef9c0642d909dded bad #add date, update intro text. add code to auto-patch VS2008 config.h. fea484d43a50655f4f6154dc6ae44060da3784f8 good #new code to generate version string d682534b9cd80c7ddb2324f47a4dbf08a782c4af good #if misc at debug loglevel, print SDL video state 6ba2abd942920bc343f48dfb6f874971e15c20c4 good #

Edit: Oh, this commit doesn't have much to do with the game not working. It has changed in that it does not find the $HOME/.dosbox/dosbox-0.800.conf configuration file, it uses the default. Earlier builds used a configuration file that exists - $HOME/.dosbox/dosbox-DOSBox-X.conf.

grapeli commented 3 years ago

After these code changes, it stops starting up. d548d1eb #Remove mainline mapping and adapter rom as ram option, var, code branches (cleanup) 016872b0 #remove mainline compatible DOS and BIOS mapping, adapter ROM as RAM options, deprecate internal state

https://user-images.githubusercontent.com/452325/137099345-979223c6-d20b-4e24-82df-a75812a48b92.mp4

Allofich commented 3 years ago

After these code changes, it stops starting up. d548d1e #Remove mainline mapping and adapter rom as ram option, var, code branches (cleanup) 016872b #remove mainline compatible DOS and BIOS mapping, adapter ROM as RAM options, deprecate internal state

I tried building with the commit immediately prior to those (https://github.com/joncampbell123/dosbox-x/commit/a8fea61b6ab8af7455794156a4ead89b2b716a42) but the game still does not start (I used no .conf file, so default settings). Do you have to change some setting in the .conf file?

I tried with the Visual Studio x64 SDL1 build.

grapeli commented 3 years ago

@Allofich I used this configuration file. It works fine under it (last good a8fea6). good.conf.txt

Allofich commented 3 years ago

Thanks, but I tried that .conf file with that commit, but it still doesn't work for me. It hangs at a black screen or at a black screen with a couple lines of garbage pixels. Maybe there is an issue with Visual Studio builds as well.(edit: was an issue with loading .conf files, see comment below)

Edit: Above I tried with the x64 SDL1 build. I just now tried with the x64 SDL2 build and in addition to hanging, it also got stuck on a long PC speaker beep.

grapeli commented 3 years ago

The x86_64 sdl1 and sdl2 versions work under linux with this configuration. The key option is:

[dosbox]
mainline compatible bios mapping = true

with mainline compatible bios mapping=false does not start.

Allofich commented 3 years ago

Even with mainline compatible bios mapping = true the build I made from a8fea61 won't start for me, but DOSBox SVN (r4466, default settings) does start.

Allofich commented 3 years ago

@grapeli I found why it didn't work for me. Seems that the old version of DOSBox-X doesn't read .conf files the same way. Normally I just put a dosbox-x.conf file in the same directory as dosbox-x.exe, but the version I built from a8fea61 wouldn't do this. I was able to load the .conf file you provided by starting dosbox-x.exe as dosbox-x.exe -conf (filename), and then it did work.

Allofich commented 3 years ago

I found the line that caused this game to stop working.

In bios.cpp, in https://github.com/joncampbell123/dosbox-x/commit/d548d1eb222d9702a69a9dfc575f86556fe40d3b

if (!IS_PC98_ARCH && mainline_compatible_bios_mapping) { /* mapping BIOS the way mainline DOSBox does */
    ...
    BIOS_DEFAULT_HANDLER_LOCATION = RealMake(0xf000,0xff53);
    ...
}

the conditions were removed and the BIOS_DEFAULT_HANDLER_LOCATION line was changed to BIOS_DEFAULT_HANDLER_LOCATION = PhysToReal416(ROMBIOS_GetMemory(1/*IRET*/,"BIOS default handler location",/*align*/4));

Changing BIOS_DEFAULT_HANDLER_LOCATION = PhysToReal416(ROMBIOS_GetMemory(1/*IRET*/,"BIOS default handler location",/*align*/4)); to BIOS_DEFAULT_HANDLER_LOCATION = RealMake(0xf000,0xff53); in the current code (cf2bc9e) will allow the game to start.

Allofich commented 3 years ago

The mainline compatible BIOS mapping set BIOS_DEFAULT_HANDLER_LOCATION to F000:FF53. Current DOSBox-X with default settings sets it to F000:FF9C.

grapeli commented 3 years ago

@Allofich After this code change, the game finally starts.

I wonder if there are other games (programs) that refuse to start with this bios mapping (F000:FF9C). Is it an individual case.

This log message is not relevant. ERROR EXEC:stack outside memory block at EXEC

joncampbell123 commented 3 years ago

A game refuses to start because of a change in location for default handler?

That doesn't sound right.

Is there something in the codebase leftover from SVN that assumes F000:FF53?

joncampbell123 commented 3 years ago

???

This game REALLY DOES hardcode F000:FF53!

Note at this point DS=0000 BX=0070 (therefore DS:BX points at INT 1Ch).

0816:00007BD9 1E                  push ds
0816:00007BDA 31C0                xor  ax,ax
0816:00007BDC 50                  push ax
0816:00007BDD 1F                  pop  ds
0816:00007BDE B853FF              mov  ax,FF53
0816:00007BE1 8907                mov  [bx],ax                ds:[0000]=20CD
0816:00007BE3 B800F0              mov  ax,F000
0816:00007BE6 894702              mov  [bx+02],ax             ds:[0002]=9FFF
0816:00007BE9 1F                  pop  ds
0816:00007BEA FB                  sti

Is F000:FF53 a known magic address? Sort of like how you could used to be able to assume the 8x8 font was at F000:FA6E.

joncampbell123 commented 3 years ago

This isn't self-modifying code, you can see it in the raw bytes of the UK.EXE file:

0000000000007AF0 E9 35 85 FA 5B 01 DB 01 DB 1E 31 C0 50 1F B8 53 0000000000007B00 FF 89 07 B8 00 F0 89 47 02 1F FB E9 1A 85 E8 17

Allofich commented 3 years ago

It does at least appear to be an actual DOS-period game (and not, for example, something made in recent years to run on DOSBox or something like that). The name is 聊齋誌異之幽谷傳奇. (Liáozhāi zhì yì zhī yōugǔ chuánqí)

According to douban.com/game/26370502/, it was released on Jan. 20, 1993. There was also at least one other site claiming a 1993 release date.

I also kind of wonder whether the game's title sequence is running correctly. If you let it sit for a bit it will get to the title, then do a wavy effect on it, but it seems to sit there with the wavy effect going for a long time. It might just be like that, though. DOSBox SVN has the same behavior.

Allofich commented 3 years ago

Searching for "F000:FF53" does turn up a number of sites suggesting it should point to an IRET.

https://titanwolf.org/Network/Articles/Article?AID=48afccb8-8557-42b8-a943-c63c58bb091f#gsc.tab=0 talks about it being a dummy IRET in the Bochs emulator.

https://groups.google.com/g/alt.comp.bios/c/nkvZQrlvhbI calls it "IRET routine" and "IRET routine for no video card found"

https://github.com/skiselev/8088_bios/blob/master/bios.asm has F000:FF53 as one of many "Fixed BIOS Entry Points".

joncampbell123 commented 3 years ago

Here on Linux, using the latest code in SVN, I see an opening sequence with a very low frame rate (seems like 4 frames/second), then a title that draws on the screen just as slow, then a wavy effect that will run (even a long time) until you hit spacebar.

Allofich commented 3 years ago

Yes, I also saw that, and similarly wondered about the slow intro and the long wavy effect. I didn't mention the low frame rate because the animations have few frames, so I thought maybe they are supposed to look like that, although I felt like the title was slow to be drawn to the screen.

Allofich commented 3 years ago

Someone quotes the same list of fixed BIOS addresses as that github link here as well: https://www.vcfed.org/forum/forum/genres/pcs-and-clones/1215993-fixed-addresses-in-the-bios-what-program-still-uses-them

Allofich commented 3 years ago

Current DOSBox-X code, default settings, sets BIOS_DEFAULT_INT5_LOCATION to F000:FF98. If it should be the fixed entry address of that list F000:FF54 INT 05 (Print Screen) Entry Point then it may be incorrect.

Allofich commented 3 years ago

https://www.pcjs.org/documents/books/mspl13/msdos/encyclopedia/section4/ Assuming this is correct documentation for MS-DOS machines, it shows the address of INT5 in the interrupt vector table at 0000:0000 as F000:FF54 (do a search for "F000:FF54" on that site and it will come up), whereas in DOSBox-X it is F000:FF98.

Edit: INT8 also differs. F000:FF84 in DOSBox-X, F000:FEA5 in the list being cited. They might all be different. But then, the pcjs.org link above shows this "fixed address" value as 0AE3:0395 (if I am reading it right), so maybe I am misunderstanding something.

Allofich commented 3 years ago

Another one. BIOS_DEFAULT_RESET_LOCATION was changed in d548d1e from F000:E05B and currently gets set to F000:FFA0, but according to the first poster at https://www.vcfed.org/forum/forum/genres/pcs-and-clones/1215993-fixed-addresses-in-the-bios-what-program-still-uses-them:

The various IBM PC/XT BIOSes use quite some fixed addresses for certain routines. The most well known one is the address 0E5Bh, the first address where the CPU far jumps to after an hard reset or a power-up. I noticed that most BIOSes I ran into use this address as well. Sergey Kiselev's BIOS, one of the newest I know of, is using this address and many others as well. The most well known (more or less) IBM compatible PC that doesn't use this address is the IBM PCjr.

They say "0E5Bh", but they probably meant E05Bh, the value used by DOSBox SVN and in the list of fixed addresses as the "POST Entry Point".

Allofich commented 3 years ago

Regarding BIOS_DEFAULT_RESET_LOCATION and its difference between IBM compatible PC and PCjr, here's what looks like a nice test case: https://www.vogons.org/viewtopic.php?t=50417

Pitstop II checks whether the byte at F000:FFF2 is 00. On the IBM PC and all machines that claim 100% IBM PC compatibility, F000:FFF0 will contain the instruction JMP F000:E05B, so F000:FFF2 will be E0. Only the PCjr jumps to F000:0043, so F000:FFF2 will indeed be 00. Because DOSBox does not emulate this particular method of PCjr detection, Pitstop II's PCjr graphics support goes unnoticed in DOSBox. (There is however at least one hacked version of the game out there which replaces the detection code with the more conventional model id query.)

DOSBox-X currently has JMP F000:FFA0 at F000:FFF0, to jump to its BIOS_DEFAULT_RESET_LOCATION, but I gather from this that PCjr probably should use F000:0043 as its BIOS_DEFAULT_RESET_LOCATION value.

Edit: Looks like SVN already does this for PCjr because of this VOGONs post. They appear to have not done the suggested change for Zaxxon, though.

joncampbell123 commented 3 years ago

@Allofich Fixed locations are fine, be aware that they need to be marked off as taken so the BIOS allocator doesn't give it away and let something else overwrite it.

Allofich commented 3 years ago

@joncampbell123 I'm taking a look at it.

Also, there is more to fixing the game than just that BIOS address. I found that if loaded after booting from an MS-DOS image, it plays MIDI music in the intro, whereas it has no music if loaded from the DOSBox-X environment. Perhaps related to having music, it will run a lot faster on auto cycles as well, compared to how it runs in the DOSBox-X environment. I had to limit the number of cycles to slow it down.

https://user-images.githubusercontent.com/19624336/137635997-ff38ac7e-ba63-40cc-b55f-3e6897db20c9.mp4

joncampbell123 commented 3 years ago

In working on the ROM BIOS allocator, I fixed a bug that claims the entire free block for an allocation just because the start (if bottom up) or end (if top down) matches. But also, I added a parameter to the allocator that limits top down dynamic allocation to below a limit. IBM PC mode sets it to only fixed allocations are allowed at F000:E000 or higher, since that the size of the BIOS on the original 5150 if I remember correctly and where most of the fixed addresses reside.

@Allofich submitted a pull request which is not exactly mergeable but I'm incorporating it into my work now.

Allofich commented 3 years ago

The original problem that the game cannot run should now be fixed in the latest code, but there is still an issue of missing music when launched from the DOSBox-X environment.

This game is also without music when played from the DOSBox environment in DOSBox SVN.

Allofich commented 3 years ago

When the music starts playing when the game is started from MS-DOS, log messages like

PIT:PIT 0 Timer at 170.4546 Hz mode 3 PIT:PIT 0 Timer at 18.2065 Hz mode 3 PIT:PIT 0 Timer at 96.0076 Hz mode 3

appear in the log. These are absent when running from the DOSBox-X environment.

Also, when exiting the game in the MS-DOS environment, the log shows

WARN MISC:Interrupt vector changed on 15 (null) WARN MISC:Interrupt vector changed on 1C (null) WARN MISC:Interrupt vector changed on 70 (null) WARN MISC:Interrupt vector changed on 19 (null) WARN MISC:Interrupt vector changed on 76 (null) WARN MISC:Interrupt vector changed on 77 (null) WARN MISC:Interrupt vector changed on E (null) WARN MISC:Interrupt vector changed on 1B (null)

The DOSBox-X environment only shows

WARN MISC:Interrupt vector changed on 1C (null)

I've also gotten a message about "changed on 1B" in the DOSBox-X environment, when I closed DOSBox-X while the game was still running.

joncampbell123 commented 3 years ago

If you ask DOSBox-X to print debug information, one debug message in the timer emulation will state whenever the game changes the timer tick rate.

DOSBox SVN does the same thing.

DOSBox-X only modified that debug message not to print it again if the game writes the same countdown value as last time to avoid many repetitions of the same message. Some applications write a counter value repeatedly, especially mid-to-late 1990s demoscene stuff, for some precise timing needs.

That can be done with the 8254 without disturbing the current timer tick as long as you don't write the mode byte first. The current timer tick will run it's course and then the one written will take effect.

Allofich commented 3 years ago

DOSBox-X only modified that debug message not to print it again if the game writes the same countdown value as last time to avoid many repetitions of the same message.

In

            //please do not spam the log and console if a game is writing the SAME counter value constantly,
            //and do not spam the console if Mode 0 is used because events are not consistent.
            if (p->cntr != old_cntr && p->mode != 0)
                LOG(LOG_PIT,LOG_NORMAL)("PIT 0 Timer at %.4f Hz mode %d",1000.0/p->delay,p->mode);

I experimented with commenting out the condition, but the game does not write the same value over and over when run through the MS-DOS image with music playing (the initial messages appear, and they appear when the music restarts, but they are not constantly spammed). When running from the DOSBox-X shell (not loading an MS-DOS image), the game doesn't write to the PIT 0 timer at all (no log messages appear).

Allofich commented 3 years ago

When run in an MS-DOS environment, UK.EXE loads MUSIC.OVL during startup. MUSIC.OVL contains the code to write to the PIT timer. MUSIC.OVL is loaded by UK.EXE during startup with with INT 21 AH=4B03 (overlay flag).

When run in the DOSBox-X environment, the INT 21 AH=4B03 call is made but MUSIC.OVL's contents do not seem to be executed.

You can get to the MUSIC.OVL call by setting BPINT 21 4B in the debugger and running UK.EXE. The debugger will stop once for loading UK.EXE, then the next time it stops is when MUSIC.OVL is being loaded.

Allofich commented 3 years ago

UK.EXE compares byte [444E] to 0. If not 0, it executes MUSIC.OVL.

0BBD:0000848C  cmp  byte [444E],00             ds:[444E]=FFFF         EAX:0004848A EBX:00000000 ECX:00000000 EDX:00000000 ESI:00000026 EDI:000083EA EBP:0000D8C0 ESP:0000D7D2 DS:0BBD ES:212E FS:0000 GS:0000 SS:0BBD CF:0 ZF:1 SF:0 OF:0 AF:0 PF:1 IF:1
0BBD:00008491  je   0000849F ($+c)             (no jmp)               EAX:0004848A EBX:00000000 ECX:00000000 EDX:00000000 ESI:00000026 EDI:000083EA EBP:0000D8C0 ESP:0000D7D2 DS:0BBD ES:212E FS:0000 GS:0000 SS:0BBD CF:0 ZF:0 SF:1 OF:0 AF:0 PF:1 IF:1
0BBD:00008493  push si                                                EAX:0004848A EBX:00000000 ECX:00000000 EDX:00000000 ESI:00000026 EDI:000083EA EBP:0000D8C0 ESP:0000D7D2 DS:0BBD ES:212E FS:0000 GS:0000 SS:0BBD CF:0 ZF:0 SF:1 OF:0 AF:0 PF:1 IF:1
0BBD:00008494  push di                                                EAX:0004848A EBX:00000000 ECX:00000000 EDX:00000000 ESI:00000026 EDI:000083EA EBP:0000D8C0 ESP:0000D7D0 DS:0BBD ES:212E FS:0000 GS:0000 SS:0BBD CF:0 ZF:0 SF:1 OF:0 AF:0 PF:1 IF:1
0BBD:00008495  push ds                                                EAX:0004848A EBX:00000000 ECX:00000000 EDX:00000000 ESI:00000026 EDI:000083EA EBP:0000D8C0 ESP:0000D7CE DS:0BBD ES:212E FS:0000 GS:0000 SS:0BBD CF:0 ZF:0 SF:1 OF:0 AF:0 PF:1 IF:1
0BBD:00008496  push es                                                EAX:0004848A EBX:00000000 ECX:00000000 EDX:00000000 ESI:00000026 EDI:000083EA EBP:0000D8C0 ESP:0000D7CC DS:0BBD ES:212E FS:0000 GS:0000 SS:0BBD CF:0 ZF:0 SF:1 OF:0 AF:0 PF:1 IF:1
0BBD:00008497  call far word [83D5]            ds:[83D5]=0040         EAX:0004848A EBX:00000000 ECX:00000000 EDX:00000000 ESI:00000026 EDI:000083EA EBP:0000D8C0 ESP:0000D7CA DS:0BBD ES:212E FS:0000 GS:0000 SS:0BBD CF:0 ZF:0 SF:1 OF:0 AF:0 PF:1 IF:1
8A6E:00000040  mov  dx,8C82                                           EAX:0004848A EBX:00000000 ECX:00000000 EDX:00000000 ESI:00000026 EDI:000083EA EBP:0000D8C0 ESP:0000D7C6 DS:0BBD ES:212E FS:0000 GS:0000 SS:0BBD CF:0 ZF:0 SF:1 OF:0 AF:0 PF:1 IF:1 (MUSIC.OVL)

In the case of DOSBox-X, byte [444E] is 0000 at the time of comparison, and the code to execute MUSIC.OVL is skipped.

0813:0000848C  cmp  byte [444E],00             ds:[444E]=0000         EAX:0000848A EBX:00000000 ECX:00004B03 EDX:000083AC ESI:00000026 EDI:000083EA EBP:0000D8C0 ESP:0000D7D2 DS:0813 ES:1D84 FS:0000 GS:0000 SS:0813 CF:0 ZF:1 SF:0 OF:0 AF:0 PF:1 IF:1
0813:00008491  je   0000849F ($+c)             (down)                 EAX:0000848A EBX:00000000 ECX:00004B03 EDX:000083AC ESI:00000026 EDI:000083EA EBP:0000D8C0 ESP:0000D7D2 DS:0813 ES:1D84 FS:0000 GS:0000 SS:0813 CF:0 ZF:1 SF:0 OF:0 AF:0 PF:1 IF:1

Maybe the game is trying to check whether there is MIDI available and thinks it is not in the DOSBox-X environment.

Edit: Setting a breakpoint here and manually writing in a non-zero value to byte [444E] does indeed allow MIDI to play in the DOSBox-X environment.

Allofich commented 3 years ago

Seems like the problem is that on the return from the INT 21 AX=4B03 call, AX needs to be 0000. It is 0000 in the MS-DOS environment, and this value is then compared against. If it is not 0, byte [444E] gets set to 0, and no music.

Allofich commented 3 years ago

AX is not 0000 in the MS-DOS environment after returning from the INT 21 AX=4B00 call used to load UK.EXE. (In my case it is 3E01). Same thing happens when starting and exiting EDIT (INT 21 AX=4B00 to enter, AX=3E01 on return).

I wonder if returning 0000 is unique to loading with the overlay flag (INT 21 AX=4B03).

Allofich commented 3 years ago

Running EDIT in the MS-DOS environment, catching it before INT 21 AX=4B00 with a breakpoint, and manually editing it to a INT 21 AX=4B03 call also results in AX becoming 0000 (although it causes a memory allocation error and makes MS-DOS halt). INT 21 AX=4B01 results in AX becoming 0100, with a memory allocation error and system halt.