flat assembler
Message board for the users of flat assembler.

Index > OS Construction > Elapsed time calculator

Goto page 1, 2  Next
Author
Thread Post new topic Reply to topic
neville



Joined: 13 Jul 2008
Posts: 507
Location: New Zealand
neville 21 Feb 2014, 04:24
I want to implement an elapsed time calculator for a FAMOS App I'm writing. In fact, I'm thinking it might also be useful to implement it as a FAMOS service routine.
BTW, FAMOS is implemented in Flat Real Mode (32-bit data, 16-bit code).

The idea is simply to calculate the elapsed time from Start and Finish timestamps (given or measured).

Here are my thoughts so far:
I only want to use integer arithmetic and store/display the results in days/hours/minutes/seconds format.

The CMOS RTC has the hours/minutes/seconds data directly available, but not days. Days must be derived from the remaining data provided by the RTC, which is
- Day of Week
- Day of Month
- Month of Year
- Year of Century
- Century

It is quite easy if I limit the timer to 6days, 23hours, 59mins, 59secs because I can just use the Day of Week register and every week has 7 days!!

But beyond that it seems to me that I will have to store the number of days in each month (and account for leap years) to calculate the number of days precisely, all of which I'm reluctant to do.

Since the RTC does all that stuff internally anyway, I'm wondering if there's a simpler way to achieve it, maybe just using logic on the data in the RTC? e.g. we know a month is a minimum of 4 weeks, and a maximum of 4 weeks and 3 days etc.

Using 1-byte variables I could usefully go up to 255 weeks, 6days, 23hours, 59mins, 59secs (almost 5 years, which would be more than adequate). I don't want to store or display months, years, or anything above weeks, because they don't represent a precise period of time.

Has anybody done anything like this before, or have any other thoughts/suggestions?

PS In case anybody is wondering, yes FAMOS is a lightning-fast OS, but some of the Apps I'm thinking about atm might be very slow!!! I will explain more later.

_________________
FAMOS - the first memory operating system
Post 21 Feb 2014, 04:24
View user's profile Send private message Visit poster's website Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 20430
Location: In your JS exploiting you and your system
revolution 21 Feb 2014, 04:34
Write a routine to convert yyyy-mm-dd into an integer day value from some convenient epoch (like days since 1970-01-01 or something). Then store all times as integers and the arithmetic is easy. If you are not concerned with leap seconds then it is easy and fast to do. If you are concerned with leap seconds then things get a little bit more tricky.

edit: And always use UTC times and only convert to local time for display purposes.
Post 21 Feb 2014, 04:34
View user's profile Send private message Visit poster's website Reply with quote
neville



Joined: 13 Jul 2008
Posts: 507
Location: New Zealand
neville 21 Feb 2014, 05:32
revolution wrote:
Write a routine to convert yyyy-mm-dd into an integer day value from some convenient epoch
Thanks, but that doesn't really seem to solve anything. The "epoch" could always be the Start Time/Date, but to calculate an elapsed time of less than a year would still need all the days of the various intervening months, wouldn't it? And anything over a year still needs leap-years etc. No, I'm not interested in leap-seconds, at least for now Smile
revolution wrote:
And always use UTC times and only convert to local time for display purposes.
I would completely concur, except that I only want to calculate time differences, not absolute times Wink

_________________
FAMOS - the first memory operating system
Post 21 Feb 2014, 05:32
View user's profile Send private message Visit poster's website Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 20430
Location: In your JS exploiting you and your system
revolution 21 Feb 2014, 05:50
That is how you calculate differences by converting YMD to an integer first then compute the difference in the integer space.
Post 21 Feb 2014, 05:50
View user's profile Send private message Visit poster's website Reply with quote
neville



Joined: 13 Jul 2008
Posts: 507
Location: New Zealand
neville 21 Feb 2014, 06:48
revolution wrote:
That is how you calculate differences by converting YMD to an integer first then compute the difference in the integer space.
I know this is how it is often done, and thanks anyway, but it really doesn't address the calculation issue I've tried to describe above.

