stardot / b-em

An opensource BBC Micro emulator for Win32 and Linux
http://stardot.org.uk/forums/viewtopic.php?f=4&t=10823
GNU General Public License v2.0
112 stars 56 forks source link

B+128K hanging inside DFS waiting for NMI-related stuff #200

Open ZornsLemma opened 1 year ago

ZornsLemma commented 1 year ago

If I set b-em to B+128K mode, boot the attached game, select mode 3 at the menu and press SPACE to run the game, it hangs consistently on move 395. (Run it at 500% speed to get there quicker!) Breaking into the code in the debugger, it is stuck inside DFS 2.26 at &8E64/&8E66, which appears to be a loop waiting for the NMI handler to do something.

The problem seems to be very timing sensitive; if I add or remove a sideways RAM bank on the emulated machine (which will change the precise pattern of instructions executed by the game and the amount of disc access) it goes away. I don't have a simple test case either, just the attached rather complex game. I can't therefore completely rule out this being due to some kind of bug in the game, rather than the emulator.

The saving grace is that, for me at least, it is 100% reproducible with the attached game.

I've bisected this and I think the problematic commit is c269c75a76b7a74c8565df2294a4ac32359f0486. Building that commit, I always get the hang on move 395. Building the previous commit (23e34b58bef135e7603101fda324c52c86f1f389), the game runs to completion (move 449).

hollywoo.zip

Just for the record, this disc image was built using commit 8dfcd73f85791d172e83c131570c3b3b54a06e28 in my Ozmoo repo (https://github.com/ZornsLemma/ozmoo) and then the LOADER BASIC program manually tweaked to omit /FASTSCR and the PROCpoke() line before it, and to use 0 rather than the value FNpeek() returns in the line after /FASTSCR.

SteveFosdick commented 1 year ago

I just tried this with the current master and it ran to completion. How many sideways RAM banks should I have to reproduce this?

ZornsLemma commented 1 year ago

I just built current master (41748aefd09504aa72751376616d651723b78949) and it still locks up for me on move 395. Did you make sure to select mode 3? You probably did but I thought I'd check.

This is with RAM in banks &0, &1, &C and &D, as well as the B+ private RAM (which the game loading screen reports as bank "P"). For what it's worth, my emulated B+128K reports "Acorn OS 128K" on first starting up, but pressing CTRL-BREAK (without running anything from disc) then shows a banner of "Acorn OS 144K", which persists until I use File->Hard Reset, and I don't know why. Looking at the b-em ROM menu there are only four banks, and the game's own auto-detection of sideways RAM agrees. BASIC 2 is in bank &F, VDFS in &E and DFS 2.26 in &B.

Again FWIW, $HOME/.config/b-em/b-em.cfg says:

[model_09]
name=BBC B+ 128K
fdc=acorn
65c02=false
b+=true
master=false
modela=false
os01=false
compact=false
os=bpos
tube=none
romsetup=bp128
rom15=basic2
rom14=vdfs
rom11=dfs226
SteveFosdick commented 1 year ago

Thanks, I found why I could not reproduce it - my B+128K model had the Graphics Extension ROM in. Removing that it locks up as described.

SteveFosdick commented 1 year ago

Ok, I can see one thing that may be causing an issue: the counter to spin down the disc is expiring before the counter for the seek to complete. Once the drive motor is off, 6502.c no longer calls the fdc callback function so there are no more status changes, including the one DFS is waiting for. I am a little puzzled as to why that commit causes it. I will have to leave it there for an hour or so but will see what I can do later.

ZornsLemma commented 1 year ago

Thanks for taking a look at this, much appreciated!

SteveFosdick commented 1 year ago

Ok, see this branch: https://github.com/stardot/b-em/tree/sf/issue200

The times for each of the counters seemed reasonable but it seems depending on the order of commands, the disc spindown can not be set for some time. It is also worth noting the 1770 is being given the longest seek time of 30ms. There was a change at some point to try to make those more realistic, yet I think most people would have set it a little shorter than that. This can be done on B-Em with the kbdips config key.

ZornsLemma commented 1 year ago

Thanks! I've built that branch and (although you've probably tested it yourself) the hang is no longer reproducible. I will keep using this build for my ongoing development work and will make a point of using the B+128K a bit more than I otherwise would (although I suspect it's mainly luck and this could happen on any machine with a 1770).

I didn't know about the kbdips option, it might be interesting to play with that at some point when I'm benchmarking.

Incidentally the emulated B+128K is still exhibiting the odd behaviour where it shows "Acorn OS 128K" on first boot but "Acorn OS 144K" on subsequent CTRL-BREAKs. This is hardly a showstopper but it does seem kind of wrong to me. That said, I am assuming a real B+ doesn't do this, but maybe it does. Should I raise a separate issue for this or is it just not worth worrying about?

SteveFosdick commented 1 year ago

On the amount of memory, I noticed that the game reported 75K of sideways RAM, IIRC, which seemed odd. I wonder if this has the same cause as the OS RAM message.

ZornsLemma commented 1 year ago

Oh no, that's just an Ozmoo quirk. :-) It's 64K of normal sideways RAM plus the 12K private RAM, but the last 512 bytes of private RAM is used by Ozmoo for storing some code (instead of game data) so it's treated as 11.5K of private RAM, and rounded down in the amount reported by the loader - int(64+11.5)=75.

I do it this way on some vague consistency grounds to make it "easier" to compare available RAM across different machines, but as I try to explain it here I'm starting to feel it's maybe not all that helpful and it would be better to just report it as 12K. I'll have a think about this, cheers!