#include #include #include #include #include "..\DPMI.H" #include "..\DPMI10.H" char file_desc[] = "**************************************************************************\n" "* FILE: dpmifun *\n" "* *\n" "* DESC: shell for calling Dpmi functions *\n" "* *\n" "* Copyright (C) 1994 *\n" "* Rainer Schnitker, Heeper Str. 283, 33607 Bielefeld *\n" "* email: rainer@mathematik.uni-bielefeld.de *\n" "* *\n" "* This program is distributed in the hope that it will be useful, *\n" "* but WITHOUT ANY WARRANTY; without even the implied warranty of *\n" "* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *\n" "* GNU General Public License for more details. *\n" "* *\n" "**************************************************************************\n"; /* input function from input.c */ int get_input(char *str, int size, int opt_newline); typedef struct dpmifnct { char *name; int fnct; int args; char *help_text; } DPMIFNCT; DPMIFNCT dpmif[] = { #include "dpmifun.h" }; #define N_REGS 10 /* we could use regs 0 - regs 9 */ int regs[128]; /* so we have 512 bytes for functions */ /* ** Test DPMI server */ #ifdef __EMX__ static int test_dpmi_server(void) { return ((_emx_env & 0x80) | (_emx_env & 0x100)); } #endif #ifdef __GO32__ #include extern Go32_Info_Block _go32_info_block; static int test_dpmi_server(void) { return _go32_info_block.run_mode & _GO32_RUN_MODE_DPMI; } #endif void PrintDescriptor(LPDESCRIPTOR d) { BYTE flag; if (!(d->access & PRESENT_BIT)) { printf("Not Present\n"); return; } if (d->access & SEGMENT_BIT)/* code or data selector */ printf("Base=%02X%02X%04X Limit=%01X%04X %s DPL=%u %s %s %s %s\n", d->base_hi, d->base_mi, d->base_lo, d->lim_hi & LIMIT_HI_MASK, d->lim_lo, (d->lim_hi & GRANULAR_BIT) ? "Pages" : "Bytes", (d->access & DPL_MASK) >> 5, (d->lim_hi & DEFAULT_BIT) ? "32bit" : "16bit", (d->access & CODE_BIT) ? (d->access & CONFIRMING_BIT) ? "CONF" : "CODE" : (d->access & EXPAND_BIT) ? "EXPD" : "DATA", (d->access & WRITE_BIT) ? (d->access & CODE_BIT) ? "R" : "W" : "-", (d->access & ACCESS_BIT) ? "ACC" : " "); else { /* system selector */ flag = d->access & (BYTE) 7; switch (flag) { case 0: break; case 1: printf("TSS%s ", (d->access & 8) ? "386" : "286"); break; case 2: printf("LDT "); break; case 3: printf("BUSYTSS%s ", (d->access & 8) ? "386" : "286"); break; case 4: printf("CALLGATE%s ", (d->access & 8) ? "386" : "286"); break; case 5: printf("TASKGATE "); break; case 6: printf("INT_GATE%s ", (d->access & 8) ? "386" : "286"); break; case 7: printf("TRAPGATE%s ", (d->access & 8) ? "386" : "286"); break; } if (flag <= 3) { printf("Base=%02X%02X%04X Limit=%01X%04X DPL=%u\n", d->base_hi, d->base_mi, d->base_lo, d->lim_hi & LIMIT_HI_MASK, d->lim_lo, (d->access & DPL_MASK) >> 5); } else { printf("Sel=%04X Offset=%02X%02X%04X DPL=%u\n", d->base_lo, d->base_hi, d->lim_hi, d->lim_lo, (d->access & DPL_MASK) >> 5); } } /* else system descriptor */ } void do_help(char *s) { int i; for (i = 0; dpmif[i].name ; i++) if (stricmp(dpmif[i].name, s) == 0) { puts(dpmif[i].help_text); return; } for (i = 0; dpmif[i].name ; i++) if (strstr(dpmif[i].name, s)) puts(dpmif[i].help_text); } static int make_tokens(char *argmem, char **argp) { int i; int args=0; argp[args++] = argmem; for (i = 0; *(argmem + i) != 0; i++) if (*(argmem + i) == ' ') { *(argmem + i) = 0; if (*(argmem + i + 1) == ' ') continue; if (*(argmem + i + 1) == 0) break; argp[args++] = (argmem + i + 1); } argp[args] = 0; return args; } static int get_function(char *s, int *argc) { int i; for (i = 0; dpmif[i].name ; i++) if (strcmp(dpmif[i].name, s) == 0) { *argc = dpmif[i].args; return (int) dpmif[i].fnct; } return 0; } static int my_atoi(char *s) { int c; if ( (*s) < '0' || (*s) > '9') return -1; return ((c=atoi(s)) >= N_REGS) ? -1 : c; } static int hex_atoi(char *s) { int c; if ( (*s) < '0' || (*s) > '9') return 0; if (*(s+1)=='x') sscanf(s+2,"%x\n", &c); else sscanf(s,"%d\n", &c); return c; } static int push_args(int begin, int end, char **argv, int pushv[]) { int i; for (i = begin; i <= end; i++) { if (argv[i][0] == 'r') { int n = my_atoi(& argv[i][1]); if (n<0) return n; pushv[i] = regs[n]; } else if (argv[i][0] == '&' && argv[i][1] == 'r') { int n = my_atoi(& argv[i][2]); if (n<0) return n; pushv[i] = (int) & regs[n]; } else pushv[i] = hex_atoi(argv[i]); } return 0; } int execute_dpmi(int fnct, int p1, int p2, int p3, int p4, int p5); int main(int argc, char **argv, char **env) { char cmd[80]; /* cmd line */ char * argvec[20]; /* cmd tokens */ int push[20]; /* pushed args for dpmi */ unsigned fnct; /* dpmi function */ int n,p,ret; puts(file_desc); puts("help command: help or h\n"); if (!test_dpmi_server()) { puts("I need dpmi, run this program with a dpmiextender\n"); puts("EMX: run rsx ; DJGPP run go32 not with 'nodpmi'\n"); return 1; } for (;;) { printf("(DPMI):"); fflush(stdout); get_input(cmd, sizeof(cmd), 1); n = make_tokens(cmd, argvec); switch (*cmd) { case '0': case 'q': printf("bye\n"); return 0; case '\n': case '\r': continue; case 'h': if (argvec[1]) do_help(argvec[1]); else { printf("\n" "(h)elp - get help\n" "c[0-9] - clear regs 0-9\n" "r[0-9] - print regs 0-9\n" "s[0-9] - set regs 0-9 to v\n" "DPMIFUNCTION args - execute dpmifuncion\n" "! - execute shell\n" "(q)uit - quit\n" "Arrow keys ,,,\n" ); printf("\nExample:\n" "dpmi:help DpmiGet // list all functions with DpmiGet\n" "int DpmiGetCoproStatus (UNIT *) // answer\n" "dpmi:DpmiGetCoproStatus &r1 // call DPMI function with address r1\n" "return 0 = 0x0 // no error\n" "dpmi:r1 // display register 1\n" "dpmi:GetDescriptor 0xf7 &r1 // use r1-r4 as a buffer\n" "return 0 = 0x0 // buffer can use 512 bytes */\n" "dpmi:PrintDescriptor &r1\n" "Base=80003000 Limit=22FFF Bytes DPL=3 32bit CODE R ACC\n" ); } continue; case 'c': n = my_atoi(& argvec[0][1]); if (n < 0) puts("What?"); else regs[n] = 0; continue; case 'r': n = my_atoi(& argvec[0][1]); if (n < 0) puts("What?"); else printf("Reg%d: %d = 0x%X\n", n, regs[n], regs[n]); continue; case 's': n = my_atoi(& argvec[0][1]); if (n < 0) puts("What?"); else { p = hex_atoi(argvec[1]); regs[n] = p; printf("Reg%d: %d = 0x%X\n", n, regs[n], regs[n]); } continue; case '!': if (argvec[1] == NULL) system(""); else if (spawnvpe(P_WAIT, argvec[1], & argvec[1], env)==-1) perror("shell program:"); continue; default: fnct = get_function(argvec[0], &p); if (!fnct) { printf("not a dpmi function\n"); continue; } if (n-1 != p) { printf("Illegal argument count\n"); continue; } push[0] = fnct; if (push_args(1, n-1, argvec, push)<0) { printf("bad parameter\n"); continue; } ret=execute_dpmi(push[0],push[1],push[2],push[3],push[4],push[5]); printf("return %d = 0x%X\n", ret, ret); regs[0] = ret; /* r0 = return register */ } /* switch */ } }