Actually, given my particular requirements I'm also not convinced that it would actually be the best way of doing it (since a double-conversion back to day/hour/min/sec format would be required for display purposes). My hunch is that a single "multi-base" calculation (i.e. base 60/60/24/7) would be much easier, certainly up to a difference of 7days minus 1second. It's just for differences above 7 days that the complications start to arise, which is what prompted me to start this thread... Wink

_________________
FAMOS - the first memory operating system
Post 21 Feb 2014, 06:48
View user's profile Send private message Visit poster's website Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 20430
Location: In your JS exploiting you and your system
revolution 21 Feb 2014, 07:01
Actually I directly addressed your concern about values above seven days. Converting to a linear measure is going to be so much easier in the long run. The days of 8-bit MCUs with 512B ROMs are long gone and such tricky, and bug-friendly, "special" conversions take more thinking and debugging time than a simple linear conversion.

I like the MS approach of using a 64-bit value that starts at 1601-01-01 and increments at 10MHz. It's good for 30000+ years without an overflow and gives sub-microsecond time differences. The Linux counter of once per second is clumsy and doesn't lead to nice code when sub-second times are needed.
Post 21 Feb 2014, 07:01
View user's profile Send private message Visit poster's website Reply with quote
neville



Joined: 13 Jul 2008
Posts: 507
Location: New Zealand
neville 21 Feb 2014, 08:05
Your Location currently claims "Trust me, I'm from the Internet" and I'd like to trust you, but sorry, I'm unconvinced Razz Because:
1. the integer linear measure I'd have to use is seconds, not days...
2. the conversion still requires the use of a calendar with all the variable numbers of days per month, leap-years etc. Yuk!
(unless some clever person can come up with some viable alternative logic which I think might be possible. Not tricky or bug-friendly logic, just simple elegance is my programming motto)
3. your reference to 8-bit MCU's is a bit unnecessary and irrelevant imo (and perhaps very slightly offensive?). I only mentioned "1-byte" variables because that's all I would need using the method I described i.e. horses for courses. I don't believe in using a qword for a 1-bit flag...
Here's another off-topic reference: Even in these so-called 64-bit and 128-bit days, memory is still commonly measured in 8-bit units Wink

revolution wrote:
I like the MS approach of using a 64-bit value that starts at 1601-01-01 and increments at 10MHz. It's good for 30000+ years without an overflow and gives sub-microsecond time differences. The Linux counter of once per second is clumsy and doesn't lead to nice code when sub-second times are needed.
Again, I'm unconvinced, and I suspect the font size=1 means your tongue is firmly in your cheek. I certainly don't want to implement a calendar back to 1601 AD, and I don't need 0.1 microsecond resolution or the associated M$ software overhead... My counter will probably be at about 18.2Hz which will be more than adequate for my purposes. Cool

_________________
FAMOS - the first memory operating system
Post 21 Feb 2014, 08:05
View user's profile Send private message Visit poster's website Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 20430
Location: In your JS exploiting you and your system
revolution 21 Feb 2014, 08:31
Days per month is a simple table, yes, of 12 values. If that is really going to be a big hardship then I'd suggest that any special code to avoid such a table will be more than 12 bytes.

Leaps years is a computation based upon 100 and 400 year periods. No calendar is required for this. And even the 400 years thing can be ignored if all years are between 1901 and 2099.

Anyhow the upshot here is that there is no need to store a calendar for any reason. You only have the 12 values for the month lengths, the rest is just fixed computed values that can be done in a single concise and simple routine.

Usually an OS will read the RTC once at startup and convert the YMDHMS to an internal linear time. After that everything is easy to compute. Even the 18.2Hz rate can be added to a time variable that counts in 18.2ths of a second (if desired) so it becomes a simple increment. Later when you need to display something convert back to YMDHMS so the user has some real world context.

