#include <exec/types.h>
#include <exec/nodes.h>
#include <exec/errors.h>
#include <exec/memory.h>
#include <exec/libraries.h>
#include <exec/devices.h>
#include <exec/resident.h>
#include <exec/semaphores.h>
#include <exec/execbase.h>
#include <dos/dos.h>
#include <dos/dostags.h>
#include <devices/serial.h>
#include <devices/timer.h>
#include <clib/exec_protos.h>
#include <clib/dos_protos.h>

#define arraysize(array)  (sizeof((array))/sizeof(*(array)))

#define SREG_ANSWER     000     /* auto-answer after # rings */
#define SREG_DEBUG      001     /* Debug loglevel */
#define SREG_TIMEOUT    002     /* # of seconds to ring */
#define SREG_DELAY      003     /* negotiation time for ATA */
#define SREG_SPEED      004     /* type of connect msg */
#define SREG_BACKSPACE  005     /* backspace character */
#define SREG_CMD_COUNT  006     /* # of chars in command buffer */
#define SREG_PROTOCOL   007     /* type of protocol to report */
#define SREG_RINGS      010     /* # of rings to do  before timeout */
#define SREG_ANSWERING  011     /* how long to wait before we answer */
#define SREG_LOCALECHO  012     /* whether the modem echos commands or not */
#define SREG_NUMERIC    013     /* verbose/numerical result codes */
#define SREG_STATE      077     /* internal state */

#define STATE_COMMAND       0
#define STATE_CONNECTED     1
#define STATE_ANSWERING     2
#define STATE_DIALING       3

#define MODEM_STACK_SIZE    4096
#define MODEM_TASK_PRI      0
#define MODEM_UNITS         5

#define UNIT_BUF_SIZE       4096

struct NullUnit {
    struct MinList          u_Readlist;         /* read requests */
    struct MinList          u_Writelist;        /* write requests */

    UWORD                   u_OpenCnt;
    UWORD                   u_Unitnum;          /* my number */
    UWORD                   u_Flags;            /* SHARED */

    UBYTE                   u_SReg[64];

    char                    u_Command[256];     /* command line */
    char                    u_Buffer[UNIT_BUF_SIZE];    /* io buffer */
    UWORD                   u_Bufcount;
    char                   *u_Readptr;
    char                   *u_Writeptr;

    struct NullModem       *u_Modem;
};

struct NullModem {
    struct Task            *nm_Taskptr;     /* actually a process */

    struct timerequest      nm_Timerequest;
    struct MsgPort          nm_TimePort;

    UWORD                   nm_OpenCnt;
    UWORD                   nm_Modemnum;

    struct SignalSemaphore  nm_Semaphore;        /* access to modem */
    struct NullUnit        *nm_Unit[2];
};

struct NullBase {
    struct Library      b_Lib;
    APTR                b_Segment;
    struct NullModem   *b_Modem[MODEM_UNITS];
};

extern struct NullBase *DevBase;
