Jump to content
IGNORED

SpartaDOS X date & time


sanny

Recommended Posts

  • 2 weeks later...

Look at SDX User Guide:

- 6.4. SpartaDOS User Accessible Data Table (DATER, TIMER, ODATER, OTIMER, TDOVER)

- 6.7. Vectors under the OS ROM (VGETTD, VSETTD, VTDON, VFMTTD)

- 6.8. Page seven kernel values

- 8.6.3.6. Z.SYS

I suspect all datetime device drivers like JIFFY.SYS, APETIME.SYS etc. have common interface, but it's better to ask Draco about it.

Link to comment
Share on other sites

  • 2 weeks later...

Look at SDX User Guide:

- 6.7. Vectors under the OS ROM (VGETTD, VSETTD, VTDON, VFMTTD)

I suspect all datetime device drivers like JIFFY.SYS, APETIME.SYS etc. have common interface, but it's better to ask Draco about it.

 

I had sent @drac030 a PM on Sep-6, but didn't get an answer. But, according to AtariAge, he hasn't read it yet.

 

Following up on this, I want to try the I_GETTD and I_SETTD SDX functions (not by using the vectors under the ROM, but by more future-proof means). I haven't found documentation about these functions in neither the SDX user manual nor the SDX programming manual.

Is there documentation available for these functions? Input/Output parameters, etc.

 

Any hint is appreciated.

 

regards,

chris

Link to comment
Share on other sites

no, If you are going to use the symbols like that, look at section 16.1 in the programming guide

you are going to have to get a feel for this using S_LOOKUP. you will have to look through this section it's helpful and should contain an example pertaining to time clock as well.

 

You will have to go to Drac's site and contact him through his posted contact there. see also TRUB ! for great help

Edited by _The Doctor__
Link to comment
Share on other sites

10 c=peek(10)+256*peek(11)

20 day=peek(c+13):month=peek(c+14):year=peek(c+15)

30 hour=peek(c+16):min=peek(c+17):sec=peek(c+18)

 

What about this don't you understand? This is simple BASIC.

 

RTFM!

 

Edit: You guys DO know, I hope that I was only using BASIC to show you a simple way of doing this. It can be accomplished using Assembly more easily. Any language, actually. I was only providing a template.to help new users who haven't read the manual, available here: http://sdx.atari8.info/sdx_files/4.48/SDX448_User_Guide.pdf

 

