View of xos/drivers/rtc.c


XOS | Parent Directory | View | Download

/* Routines d'acces a l'horloge temps reel (Real-time clock) */
/* Copyright (C) 2008  Emmanuel Varoquaux
 
   This file is part of XOS.
 
   This program is free software: you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.
 
   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.
 
   You should have received a copy of the GNU General Public License
   along with this program.  If not, see <http://www.gnu.org/licenses/>. */
 
#include <rtc_structs.h>
#include <asm.h>
 
#define rtc_read(addr) ({ \
  outbp(0x80 | addr, 0x70); \
  inbp(0x71); \
})
 
#define BCD_to_bin(var) ((var) = ((var) & 15) + ((var) >> 4) * 10)
 
/* Clock/calendar */
void rtc_get_clock(struct rtc_clock_struct *clock)
{
  int intr;
  unsigned char sec, min, hour, wday, mday, mon, year, century;
  int k;
 
  disable_intr(intr);
  k = 0;
  do {
    sec = rtc_read(0);
    min = rtc_read(0x2);
    hour = rtc_read(0x4);
    wday = rtc_read(0x6);
    mday = rtc_read(0x7);
    mon = rtc_read(0x8);
    year = rtc_read(0x9);
  } while (sec != rtc_read(0) && ++k < 1000000);
  century = rtc_read(0x32);
  BCD_to_bin(sec);
  BCD_to_bin(min);
  BCD_to_bin(hour);
  BCD_to_bin(wday);
  BCD_to_bin(mday);
  BCD_to_bin(mon);
  BCD_to_bin(year);
  BCD_to_bin(century);
  restore_intr(intr);
 
  clock->sec = sec;
  clock->min = min;
  clock->hour = hour;
  clock->wday = wday - 1;
  clock->mday = mday;
  clock->mon = mon;
  clock->year = 100 * century + year;
}
 
/* CMOS configuration data */
void rtc_get_configuration(struct rtc_configuration_struct *configuration)
{
  int intr;
  unsigned char diskette, hard_disk, equipment, base_mem_low, base_mem_high, extended_mem_low, extended_mem_high, disk_0, disk_1;
 
  disable_intr(intr);
  diskette = rtc_read(0x10);
  hard_disk = rtc_read(0x12);
  equipment = rtc_read(0x14);
  base_mem_low = rtc_read(0x15);
  base_mem_high = rtc_read(0x16);
  extended_mem_low = rtc_read(0x17);
  extended_mem_high = rtc_read(0x18);
  disk_1 = disk_0 = 0;
  if (((hard_disk & 0xf0) >> 4) == 0xf)
    disk_0 = rtc_read(0x19);
  if ((hard_disk & 0x0f) == 0xf)
    disk_1 = rtc_read(0x1a);
  restore_intr(intr);
 
  configuration->floppy_drive_nr = equipment & 0x01 ? ((equipment & 0xc0) >> 6) + 1 : 0;
  configuration->diskette_drive_0_type = (diskette & 0xf0) >> 4;
  configuration->diskette_drive_1_type = diskette & 0x0f;
  configuration->hard_disk_drive_0_type = ((hard_disk & 0xf0) >> 4) != 0xf ? (hard_disk & 0xf0) >> 4 : disk_0;
  configuration->hard_disk_drive_1_type = (hard_disk & 0x0f) != 0xf ? hard_disk & 0x0f : disk_1;
  configuration->primary_display = equipment & 0x30 >> 4;
  configuration->math_coprocessor = (equipment & 0x02) >> 1;
  configuration->base_memory = (base_mem_high << 8) + base_mem_low;
  configuration->extended_memory = (extended_mem_high << 8) + extended_mem_low;
}