Listing 1

/*************************************
 *      mon86.c
 *      Simple 8086 rom based monitor.
 **************************************/

#include <stdio.h>
#include <dos.h>

void debug();
int smatch();

struct table
{
    char *t_name;    /* the name for this entry */
    int (*t_fn)();   /* the function to execute */
};

int mem(), go(), error();

struct table cmd[]=
{
    "mem", mem,
    "go",  go,
    "",    error
};


void main(argc, argv)
int argc;
char *argv[];
{
    if(argc != 2)
    {
         printf("%s: incorrect argument count\n",
                argv [0] );
         exit(1);
    }
    else
         printf("mon86 - demo 8086 monitor\n%s
                version\n", argv[1] );
    debug ();
}

void debug()
{
    char line[BUFSIZ];
    char key[32];
    char *lp, *p;
    struct table *tp;
    char *skipwh();
    
    for(;;)
    {
        printf("/nmon86:");
        gets(line);
        lp = skipwh(line);
        if(*lp == NULL)
            continue;
        p = key;
        while(*lp != NULL && !iswhite(*lp))
            *ptt  = *lp++;
        *p = NULL;
        for(tp = cmd; *(tp -> t_name) != NULL; tp++)
            if(smatch(key, tp -> t_name))
                break;
        (*(tp -> t_fn))(lp);
    }
}

int iswhite(c)
register int c;
{
    return (c != NULL && (c == ' ' || c == '\t, ||
            c == '\n' || c == '\r'));
}

char *skipwh(p)
register char *p;
{
    while(iswhite(*p))
        ++p;
    return p;
}

/**********************************************
 * smatch:
 *      match two strings. return true if equal
 *********************************************/
static int smatch(s1, s2)
char *s1, *s2;
{
    while(*s1 != '\0')
    {
        if(*s1 !=*s2)
            break;
        ++s1;
        ++s2;
    }
    return *s1 == *s2;
}

int mem(lp)
char *lp;
{
    unsigned long l = 0l;
    unsigned int seg, offset;
    char far *fp;
    char buf[80];
    
    printf("Memory examine and change\n");
    lp = skipwh(lp);
    while(hexdigit(*lp) >= 0)
        l = (l << 4) + hexdigit(*lp++);
    if(*lp == ':')
    {
        ++lp;
        seg = l;
        l = 0l;
        while(hexdigit(*lp) >= 0)
            l = (l << 4) + hexdigit(*lp++);
        offset = l;
    }
    else
    {
        seg = 0;
        offset = l;
    }
    fp = MK_FP(seg, offset);
    for(;;)
    {
        printf("%04x:%04x - %02x ", FP_SEG(fp),
              FP_OFF(fp), *fp & 0xff);
        gets(buf);
        lp = skipwh(buf);
        if(smatch(".", lp))
            break;
        if(!hexdigit(*lp) >= 0)
        {
            ++fp;
            continue;
        }
        while(hexdigit(*lp) >= 0)
            l = (l << 4) + hexdigit(*lp++);
        *fp++ = l & 0xff;
    }
}
int go(lp)

char *lp;
{
    int (far *fp)();
    unsigned long l = 0l;
    unsigned int seg, offset;
    
    lp = skipwh(lp);
    while(hexdigit(*lp) >= 0)
        l = (l << 4) + hexdigit(*lp++);
    if(*lp == ':')
    {
        ++lp;
        seg= l;
        l = 0l;
        while(hexdigit(*lp) >= 0)
            l = (l << 4) + hexdigit(*lp++);
        offset = l;
    }
    else
    {
        seg= 0;
        offset = l;
    }
    fp = NK_FP(seg, offset);
    printf("Go from %04x:%04x", FP_SEG(fp),
         FP_OFF(fp));
    (*fp)();
}

int error()
{
    printf("*** Unknown command\n");
}

hexdigit(c)
int c;
{
    register char *p;
    register i;
    static char *set = "0123456789abcdef",
           *alt_set = "0123456789ABCDEF";
    
    for(i = 0, p = set; *p != NULL; i++, p++)
        if(c == *p)
            return i;
    for(i = 0, p = alt_set; *p != NULL; i++, p++)
        if(c == *p)
            return i;
    return -1;
}