88 lines
2.3 KiB
C
88 lines
2.3 KiB
C
#include <stdio.h> /* fprintf, stderr */
|
|
#include <stdbool.h> /* bool, true, false */
|
|
#include <stdint.h> /* uint8_t */
|
|
#include <time.h> /* struct tm */
|
|
|
|
#include "noslotclock.h"
|
|
#include "prodos.h"
|
|
#include "trace.h"
|
|
|
|
#define NSC_STRING_RESULT_ADDR 0x0280 /* String result, Ends at 0x0291 */
|
|
#define NSC_STRING_RESULT_LEN 12 /* The length of the above result */
|
|
#define NSC_UPDATE_SUB_ADDR 0x030B /* Start address of update subroutine */
|
|
|
|
typedef struct {
|
|
uint8_t year; /* 0..99 */
|
|
uint8_t month; /* 1..12 */
|
|
uint8_t day_of_month; /* 1..31 */
|
|
uint8_t day_of_week; /* 1..7 */
|
|
uint8_t hour; /* 0..23 */
|
|
uint8_t min; /* 0..59 */
|
|
uint8_t sec; /* 0..59 */
|
|
uint8_t hundredths_of_sec; /* 0..99 */
|
|
} no_slot_clock_time_t;
|
|
|
|
static const no_slot_clock_time_t *nsc = (no_slot_clock_time_t *) 0x0303;
|
|
static const char *nsc_absent_addr = (char *) 0x0304;
|
|
|
|
static bool is_nsc_absent(void);
|
|
static void read_time_from_nsc(void);
|
|
|
|
static void read_time_from_nsc()
|
|
{
|
|
TRACE_ENTER("read_time_from_nsc");
|
|
asm("jsr %w", NSC_UPDATE_SUB_ADDR);
|
|
TRACE_EXIT("read_time_from_nsc");
|
|
}
|
|
|
|
/**
|
|
* load_driver must be called first.
|
|
*/
|
|
static bool is_nsc_absent()
|
|
{
|
|
TRACE_ENTER("is_nsc_absent");
|
|
read_time_from_nsc();
|
|
TRACE_EXIT("is_nsc_absent");
|
|
return nsc_absent_addr[0] == NULL;
|
|
}
|
|
|
|
bool load_driver()
|
|
{
|
|
bool status = false;
|
|
|
|
TRACE_ENTER("load_driver");
|
|
if (run_basic_system_command("BLOAD READ.TIME")) {
|
|
|
|
/* Check for a missing NSC. */
|
|
if (! is_nsc_absent()) {
|
|
fprintf(stderr, "The No-Slot Clock hardware is missing");
|
|
status = true;
|
|
}
|
|
}
|
|
TRACE_RET_BOOL("load_driver", status);
|
|
return status;
|
|
}
|
|
|
|
/**
|
|
* The setup function must be called first.
|
|
*/
|
|
struct tm *read_time(struct tm *t)
|
|
{
|
|
/* Reload the current time from the No-Slot Clock into memory. */
|
|
read_time_from_nsc();
|
|
|
|
/* Transfer loaded values into a standard C struct tm. */
|
|
t->tm_sec = nsc->sec;
|
|
t->tm_min = nsc->min;
|
|
t->tm_hour = nsc->hour;
|
|
t->tm_mday = nsc->day_of_month;
|
|
t->tm_mon = nsc->month - 1;
|
|
t->tm_year = nsc->year + 100;
|
|
t->tm_wday = nsc->day_of_week == 7 ? 0 : nsc->day_of_week;
|
|
t->tm_yday = 0;
|
|
t->tm_isdst = 0;
|
|
return t;
|
|
}
|
|
|
|
|