Skip to main content

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.