// Copyright Notice
// ================
// BOCHS is Copyright 1994-1999 by Kevin P. Lawton.
//
// BOCHS is commercial software.
//
// For more information, read the file 'LICENSE' included in the bochs
// distribution.  If you don't have access to this file, or have questions
// regarding the licensing policy, the author may be contacted via:
//
//     US Mail:  Kevin Lawton
//               439 Marrett Rd.
//               Lexington, MA 02421-7714
//
//     EMail:    bochs@world.std.com



/* maximum number of emulated devices allowed.  floppy, mda, etc...
   you can increase this to anything below 256 since an 8-bit handle
   is used for each device */
#define BX_MAX_IO_DEVICES 20

/* number of IRQ lines supported.  In an ISA PC there are two
   PIC chips cascaded together.  each has 8 IRQ lines, so there
   should be 16 IRQ's total */
#define BX_MAX_IRQS 16
#define BX_NO_IRQ  -1


class bx_pit_c;
class bx_keyb_c;
class bx_dma_c;
class bx_floppy_ctrl_c;
class bx_cmos_c;
class bx_serial_c;
class bx_parallel_c;
class bx_unmapped_c;
class bx_vga_c;
class bx_pic_c;
class bx_hard_drive_c;
class bx_sb16_c;
class bx_pci_c;
class bx_ne2k_c;
class bx_g2h_c;




typedef Bit32u (*bx_read_handler_t)(void *, Bit32u, unsigned);
typedef void   (*bx_write_handler_t)(void *, Bit32u, Bit32u, unsigned);


#if BX_USE_DEV_SMF
#  define BX_DEV_SMF  static
#  define BX_DEV_THIS bx_devices.
#else
#  define BX_DEV_SMF
#  define BX_DEV_THIS this->
#endif



class bx_devices_c {
public:
  bx_devices_c(void);
  ~bx_devices_c(void);
  void init(void);
  void register_io_read_handler(void *this_ptr, bx_read_handler_t f, Bit32u addr, const char *name );
  void register_io_write_handler(void *this_ptr, bx_write_handler_t f, Bit32u addr, const char *name );
  void register_irq(unsigned irq, const char *name);
  void unregister_irq(unsigned irq, const char *name);
  void iodev_init(void);
  Bit32u inp(Bit16u addr, unsigned io_len);
  void   outp(Bit16u addr, Bit32u value, unsigned io_len);

  void dma_write8(unsigned channel, Bit8u *data);
  void dma_read8(unsigned channel, Bit8u *data);
  void drq(unsigned channel, Boolean val);
  void raise_hlda(void);
  static void timer_handler(void *);
  void timer(void);

  bx_pci_c         *pci;
  bx_pit_c         *pit;
  bx_keyb_c        *keyboard;
  bx_dma_c         *dma;
  bx_floppy_ctrl_c *floppy;
  bx_cmos_c        *cmos;
  bx_serial_c      *serial;
  bx_parallel_c    *parallel;
  bx_unmapped_c    *unmapped;
  bx_vga_c         *vga;
  bx_pic_c         *pic;
  bx_hard_drive_c  *hard_drive;
  bx_sb16_c        *sb16;
  bx_ne2k_c        *ne2k;
  bx_g2h_c         *g2h;

private:
  Bit8u                 read_handler_id[0x10000];  // 64K
  struct {
    bx_read_handler_t funct;
    void             *this_ptr;
    const char       *handler_name;  // name of device
    } io_read_handler[BX_MAX_IO_DEVICES];
  unsigned              num_read_handles;

  Bit8u                 write_handler_id[0x10000]; // 64K
  struct {
    bx_write_handler_t funct;
    void              *this_ptr;
    const char        *handler_name;  // name of device
    } io_write_handler[BX_MAX_IO_DEVICES];
  unsigned              num_write_handles;

  // more for informative purposes, the names of the devices which
  // are use each of the IRQ 0..15 lines are stored here
  const char *irq_handler_name[BX_MAX_IRQS];

  static Bit32u read_handler(void *this_ptr, Bit32u address, unsigned io_len);
  static void   write_handler(void *this_ptr, Bit32u address, Bit32u value, unsigned io_len);
  BX_DEV_SMF Bit32u port92_read(Bit32u address, unsigned io_len);
  BX_DEV_SMF void   port92_write(Bit32u address, Bit32u value, unsigned io_len);

  int timer_handle;
  };



#include "iodev/pci.h"
#if BX_SUPPORT_VGA
#  include "iodev/vga.h"
#else
#  include "iodev/hga.h"
#endif
#include "iodev/cmos.h"
#include "iodev/dma.h"
#include "iodev/floppy.h"
#include "iodev/harddrv.h"
#include "iodev/keyboard.h"
#include "iodev/parallel.h"
#include "iodev/pic.h"
#include "iodev/pit.h"
#include "iodev/serial.h"
#if BX_SUPPORT_SB16
#  include "iodev/sb16.h"
#endif
#include "iodev/unmapped.h"
#include "iodev/eth.h"
#include "iodev/ne2k.h"
#include "iodev/guest2host.h"
