#ifndef HWAPI_H
#define HWAPI_H

/*
    HWAPI.H

    Interface to the hardware API


    $Log: 
     5    IPC@CHIP  1.4         02.08.01 20:13:00    Thomas Kinder 
          Added defines for most of the function parameters.
          Defined all missing functions for BIOS v1.0.
     4    IPC@CHIP  1.3         31.05.01 16:18:24    Christoph Stoidner 
     3    IPC@CHIP  1.2         23.02.01 11:59:14    Ernest Schlösser Added a few
          comments
     2    IPC@CHIP  1.1         15.02.01 15:16:52    Christoph Stoidner 
     1    IPC@CHIP  1.0         14.02.01 16:09:19    Christoph Stoidner 
    $


*/

/***************************************************************************/
// Typedefs
/***************************************************************************/
typedef void interrupt (*InterruptHandler)(void);

/***************************************************************************/
// Defines
/***************************************************************************/
#ifdef _MSC_VER /* If Microsoft C Compiler is used, define new FP_SEG and FP_OFF Macro */
	#ifdef FP_SEG
  		#undef FP_SEG
	#endif
	#define FP_SEG(ptr)    ((unsigned int)(((unsigned long)ptr)>>16))

	#ifdef FP_OFF
  		#undef FP_OFF
	#endif
	#define FP_OFF(ptr)    ((unsigned int)(((unsigned long)ptr)&0xFFFF))
#endif


#define HAL_INT       0xA1
#define PFE_INT       0xA2

// Enable Programmable I/O Pins
#define PIO_I            1
#define PIO_IPU          2
#define PIO_IPD          3
#define PIO_O1           4
#define PIO_O0           5

// Set Edge/Level Interrupt Mode
#define INT_EDGE         0
#define INT_LEVEL        1

// Initialize Timer Settings
#define TIMER_CONT       1
#define TIMER_INT        2
#define TIMER_EXT        4

// Set Timer Duty Cycle Waveform
#define TIMER_DUTY       1

// Enable External Timer Inputs/Outputs
#define TIMER_IN0        2
#define TIMER_OUT0       3
#define TIMER_IN1        8
#define TIMER_OUT1      12

// Install Interrupt Service Routine
#define ISR_INT0         0
#define ISR_ETH          1
#define ISR_INT2         2
#define ISR_INT3         3
#define ISR_INT4         4
#define ISR_INT5         5
#define ISR_INT6         6
#define ISR_TIMER0       8
#define ISR_TIMER1       9
#define ISR_TIMER1MS    10
#define ISR_SER0        11
#define ISR_SER1        12
#define ISR_DMA0        13
#define ISR_DMA1        14
#define ISR_NMI         15

// Get Frequencies
#define FREQ_CPU         0
#define FREQ_TIMER       1
#define FREQ_MAXBAUD     2
#define FREQ_PWD         3

// Get Reboot Reason
#define REBOOT_UNKNOWN   0
#define REBOOT_WATCHDOG  3
#define REBOOT_PFAIL     4

// Get/Set Watchdog Mode
#define WDOG_GETMODE     0
#define WDOG_USER        2
#define WDOG_BIOS        3

// Initialize/Restore Non-Volatile Data
#define REMA_FILENAME    "A:\\rema.bin"


#define DIRECT_IO


#ifdef DIRECT_IO
 #define hal_inportb(x)      inportb(x)
 #define hal_outportb(x,y)   outportb(x,y)
#else
 #define hal_inportb(x)      hal_read_bus(x,0xFFFF,0x0000)
 #define hal_outportb(x,y)   hal_write_bus(x,y,0xFFFF,0x0000)
#endif

#define hal_inportb_block    hal_readblock_bus
#define hal_outportb_block   hal_writeblock_bus


/***************************************************************************/
// Data types
/***************************************************************************/

// TODO: THIS IS ACTUALLY A WILD GUESS! I COULDN'T FIND THE
//       CORRECT VALUE IN THE BIOS DOCUMENTATION.
#define MAX_RETENTIVE_AREAS  16

typedef struct _REMOP
{
    unsigned entries; // number of entries in struct REMOP_ENTRY x[]
    unsigned segment; // common segment address

    struct REMOP_ENTRY
    {
        unsigned offs;      // offset address
        unsigned size;      // number of bytes (must be <= maxsize)
        unsigned maxsize;   // maximal number of bytes
        unsigned elemsize;  // number of bytes per data element
        unsigned distance;  // distance to next data element (must be >= elemsize)
    } x[MAX_RETENTIVE_AREAS];
} _REMOP; 


/***************************************************************************/
// Prototypes
/***************************************************************************/

// ********** PFE Functiuons **************************
void          pfe_enable_bus (unsigned mask, unsigned char ale);
void          pfe_enable_adr (unsigned char adr);
void          pfe_enable_pcs (unsigned char pcs);
void          pfe_enable_int (unsigned char irq);
void          pfe_enable_timer (unsigned mode);
void          pfe_enable_pio (unsigned pio, unsigned char mode);
void          pfe_get_pio_state (unsigned *wPio, unsigned *wInp, unsigned *wOut);
void          pfe_set_int_mode (unsigned intr, unsigned char mode);
void          pfe_enable_pwd();

// ************ HAL functions ************************

unsigned char hal_read_bus (unsigned adr, unsigned wAND, unsigned wXOR);
void          hal_write_bus (unsigned adr, unsigned char value, unsigned wAND, unsigned wXOR);
void          hal_readblock_bus (unsigned adr0, unsigned adr1, unsigned char *buf, unsigned cnt);
void          hal_writeblock_bus (unsigned adr0, unsigned adr1, unsigned char *buf, unsigned cnt);

void          hal_get_pio_output_state (unsigned *pins, unsigned wOut);
unsigned      hal_read_pios (unsigned wAND, unsigned wXOR);
void          hal_write_pios (unsigned value, unsigned wAND, unsigned wXOR);
unsigned char hal_read_pio (unsigned char pio);
void          hal_write_pio (unsigned char pio, unsigned value);

InterruptHandler  hal_install_isr (unsigned irq, unsigned count, InterruptHandler handler);

unsigned long hal_get_frequency(unsigned char which);
void          hal_init_timer (unsigned char timer, unsigned mode, unsigned divider);
void          hal_set_timer_duty(unsigned char timer, unsigned mode, unsigned divider);
void          hal_start_timer (unsigned char timer);
void          hal_stop_timer (unsigned char timer);
unsigned      hal_read_timer_count (unsigned char timer, unsigned far *maxcount);
void          hal_write_timer_count (unsigned char timer, unsigned counter);

unsigned char hal_set_watchdog_mode (unsigned char mode);
void          hal_refresh_watchdog (void);

unsigned      hal_init_nv_data(_REMOP remop);
void          hal_save_nv_data();
unsigned      hal_get_reboot_reason();

#endif

