Jump to content
IGNORED

Bios <-> keyboard date issue


Recommended Posts

The GEMDOS interface for date and time uses bits 15-9 (7 bits) for year (current year - 1980), bits 8-5 (4 bits) for month, bits 4-0 (5 bits) for day of month. Trap 1 $2A => get date, trap 1 $2B set date, trap 1 $2C get time, trap 1 $2D set time. The BIOS calls for the keyboard clodk are trap 14, $16 to get date|time, trap 14, $17 to set date|time. The book I have states the actual keyboard interface uses a 6 byte message, 2 BCD digits per byte (year, month, day, hour, minute, second) (no bias for the year, 1980 would be transferred as $80 (BCD)).

 

There is an issue on my old 520 ST with the BIOS <-> keyboard clock interface. A variation of the Y2K problem. If using trap 14 to set and get the date|time, year values 0 to 19 (representing 1980 to 1999) work. Trying to set year values 20 to 79 (2000 to 2059) will be ignored, although month and day will be updated. Year values 80 to 127 can be set, but the values returned by get will be 32 less, 48 to 95. So my workaround in my date and time program is to use year values 80 to 127 for the years 2000 to 2047 when setting keyboard date|time via trap 14, and to use values 48 to 95 for the years 2000 to 2047 when getting date|time. via trap 14.

 

I'm wondering if this is an issue specific to my old 520 ST, or if later versions of the ST have the same issue.

 

Edited by rcgldr
Link to comment
Share on other sites

9 hours ago, ParanoidLittleMan said:

That's just stupid code in TOS. Present in 1.04, 1.62 too.  They add 80 BCD to year before write it to IKBD chip - why ? To lower span to 1980-1999.

 

The keyboard controller / clock is a 6301. When sending a set date|time message, the date|time is sent as 6 bytes of BCD data, each byte containing 2 BCD digits. The 6301 will ignore any byte with an invalid BCD digit {$A ... $F}, but will update the remaining bytes if valid. When getting a date|time message, the date|time is received as 6 bytes of BCD data.

 

Both GEMDOS and BIOS set and get date|time using binary fields:   date: bits 15->8 (7 bits) year-80, bits 8->5 (4 bits) month, bits 4->0 (5 bits) day of month, time: bits 15->11 (5 bits) hour, bits 10-5 (6 bits) minute, bits 4-0 (5 bits) second/2. 

 

For BIOS set keyboard date|time, it gets year field, adds 80, converts to BCD. Year values {00 ... 19} are mapped to {$80 ... $99}. Year values 20 ... 79} are mapped to {$A0 ... $F9}, which the 6301 will ignore. Year values {80 ... 127} are mapped to byte values {$00 ... $47} (bit 8 is dropped since it ends up in a byte), which the 6301 will accept.

 

For BIOS get keyboard date|time, it maps BCD year to binary, subtracts 80, and puts the result into a 7 bit field. {$80 ... $99} get mapped to {00 ... 19}, values {$00 ... $47} get mapped to {48 ... 95}. 

 

I created a work around with my get|set date|time utility, which will work for years 1980 -> 2047. Example code:

 

;       adjust before setting date|time, d4 = date
;       year field = year - 80

        cmp     #$2800,d4               ;br if year field lt 20
        bcs.s   set0
        add     #$7800,d4               ;add 60 to year field
set0:   ...

;       adjust after getting date|time, d4 = date

        cmpi.w  #$6000,d4               ;br if year field lt 48
        bcs.s   get0
        subi.w  #$3800,d4               ;subtract 28 from year field
get0:   ...

 

Edited by rcgldr
clean up
Link to comment
Share on other sites

Sorry, but that's irrelevant. Actually 6301 stores not year, since it can store 0-99 . So, it stores only part of year.

And in any case year data from IKBD (6301) chip goes not directly to output (like file stamp), but after processing by TOS.

There are diverse programs to make it working in years 2K. All based on same principle - changing that bad/low year span.

Link to comment
Share on other sites

53 minutes ago, ParanoidLittleMan said:

Sorry, but that's irrelevant. Actually 6301 stores not year, since it can store 0-99 . So, it stores only part of year.

And in any case year data from IKBD (6301) chip goes not directly to output (like file stamp), but after processing by TOS.

