flat assembler
Message board for the users of flat assembler.
Index
> OS Construction > Elapsed time calculator Goto page 1, 2 Next |
Author |
|
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. |
|||
21 Feb 2014, 04:34 |
|
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 revolution wrote: And always use UTC times and only convert to local time for display purposes. _________________ FAMOS - the first memory operating system |
|||
21 Feb 2014, 05:32 |
|
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.
|
|||
21 Feb 2014, 05:50 |
|
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. 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... _________________ FAMOS - the first memory operating system |
|||
21 Feb 2014, 06:48 |
|
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. |
|||
21 Feb 2014, 07:01 |
|
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 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 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. _________________ FAMOS - the first memory operating system |
|||
21 Feb 2014, 08:05 |
|
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 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. |
|||
21 Feb 2014, 08:31 |
|
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. |
|||
21 Feb 2014, 08:58 |
|
revolution 21 Feb 2014, 09:04
baldr wrote:
|
|||
21 Feb 2014, 09:04 |
|
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 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. Thanks again for your thoughts but we might just have to agree to disagree for now 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 |
|||
21 Feb 2014, 09:55 |
|
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. |
|||
21 Feb 2014, 10:28 |
|
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 , 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. |
|||
21 Feb 2014, 10:48 |
|
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 |
|||
21 Feb 2014, 10:58 |
|
neville 21 Feb 2014, 20:14
baldr wrote: neville, _________________ FAMOS - the first memory operating system |
|||
21 Feb 2014, 20:14 |
|
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 "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. (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 revolution wrote: And the Linux seconds counter is bad, I already mentioned that above. revolution wrote: I like the Windows 0.1µs resolution. _________________ FAMOS - the first memory operating system |
|||
21 Feb 2014, 20:25 |
|
neville 21 Feb 2014, 20:37
edfed wrote: maybe by just building a master timer in the os first 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 |
|||
21 Feb 2014, 20:37 |
|
neville 21 Feb 2014, 20:44
sinsi wrote: INT 1A - TIME - READ SYSTEM-TIMER DAY COUNTER sinsi you are a genious! I think you have just given me an elegant solution to my problem. 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 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 |
|||
21 Feb 2014, 20:44 |
|
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 It returns no data, and sets the C flag. Further research suggests it may only be in PS/2 systems. What a pity
_________________ FAMOS - the first memory operating system |
|||
21 Feb 2014, 23:35 |
|
BAiC 22 Feb 2014, 03:56
Quote:
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? |
|||
22 Feb 2014, 03:56 |
|
Goto page 1, 2 Next < Last Thread | Next Thread > |
Forum Rules:
|
Copyright © 1999-2024, Tomasz Grysztar. Also on GitHub, YouTube.
Website powered by rwasa.