My reference to 8-bit MCUs was not intended to be offensive, but just to suggest that the old style byte encoding and byte storage and byte increments and different radices and such things are a large hindrance to things like time difference computations. And even byte storage of each individual C, Y, M, D, H, M and S is already 7 bytes, so why not just go to a single qword? Modern CPUs can handle a qword easily Wink And there are no invalid values to deal with like 63 minutes past 27 o'clock. There are no discontinuities. There are no ambiguous overlaps.
Post 21 Feb 2014, 08:31
View user's profile Send private message Visit poster's website Reply with quote
baldr



Joined: 19 Mar 2008
Posts: 1651
baldr 21 Feb 2014, 08:58
neville,

Using 8254 PIT (if I understood 18.2 Hz reference correctly) you may achieve slightly more than 1 µs resolution when needed by reading back timer counter.

----8<----
revolution wrote:
There are no discontinuities. There are no ambiguous overlaps.
Oh really? Can you spell DST? Wink
Post 21 Feb 2014, 08:58
View user's profile Send private message Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 20430
Location: In your JS exploiting you and your system
revolution 21 Feb 2014, 09:04
baldr wrote:
revolution wrote:
There are no discontinuities. There are no ambiguous overlaps.
Oh really? Can you spell DST? Wink
I already mentioned about using UTC. Although you are correct but not in the way you suggest. DST related overlaps and gaps are solved by UTC. But leap seconds are not solved by using UTC. In fact UTC makes dealing with leap seconds more tricky and doesn't solve the one second overlaps, hehe.
Post 21 Feb 2014, 09:04
View user's profile Send private message Visit poster's website Reply with quote
neville



Joined: 13 Jul 2008
Posts: 507
Location: New Zealand
neville 21 Feb 2014, 09:55
Whoa, let's not make bloatware here! You don't need 12 bytes for a table with 12 values each less than 32 (=2^5). 5 bits * 12 = 60 bits so 8 bytes will do it, and you've still got 4 bits spare for flags. Ok, I jest (but hey, M$ DID implement FAT12 for good reasons at the time?), but your byte comparisons might be a bit misleading. My thoughts are that the code needed to use that "month table" in a completely robust way for all possible situations will be a LOT more than 12 bytes! So doing it another way could easily be more efficient. Although even that is not my objective. I go for "elegance" rather than efficiency which of course is much more objective.

When FAMOS is on it's main screen, and displaying the date and time, it is reading the RTC registers continuously. So I guess that means it is an unusual OS in your view. I make no apology for that Rolling Eyes It also reads the RTC directly when creating timestamps for new memory entries etc. I don't see anything wrong with that. The RTC is a perfectly good clock so why re-invent it?

Old-style byte encoding? Large hindrance? Really?? And if you really need to do qword arithmetic, by all means use qwords. But in practice if all you really need to process are bytes or words, I find rotating and shifting to get access to the packed values in a larger word can be far clumsier and more bug-prone than using direct 8-bit or 16-bit registers and arithmetic .i.e AL or AX is often more convenient than using eax or rax. Also 2^64 seconds = 580 billion years and I don't plan on keeping any processes running that long in FAMOS. Wink

Thanks again for your thoughts but we might just have to agree to disagree for now Very Happy Some of this has got a little off-topic but does anybody else have a view or experiences with elapsed time calculators?

_________________
FAMOS - the first memory operating system
Post 21 Feb 2014, 09:55
View user's profile Send private message Visit poster's website Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 20430
Location: In your JS exploiting you and your system
revolution 21 Feb 2014, 10:28
It is indeed unusual to read the RTC "continuously". Going out to the hardware ports and reading stuff from there is kind of hard and slow for a modern CPU to do when compared to doing a few mathematics computations and table lookups.