I already posted that the 6301 stores the year as 2 BCD digits in a byte, so $00 to $99. Year values that are a multiple of 4, including $00, are properly handled as leap years. 

 

Side note - If I boot my 520 ST, and then save desktop, the desktop.inf file ends up with date|time 11/20/1985 12:00:xx am (which was a Wednesday), apparently a default date|time chosen by the TOS on my 520 ST. That may be a way to determine the TOS version? The TOS on my 520ST is not pulling the date|time info from the keyboard clock. I need to use a date|time utility to get date|time from the keyboard (trap 14) and set GEMDOS date|time (trap 1).

 

Edited by rcgldr
Link to comment
Share on other sites

TOS creation date is in TOS header (first 48 bytes) - in ACSI and in 'packed' TOS format. Later is 2 bytes - 5 bits for date, 4 for month and 7 for year. You can read about such things on sites about TOS. And DL diverse TOS versions to see diff. in headers, where version code is too, of course.

Normally, after reset TOS checks date and time in IKBD chip and if it seems valid will copy it in GEMDOS time. Not sure that it is case with TOS 1.00 too, which is what you have. 1.02 will have year 1987, 1.04 and 1.06 1989.

 

And to add answer on questions in first post here:  low year span issue is present in TOS versions 1.00-1.62 for sure. Likely in later ones too, but I did not test on TT, Falcon.  Unfortunately Atari/DRI made some really poor decisions in TOS. I have some WEB pages about it, and even threads here in programming section about it.

Funny thing is that they even experienced with extra board for using IKBD chip as RTC when no power. But that was abandoned idea, and it is good, because in 1987, in Mega ST Atari added Ricoh RTC chip, with low power consumption and small battery pack. And support in TOS 1.02 for. But it was present only in Mega ST and little later in Mega STE and likely TT .

Link to comment
Share on other sites

Looking at old code (from Jan 01, 1986), there is a workaround for the low year gap, at least for older models like the 520 ST (I don't know about later models). There is a BIOS call (trap #14) to send a message to the keyboard / clock / 6301 chip. To set the date|time, the message is 7 bytes long, $1B, followed by 6 BCD encoded bytes for year, month, day, hour, minute, second. This workaround allows all 100 years to be set: 00 to 99, representing 1980 -> 2079 by GemDos. Since 2000 was a leap year, the 6301 didn't need any special handling for 02/29/2000. The 6301 wraps around from 99|12|31 23:59:59 to 00|01|01 00:00:00. 

 

The BIOS call takes an address, and count-1, in this case 7-1 = 6. Trap #1 is still used to get the keyboard time, and needs the same workaround as posted above. There's no BIOS 6301 input call, since TOS defaults to ignoring 6301 responses, but code can hook into the interrupt vector and manually receive data from the 6301. However, the Gemdos call (trap 1) with the workaround posted earlier can be used to get the data|time from the keyboard for all 100 years. 

 

*
*       kbd (6301) output message
*       a0 = adr message
*       d0 = # bytes
*
kbdot:  subq.l  #1,d0           trap count is -1
        move.l  a0,-(a7)        output kbd msg
        move.w  d0,-(a7)
        move.w  #25,-(a7)
        trap    #14
        addq.l  #8,a7
        rts

*       set date|time message
*       $1b, followed by 6 bcd bytes: 
*                    yy  mm  dd  hh  mm  ss
kbdmsg: db      $1b,$20,$03,$10,$12,$34,$56

 

Link to comment
Share on other sites

Yeah, you describing now here (should go rather in programming section) some well known and basic things about Atari ST TOS and IKBD programming. Really not best idea to start like this.

& there is XBIOS call GETTIME, GEDDATE. And TOS has his way for getting input from 6301 chip - much better one than via some Trap call - it's called interrupt ?

 

Link to comment
Share on other sites

When did the usage of the term IKBD for the 6301 begin? I don't recall this, and it's not in the old books, like Atari ST internals.

 

interrupt

The Atari ST Internals book has example code for receiving data from the 6301 by hooking into the interrupt, but it uses the BIOS call to send data. I may have code for this archived somewhere.

 

Turns out I probably got my 520 ST in 1985 (not 1986). So I started this thread because I didn't know if this date | year issue was specific to my old 520 ST or was also an issue for later systems (which apparently it is).

 

 

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...