/* TEST2E.C -- version to build TSR2E */

#include <stdlib.h>
#include <string.h>
#include <dos.h>

#include "put.h"

#define MK_FP(seg,ofs) \
    ((void far *)(((unsigned long)(seg) << 16) | (ofs)))

extern unsigned foreground_psp;     // in TSREXAMP.C
extern int Send2E(char *command);   // in SEND2E.C
    
static char buf[80];
static int running = 0;

typedef enum { SAVE=0, RESTORE } SAVEREST;
typedef void (interrupt far *INTVECT)();

void interrupts(int restore)
{
    static INTVECT int_1b, int_23, int_24;
    if (restore)
    {
        _dos_setvect(0x1b, int_1b);
        _dos_setvect(0x23, int_23);
        _dos_setvect(0x24, int_24);
    }
    else
    {
        int_1b = _dos_getvect(0x1b);
        int_23 = _dos_getvect(0x23);
        int_24 = _dos_getvect(0x24);
    }
}

void application(void)
{
    // don't run if we are already running
    if (running)
        return;
    running++;

    // don't execute INT 2Eh if COMMAND.COM already running
    // see if COMMAND.COM running by checking if current PSP is the
    // same as its own parent
    // THIS TEST IS IMPORTANT!  POPPING UP THIS 2E SHELL WHILE
    // COMMAND.COM IS ALREADY RUNNING CAUSES A CRASH AS SOON AS
    // YOU EXIT!
    if (foreground_psp == 
        *((unsigned far *) MK_FP(foreground_psp, 0x16)))
    {
        put_str("COMMAND.COM already running");
        running--;
        return;
    }
    
    put_str("TSR COMMAND SHELL: type DOS commands, or BYE to quit\r\n");
    for (;;)
    {
        put_str("$ ");
        if (! get_str(buf, 80))
            break;
        // added since printing of book: accept EXIT as well as BYE
        if ((strcmp(buf, "bye") == 0 || strcmp(buf, "BYE") == 0) ||
            (strcmp(buf, "exit") == 0 || strcmp(buf, "EXIT") == 0))
            break;
        interrupts(SAVE);
        Send2E(buf);
        interrupts(RESTORE);
    }
    putstr("Bye");
    running--;
}