(Banging my head off the wall now, if you guys can't figure it out yet.)...... :)

Edited by Kyle22
Link to comment
Share on other sites

no, If you are going to use the symbols like that, look at section 16.1 in the programming guide

you are going to have to get a feel for this using S_LOOKUP. you will have to look through this section it's helpful and should contain an example pertaining to time clock as well.

 

I looked at sc 16.1. This is very helpful, thanks.

 

Still, now I should be able to get the addresses of I_SETTD and I_GETTD, but don't know their parameters (new time in case of I_SETTD) and results (current time with I_GETTD).

 

 

You will have to go to Drac's site and contact him through his posted contact there. see also TRUB ! for great help

 

Thanks for the hint. I'll send him an email directly.

 

regards,

chris

Link to comment
Share on other sites

I was able to do this in CC65 by doing:

void timedate(TimeDate* td)
{
  struct regs r;
  assert(td!=NULL);
  r.pc = 0x703; // KERNEL
  r.y = 100;    // GETTD

  *(byte*) 0x0761 = 0x10; // DEVICE

  _sys(&r);     // Do Kernel Call.

  td->day     = *(byte*) 0x77B;
  td->month   = *(byte*) 0x77C;
  td->year    = *(byte*) 0x77D;
  td->hours   = *(byte*) 0x77E;
  td->minutes = *(byte*) 0x77F;
  td->seconds = *(byte*) 0x780;

  return;
}
Link to comment
Share on other sites

What about this don't you understand? This is simple BASIC.

 

I did understand it. I guess it can be used to get the current time.

 

But how to _set_ time? And update the RTC if present. For a simple version of "setting" I could try to overwrite these variables with a new time, but don't know whether it will persist (maybe a RTC driver sporadically updates those fields from the RTC).

 

regards,

chris

  • Like 2
Link to comment
Share on other sites

What you need is described in section 6.8 of the current SDX User Manual (Page Seven "Kernel" Values).

 

date $77B see below (3 bytes)

time $77E see below (3 bytes)

 

The 'kernel' routine is called by doing a jump subroutine (JSR) to address $703 with the

desired command in the 6502 Y register and the desired device number previously

stored in the memory location 'device'. For example, with a $10 in device, a value of 100

in the Y-register will cause the current time and date to be placed in the variables 'time'

and 'date'. A 101 will cause the current time to be set to the values contained in the

variables 'time' and 'date'.

 

kd_gettd 100 get current time and date

kd_settd 101 set time and date

  • Like 1
Link to comment
Share on other sites

Yep, this seems to work. Tested on SDX with an RTC and without an RTC (JIFFY.SYS).

 

Thanks @flashjazzcat and @tschak909!

/* $Id: sdxtime.c,v 1.1 2018/09/19 20:25:03 chris Exp $
 *
 * SpartaDOS-X time/date test
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <conio.h>
#include <time.h>
#include <assert.h>
#include <atari.h>
#include <cc65.h>
#include <6502.h>

static void exitfn(void)
{
    if (doesclrscrafterexit()) cgetc();
}

/* from Thom Cherryhomes: */
static void timedate(struct tm *td)
{
    struct regs r;
    assert(td != NULL);
    r.pc = 0x703; /* KERNEL entry */
    r.y = 100;    /* GETTD function */

    *(unsigned char *)0x0761 = 0x10; /* DEVICE */

    _sys(&r);     /* do the kernel call */

    td->tm_mday = (int)*(unsigned char *)0x77B;
    td->tm_mon  = (int)*(unsigned char *)0x77C - 1;
    td->tm_year = (int)*(unsigned char *)0x77D;
    td->tm_hour = (int)*(unsigned char *)0x77E;
    td->tm_min  = (int)*(unsigned char *)0x77F;
    td->tm_sec  = (int)*(unsigned char *)0x780;

    /* fix century */
    if (td->tm_year < 79)
        td->tm_year += 100;
}

static void timedate_set(struct tm *td)
{
    struct regs r;
    assert(td != NULL);

    *(unsigned char *)0x77B = (unsigned char)td->tm_mday;
    *(unsigned char *)0x77C = (unsigned char)td->tm_mon + 1;
    *(unsigned char *)0x77D = (unsigned char)td->tm_year % 100;
    *(unsigned char *)0x77E = (unsigned char)td->tm_hour;
    *(unsigned char *)0x77F = (unsigned char)td->tm_min;
    *(unsigned char *)0x780 = (unsigned char)td->tm_sec;

    r.pc = 0x703; /* KERNEL entry */
    r.y = 101;    /* SETTD function */

    *(unsigned char *)0x0761 = 0x10; /* DEVICE */

    _sys(&r);     /* do the kernel call */
}

static void print_time(struct tm *time_to_print)
{
    timedate(time_to_print);

    printf("time: %s\n", asctime(time_to_print));
    // DEBUG:
    printf("mday=%d mon=%d year=%d\nhour=%d min=%d sec=%d\n", time_to_print->tm_mday, time_to_print->tm_mon, time_to_print->tm_year, time_to_print->tm_hour, time_to_print->tm_min, time_to_print->tm_sec);
}

int main(int argc, char **argv)
{
    static char c;
    static int s;
    static struct tm cur_time;

    atexit(exitfn);

    if (_dos_type != SPARTADOS) {
        /* check version? */
        printf("not on SpartaDOS, exiting...\n");
        return 1;
    }

    if (argc <= 1) {
        print_time(&cur_time);
        return 0;
    }

    if (argc != 3 || strcasecmp(*(argv + 1), "set")) {
        printf("usage: SDXTIME [set DD-MM-YY-HH-MM-SS]\n");
        return 1;
    }

    s = sscanf(*(argv + 2), "%d-%d-%d-%d-%d-%d", &cur_time.tm_mday, &cur_time.tm_mon, &cur_time.tm_year, &cur_time.tm_hour, &cur_time.tm_min, &cur_time.tm_sec);
    if (s != 6 || cur_time.tm_year > 99 /* other input values aren't being verified... */) {
        printf("invalid time/date format\n");
        return 1;
    }
    --cur_time.tm_mon;
    if (cur_time.tm_year < 79)
        cur_time.tm_year += 100;  /* adjust century */

    printf("\nyou are about to set the time to\n-->  %s\n\nContinue (y/n)?", asctime(&cur_time));

    while (c != 'y' && c != 'Y' && c != 'n' && c != 'N')
        c = cgetc();
    printf("%c\n", c);

    if (c == 'n' || c == 'N') {
        printf("user abort\n");
        return 0;
    }

    timedate_set(&cur_time);
    printf("time set!\n");
    //DEBUG test begin
    memset(&cur_time, 0, sizeof(cur_time));
    print_time(&cur_time);
    //DEBUG test end
    return 0;
}
/* Local Variables: */
/* c-file-style: "cpg" */
/* c-basic-offset: 4 */
/* End: */

  • Like 1
Link to comment
Share on other sites

 

I did understand it. I guess it can be used to get the current time.

 

But how to _set_ time? And update the RTC if present. For a simple version of "setting" I could try to overwrite these variables with a new time, but don't know whether it will persist (maybe a RTC driver sporadically updates those fields from the RTC).

 

regards,

chris

Ok, I thought you only wanted to read the time.

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...