The FAT12 thing is awful with its two-second resolution and plethora of values that form invalid dates and times.

And the Linux seconds counter is bad, I already mentioned that above. I like the Windows 0.1µs resolution. Seems a good balance between full range extents and small range requirements.
Post 21 Feb 2014, 10:28
View user's profile Send private message Visit poster's website Reply with quote
edfed



Joined: 20 Feb 2006
Posts: 4353
Location: Now
edfed 21 Feb 2014, 10:48
maybe by just building a master timer in the os first
then, using the current timer value as an init value in the process, using the exactlly same structure/routines as the system does

and then, to get the elapsed time, just compute a substraction, using the exact same function as it does in the system.

Code:
FAMOS:
.time dd 0;
;;here, install the .timing routine in the programmable interval timer interrupt, or elsewhere

timer:
.time dd 0
.timing:
     inc [this.time];forgot how it works in asm Wink, but the idea is like this
     ret
.delta:
     mov eax,[FAMOS.timer.time]
     sub eax,[this.time]
     ret
    


the timer is not so hard to implement.
Post 21 Feb 2014, 10:48
View user's profile Send private message Visit poster's website Reply with quote
sinsi



Joined: 10 Aug 2007
Posts: 794
Location: Adelaide
sinsi 21 Feb 2014, 10:58
Maybe a combination of these
Code:
INT 1A - TIME - GET REAL-TIME CLOCK TIME (AT,XT286,PS)
INT 1A - TIME - READ SYSTEM-TIMER DAY COUNTER (XT2,PS)
    

The first gives h/m/s, the second gives days since 1/1/1980
Post 21 Feb 2014, 10:58
View user's profile Send private message Reply with quote
neville



Joined: 13 Jul 2008
Posts: 507
Location: New Zealand
neville 21 Feb 2014, 20:14
baldr wrote:
neville,

Using 8254 PIT (if I understood 18.2 Hz reference correctly) you may achieve slightly more than 1 µs resolution when needed by reading back timer counter.
Yes I was referring to Counter/Timer#2 in the PIT, but mainly as a counter (pardon the pun!) to revolution's argument about the M$-like 10MHz clock. In fact I'm probably going to be happy with 1 second resolution so I won't need to improve it with the help of the PIT Timer2 output.

_________________
FAMOS - the first memory operating system
Post 21 Feb 2014, 20:14
View user's profile Send private message Visit poster's website Reply with quote
neville



