FOOLING AROUND WITH THE DATE AND THE TIME
- OR -
SHUFFLING BITS WITH GfA 2.0
by Stefan Posthuma
Each time my hard disk booted, a little program was executed from
the auto folder that enabled me to set the date and the time. But
this program had some misfits that aroused my anger sometimes. It
mysteriously bombed out on me or it just halted and refused to do
anything. Or sometimes it caused the computer to re-boot after
being run. Terrible things for somebody who resets his computer
quite a lot, assorted programming is likely to create hangups!
One day, while suffering yet another crash from this annoying
little program, I decided to write my own date and time setter,
this time without those stupid bugs.
Of course, writing a program like this can be ultra-simple. Enter
two values, convert them to the necessary format and slam them
into your ST using an Xbios call. But being the perfectionist I
am, I built in things like validity checks and nice layouts. I
put the Digital Insanity touch to it so to speak.
For those interested in fooling around with the date and time
kept by your computer, or those interested in playing with bits
without using GfA 3.0, this might be interesting.
Little note:
After the enormously insane issue 3.6, we decided to make this
issue a little more serious. So I am really trying my best here
not to lose control. This results in sudden outbursts of insane
laughter, consuming large amount of junk-food and drink and
blood-shot eyes. But I am going to make it.
The first thing I had to do is to get the current date and time
stored somewhere in the ST. Now the ST has two independent
clocks, the GEMDOS clock and the Xbios clock. The nice thing
about the Xbios clock is that it is reset-resistant, so we are
going to use that one of course.
Obtain the date and time by using the following Xbios call:
T%=Xbios(22)
After this call, T% contains a 32-bit integer value containing
the date and time in a special format. Bit fields within T%
represent the various values like day, hour and year. It is up to
the programmer to do the unravelling. The format is this:
seconds bits 0-4
minutes bits 5-10
hours bits 11-15
day bits 16-20
month bits 21-24
year bits 25-31
Getting the seconds is easy. Just perform a logical AND on T%
with a certain value and we have them.
Maybe you don't know that ANDing is all about. Well, let me tell
you about it.
The logical AND operator is an operator that can change certain
bits within a binary value. You AND two values and get a third
one, consisting of the two ANDed values, with their bits combined
in some way or the other. ANDing the following bits will have the
following results:
0 AND 0 = 0
1 AND 0 = 0
0 AND 1 = 0
1 AND 1 = 1
So let's return to our date and time. T% contains a value from
which the last (or rightmost) 5 bits contain the seconds. The
rest of the bits are of no importance to those who want to know
the seconds. Let's say T% contains the following value:
0010010010101101010111011100011
If we look at the lower 5 bits, we will see the value:
00011
which is in fact 3, and this is the value for the seconds!
Using AND, we can get these 5 bits, consider this:
0010010010101101010100011100011 (decimal whocares)
0000000000000000000000000011111 (decimal 31)
------------------------------- AND
0000000000000000000000000000011 (decimal 3)
Just perform the AND rules on every single bit and you will get
the desired result!
A specialty of this is that the seconds have to be multiplied by
2 to get the real value of the seconds. This only applies to the
seconds though.
Now we want the minutes. Just use another AND operation:
0010010010101101010100011100011 (decimal whatever)
0000000000000000000011111100000 (decimal 2016)
------------------------------- AND
0000000000000000000000011100000 (decimal 448)
This means that the minutes will get the value 15, but we have
a little problem. The value of the result after the and operation
is 448 and not 15!
The problem lies in the fact that the bits are allright, but they
are too far to the left. In fact, they have to shift 5 places to
the right in order to make them correct. In Assembler, C or GfA
3.0, this would not have been any problem, but since we want to
compile our little program and we want to use GfA, we have to use
GfA 2.0 which has no easy way to shift bits.
The nice thing about numbers is, that if you divide a number by
its radix, the entire number will shift one place to the right
and the rightmost digit will disappear. This sounds complex, but
consider this: (we work with integers only)
1024 / 10 = 102
456 / 10 = 45
23 / 10 = 2
As you can see, the numbers just shift one place to the right if
you divide them by 10. Since we are working with binary numbers
here and the radix of the binary system is two, we have to divide
the numbers by two in order to make them shift one place to the
right!
So we have to divide our number by 2 five times (which is equal
to dividing by 2^5) and we have our minutes!
To compile the above mass of words into simple GfA code:
T%=Xbios(22)
Seconds%=(T% And 31)*2
Minutes%=(T% And 2016)/32
Hours%=(T% And 63488)/2048
After getting the time, the retrieval of the date would require
very large numbers, so we first put the high word in the low word
by shifting it to the right 16 places, which means dividing it by
2^16 = 65536
Div T%,65536
Day%=(T% And 31)
Month%=(T% And 480)/32
Year%=(T% And 65024)/512
In order to get the correct year, we have to add 1980:
Add Year%,1980
After this, the rest of the program is entirely up to the
programmer. A nice screen might appear, prompting the user to
input the date and the time. My program first checks to see if
there is a valid date. If there isn't, both date and time are
cleared and the user has to enter them correctly. If there is
already a valid date, the date and time are displayed and the
user can update them or just leave them be. I also included some
checking of valid dates and times, and allowed various input
options like 01.12.88, 1/12/88, 011288, 1 12/88 etc. etc. So
everybody can enter the date and time just like they used to.
Today I checked out my dad's record collection and found some
interesting records:
- Imaginations 'Body Talk', a maxi single. Great for when you
have an interesting person of the opposite sex with you and
nobody else is home, the fire is burning and the champaign is
chilled...
- 'Do they know it's Christmas', everybody should have that one.
- 'Wham rap' from Wham!, another maxi-single, from my mid-puberty
'just found out what girls are all about' period.
- 'Level 42' by Level 42. Early stuff from Level 42, very
cheerful and nice music.
- 'Faith' from The Cure. One of their first albums, when they
were still good. Very dark 'doom' music. With titles like 'the
funeral party' and 'the drowning man'. Great stuff to cheer you
up when the world seems a hostile and terrible place to be
in....
Ok, so much for the human interest. Kept it nice and clean this
time didn't I?
After the correct date and time have been input, they have to be
passed to TOS so the ST knows what all the fuzz is about. This is
a matter of applying another logical operator, this time called
OR. Oring bits will have the following effect:
0 OR 0 = 0
1 OR 0 = 1
0 OR 1 = 1
1 OR 1 = 1
As you can see, it is the opposite of AND and is used to combine
bit patterns to form one big value, and that is what we want
here.
Of course, some values have to be shifted to the left this time
to get the bits in the right position. If the minutes are 5, the
bit pattern will look something like this:
000101
But the minutes are bits 5-10 so we have to shift the minutes 5
places to the left in order to get the right positions. Now
dividing by two shifts one place to the right, but multiplying by
two shifts one place to the left! So if we multiply our minutes
by 2^5 (32) we get the desired result.
Assuming the seconds are 15, we get the following OR operation:
00000000111 seconds
00010100000 minutes
----------- OR
00010100111
After ORing all other values, we have the desired result,
suitable for passing to TOS!
There is one problem though. The multiplication factor increases
rapidly, and in order to get the year bits in the right position,
we have to multiply by 2^32 which will result in a runtime error,
GfA complaints that the number is too large. This is because GfA
uses the rightmost bit as a sign-indicator and we don't want
that. In order to avoid things like 1-bit complementing, I have
chosen a more radical approach, just POKE the values into the
memory locations used by the variable.
Every integer (with a % postfix) variable occupies 4 consecutive
bytes of memory, capable of holding 4*8 = 32 bits. The address of
the first byte can be retrieved using the Varptr command of GfA.
Now the first two bytes of the variable hold the date and the
last two hold the time, so two Dpokes (a 16-bit Poke) will do the
job:
Date%=((Year%-1980)*512) Or (Month%*32) Or Day%
Time%=(Hour%*2048) Or (Minute%*32) Or (Seconds%/2)
The Seconds%/2 was neccesary because TOS counts seconds in steps
of two.
Now create a variable in which we can Poke the values of Date%
and Time% and Dpoke the values into their positions!
T%=1
Dpoke Varptr(T%),Date%
Dpoke Varptr(T%)+2,Time%
Now pass T% to Xbios:
Void Xbios(22,L:T%)
A lot of programs (including Tempus and GfA 3.0) use the Gemdos
clock, better set that one too:
Void Gemdos(&H2D,Time%)
Allright, that's it for the programming! The source of Datetime
can be found in the PROGRAMS folder of this ST NEWS disk!
Now let me say it's not a question of getting down,
but actually how low you can go....
- Hamilton Bohannon
�
Disclaimer
The text of the articles is identical to the originals like they appeared
in old ST NEWS issues. Please take into consideration that the author(s)
was (were) a lot younger and less responsible back then. So bad jokes,
bad English, youthful arrogance, insults, bravura, over-crediting and
tastelessness should be taken with at least a grain of salt. Any contact
and/or payment information, as well as deadlines/release dates of any
kind should be regarded as outdated. Due to the fact that these pages are
not actually contained in an Atari executable here, references to scroll
texts, featured demo screens and hidden articles may also be irrelevant.