/*
 * timer.c
 *
 * This version, for the Amiga, was written by Nick Waterman.
 *
 * THIS SOFTWARE IS PROVIDED AS IS AND WITHOUT WARRANTY OF ANY KIND,
 * EITHER EXPRESSED OR IMPLIED.
 *
 */

#include "timer.h"
#include "pphw.h"
#include <stdio.h>
#include <stdlib.h>

#include <clib/exec_protos.h>
#include <clib/misc_protos.h>
#include <clib/dos_protos.h>
#include <clib/alib_protos.h>

#include <resources/misc.h>

/* #include <pragmas/exec_pragmas.h> */
/* #include <pragmas/misc_pragmas.h> */
/* #include <pragmas/dos_pragmas.h> */

static char *version = "timer.c V-0.1  Copyright (C) 1998 Nick Waterman";    
extern char *does;
APTR MiscBase;
struct timerequest *tr = NULL;
struct MsgPort *tp = NULL;
int byeflags = 0;   /* other things that should be freed on exit... */

#define FREEPARPORT 1
#define FREEPARBITS 2
#define DONTDOTWICE 4

    /* ms_delay(ticks)
     * Amiga version
     * Returns after ticks microseconds
     */

void ms_delay(int ticks)
{
    us_delay(ticks);
}

    /* us_delay(ticks)
     * Amiga version
     * Returns after ticks microseconds
     */

void us_delay(int ticks)
{
    if (ticks < 1) return;   /* it's apparently fantastically stupid to
            wait 0 microseconds. */
    if (ticks > 1000000) {
        printf("HEY! us_delay can only wait MICROseconds, not whole\n");
   printf("SECONDS, dammit!\n");
   exit(99);
    }

    /* add a new timer request */
    tr->tr_time.tv_micro = ticks;
    DoIO((struct IORequest *) tr );
}

    /* reset_timer()
     *
     * Attempts to restore timer 2 to default state.
     *
     */

void reset_timer(void)
{
    /* nothing to do here - everything is freed by __autoexit routine */
}

ami_setup() {
   char *owner;

   if (byeflags & DONTDOTWICE) return;
   byeflags |= DONTDOTWICE;

   MiscBase = OpenResource(MISCNAME);
   if (!MiscBase) {
      printf("Unable to open %s!\n", MISCNAME);
      exit (10);
   }

   owner = AllocMiscResource(MR_PARALLELPORT, does);
   if (owner) {
      printf("Parallel port is already grabbed by %s!\n", owner);
      exit(10);
   }
   byeflags |= FREEPARPORT;

   owner = AllocMiscResource(MR_PARALLELBITS, does);
   if (owner) {
      printf("Parallel control already grabbed by %s!\n", owner);
      exit(10);
   }
   byeflags |= FREEPARBITS;

   if (!(tp = CreatePort( 0, 0 ))) {
      printf("Can't create port for timer!\n");
      exit(10);
   }

   tr = (struct timerequest *)
      CreateExtIO( tp, sizeof( struct timerequest ) );
   if (!tr) {
      printf("Can't create ExtIO thingy!\n");
      exit(10);
   }
   
   if (OpenDevice(TIMERNAME, UNIT_MICROHZ, (struct IORequest *) tr, 0L)) {
      printf("Can't open timer.device unit_microhz!\n");
      exit(10);
   }

   tr->tr_node.io_Command = TR_ADDREQUEST;
   tr->tr_time.tv_secs = 0;
}

__autoexit ami_exit() {
   if (tp) DeletePort(tp);
   if (tr) {
      CloseDevice( (struct IORequest *) tr );
      DeleteExtIO( (struct IORequest *) tr );
   }
   if (byeflags & FREEPARPORT) FreeMiscResource(MR_PARALLELPORT);
   if (byeflags & FREEPARBITS) FreeMiscResource(MR_PARALLELBITS);
}

int getch() {
   return fgetc(stdin);
}

int inportb(PPREG_T addr) {
#ifdef DEBUG
   printf("+++ inportb (%p)=%d\n", addr, *addr);
#endif
   return *addr;
}

outportb(PPREG_T addr, int bits) {
#ifdef DEBUG
   printf("+++ outportb (%p, %d)\n", addr, bits);
#endif

   if ((addr == (PPREG_T) 0xBFE101) || (addr == (PPREG_T) 0xBFE301)) {
      *addr = bits;
   } else {
      printf("Tried to output to illegal addr %p!!\n", addr);
   }
}