Joined: 13 Jul 2008
Posts: 507
Location: New Zealand
neville 21 Feb 2014, 20:25
revolution wrote:
Going out to the hardware ports and reading stuff from there is kind of hard and slow for a modern CPU to do
Thanks, I couldn't agree more!!! Smile In fact, you have just succintly stated the whole raison d'etre for FAMOS, a Memory OS rather than an old slow disk OS like M$ Windows!
"Going out to the hardware ports and reading stuff from there" is of course an accurate description of reading a disk drive, which Windows does ad nauseum, even to the extent of pretending that it is RAM sometimes. Yes, you can mitigate a little of the downside effects with tricks such as caching, pipeline, multithreading, hyperthreading and all the rest, but nothing will change the basic truth of your initial statement. Wink
(It's a bit like pretending that modern IC-engine cars are "low-emission vehicles" when they are still burning hydrocarbons and producing similar and copious amounts of CO2 but lets not go THERE...)
But in FAMOS, reading the RTC continuously to display the date and time has no downside at all, because it is effectively part of the idle loop when the CPU has little else better to do. And it's occasional use to provide a timestamp for new memory entries is of no consequence.
Again, the RTC is a perfectly good clock, so why re-invent it?

Oh, and harking back to your 12-byte month table, since there are only 4 possible values (between 28 and 31) we only need 2 bits per value, so the whole table could actually be just 24bits = 3 bytes! But again, that is NOT the point...
revolution wrote:
The FAT12 thing is awful
Yes again, I couldn't agree more. Awful = inelegant in my book, and for other reasons also.

revolution wrote:
And the Linux seconds counter is bad, I already mentioned that above.
Yes you did mention the Linux counter before. But why is it bad? Just because you think 1 second resolution is inadequate, or for other reasons too?
revolution wrote:
I like the Windows 0.1µs resolution.
You mentioned this before too... Wink But for the record I am not going to implement anything like it! (I think it is irrelevant to me)

_________________
FAMOS - the first memory operating system
Post 21 Feb 2014, 20:25
View user's profile Send private message Visit poster's website Reply with quote
neville



Joined: 13 Jul 2008
Posts: 507
Location: New Zealand
neville 21 Feb 2014, 20:37
edfed wrote:
maybe by just building a master timer in the os first
Oui, merci beaucoup edfed Smile We are on the same page, except that I already have the master timer available in FAMOS - it is aleady built. It' s called the CMOS RTC Wink
edfed's location wrote:
In an open world without walls and fences, we wouldn't need Windows and Gates

So true! I love it!

_________________
FAMOS - the first memory operating system
Post 21 Feb 2014, 20:37
View user's profile Send private message Visit poster's website Reply with quote
neville



Joined: 13 Jul 2008
Posts: 507
Location: New Zealand
neville 21 Feb 2014, 20:44
sinsi wrote:
INT 1A - TIME - READ SYSTEM-TIMER DAY COUNTER

sinsi you are a genious!Cool I think you have just given me an elegant solution to my problem.Idea I had forgotten about the BIOS INT 1A functions. That is one of the many advantantages of working in real mode - the BIOS functions are readily available, and INT 1A function 0A is all I need to call at the start and finish of the timing period to keep track of the number of days. I could also use function 0B to reset the day counter to zero at the start. I probably won't even need to use the RTC's Day of Week function either! Brilliant! Thank you Very Happy

Yes I could also use Int 1A function 02 for H/M/S and dispense with the RTC all together, except that it only provides BCD outputs whereas the RTC also gives a binary option. Also I generally prefer direct hardware access over BIOS functions, especially if the BIOS is accessing the same hardware anyway. Looking at the Alarm functions which are also provided in INT 1A it seems obvious that INT 1A does indeed just access the RTC.

_________________
FAMOS - the first memory operating system
Post 21 Feb 2014, 20:44
View user's profile Send private message Visit poster's website Reply with quote
neville



Joined: 13 Jul 2008
Posts: 507
Location: New Zealand
neville 21 Feb 2014, 23:35
sinsi it was a good thought, but unfortunately INT 1A func 0A doesn't work on the first machine I tried it on Sad It returns no data, and sets the C flag. Further research suggests it may only be in PS/2 systems. What a pity Sad

_________________
FAMOS - the first memory operating system
Post 21 Feb 2014, 23:35
View user's profile Send private message Visit poster's website Reply with quote
BAiC



Joined: 22 Mar 2011
Posts: 272
Location: California
BAiC 22 Feb 2014, 03:56
Quote:

I could also use function 0B to reset the day counter to zero at the start.

modifying the global state to "optimize" your particular code is the entire reason that the x86 has "Protected Mode". they're protecting the system FROM YOU! Do you have ANY consideration for the other programs that are running? all you have to do is evaluate a difference! how FUCKING DIFFICULT IS THAT?

simply read the timer at the start, the timer at the end, and take the difference. why the fuck do you need to hijack the system information just to avoid trivial arithmetic?
Post 22 Feb 2014, 03:56
View user's profile Send private message Visit poster's website Reply with quote
Display posts from previous:
Post new topic Reply to topic

Jump to:  
Goto page 1, 2  Next

< Last Thread | Next Thread >
Forum Rules:
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


Copyright © 1999-2024, Tomasz Grysztar. Also on GitHub, YouTube.

Website powered by rwasa.