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

Strange behaviour when setting Master RTC #181

Open ZornsLemma opened 1 year ago

ZornsLemma commented 1 year ago

I don't know if this is a bug or not, but it seems weird and I'd appreciate your thoughts on it. Using commit dfa9d7c26aace3f20baadbd3c656426059e58a26, the attached test program seems to behave oddly - when setting the time to 05:00:00, it comes back as 06:00:00. This happens with both OS 3.20 and 3.23: time-set-quirk-3 20 time-set-quirk-3 23

The first (OS 3.20) screenshot also shows setting the time to 00:00:00 seeming to actually set it to 23:00:00 the previous day. I don't think this always happens and I don't think it's actually a real difference between OS 3.20 and 3.23, but I may be getting confused.

I did wonder if this is something to do with the US-oriented daylight savings time support in the emulated RTC chip, but I have not done anything explicit to fiddle with the RTC registers, and looking at the datasheet for the CDP6818 (just because I have a copy handy, not because I think that's what the Master uses) it says the daylight saving change happens on the last Sunday in April/October, which doesn't match what I'm seeing here.

The test program sets the day of the week to Wednesday, which isn't right - 26/03/2000 is a Sunday - but I don't think that's the issue here.

time-set-quirk.zip

ZornsLemma commented 1 year ago

I don't know if it's related or not, but I've noticed another quirk. Setting just the date appear to knock the time backwards: set-date-screenshot Note that the time is 12:35:06 to start with, but after the date set operation it's jumped back to 12:34:56.

ZornsLemma commented 1 year ago

Sorry for the spam, but I noticed something else strange: set-date-screenshot-2 It looks as though the RTC stops updating after it's been written until the next read occurs. Note that we set the time to 23:00:00, wait ten seconds and print it, and it's still 23:00:00. But it's now running again, and waiting another ten seconds shows 23:00:10.

SteveFosdick commented 1 year ago

This will probably need some further investigation but a couple of points occur to me.

When setting the RTC the value is stored as an offset from the host OS system time rather than as an absolute value. That means that when the emulator is stopped and later restarted time will continue to advance just like on real hardware because the RTC emulation will apply the stored offset to the new system time when restarted. That also means the RTC should usually be correct even if you never set it.

So this first issue is probably some issue with DST handling in gmtime/localtime/mktime.

SteveFosdick commented 1 year ago

Then the RTC not advancing when it should be a side effect of something done to support the Integra B which does some more advanced stuff with the RTC than the Acorn MOS.

ZornsLemma commented 1 year ago

Thanks Steve. For what it's worth, I was playing around with this as I've been looking into adding OSWORD &F support to the Integra-B's IBOS. I wrote some test programs to exercise the functionality and was running them on an emulated Master to debug the tests before I started writing the IBOS OSWORD &F code. The RTC was probably set correctly before I started fiddling (although I seldom care about it under emulation anyway) - I wasn't trying to set it because it was wrong, just to experiment with OSWORD &F.

You can see my test cases on github at https://github.com/ZornsLemma/IntegraB-OS/tree/osword-0f/test (osword0f-*.bas) in case they're helpful for this, but right now I don't know if the tests themselves are valid, as the only thing I can run them on is b-em and so the bugs could be in my tests or in b-em.

b-em deserves credit for trying to support this at all. I had a quick go with jsbeeb and beebjit and it doesn't look like either of them emulate the RTC; at least with jsbeeb setting it seemed to have no effect, and beebjit explicitly gives debug output saying this isn't implemented.

SteveFosdick commented 1 year ago

I have pushed a fix to the first sub-issue, the hour offset: https://github.com/stardot/b-em/tree/sf/issue181

On the question of US DST behaviour, this is not emulated accurately as it doesn't seem very useful. Instead we assume the values being set are in local time and DST is either in force or not according to the rules in the host OS used for mktime/localtime for the current timezone.

ZornsLemma commented 1 year ago

Thanks Steve, I've just given that a test and the latest version of my osword0f-c.bas test now gets further; using OS 3.23, it goes wrong on 1st October 2000 but that's an improvement on going wrong in March, and this may be well be caused by one of the other issues we've been discussing here. (And just to repeat, these tests themselves might be buggy, of course.)

I agree the US DST behaviour isn't worth emulating accurately. I only brought it up as a possible cause of the strange behaviour I was seeing in case it turned out to be part of the problem.

SteveFosdick commented 1 year ago

I have pushed another commit that deals with just setting the date.

ZornsLemma commented 1 year ago

Thanks Steve, I think - I must admit I'm getting a bit confused about which tests failed in exactly which ways - that has improved the osword0f-b.bas test, which used to fail because the time changed when it shouldn't. It still failed on 1st October 2000 but it's better than it was.

SteveFosdick commented 1 year ago

I have pushed some more commits. I think this solves all the issues. I was expected the October one to be DST-related but it was actually a result of doing the -1 to adjust from 1-based values in the RTC chip to 0-based in the POSIX struct tm to a BCD value when it should have been done to the binary value. October is the first month to use the upper BCD digit where that starts to make a difference.

ZornsLemma commented 1 year ago

This looks good, with e67722f859f0ee0df74c12fa71d69f7044411c94 an emulated Master with OS 3.23 passes all my OSWORD &0F tests. Thanks very much for taking a look at this, especially given how obscure a feature it is!