Subversion Repositories SvarDOS

Compare Revisions

Ignore whitespace Rev 449 → Rev 450

/svarcom/trunk/cmd/echo.c
29,7 → 29,6
static int cmd_echo(struct cmd_funcparam *p) {
unsigned short offs = FP_OFF(p->cmdline) + 5;
unsigned short segm = FP_SEG(p->cmdline);
unsigned char far *echostatus = MK_FP(p->rmod->rmodseg, RMOD_OFFSET_ECHOFLAG);
 
/* display help only if /? is the only argument */
if ((p->argc == 1) && (imatch(p->argv[0], "/?"))) {
44,7 → 43,7
 
/* ECHO without any parameter: display current state */
if (p->argc == 0) {
if (*echostatus) {
if (p->rmod->echoflag) {
outputnl("ECHO is on");
} else {
outputnl("ECHO is off");
54,13 → 53,13
 
/* ECHO ON */
if ((p->argc == 1) && (imatch(p->argv[0], "on"))) {
*echostatus = 1;
p->rmod->echoflag = 1;
return(-1);
}
 
/* ECHO OFF */
if ((p->argc == 1) && (imatch(p->argv[0], "off"))) {
*echostatus = 0;
p->rmod->echoflag = 0;
return(-1);
}
 
/svarcom/trunk/command.c
323,6 → 323,55
}
 
 
/* wait for user input */
static void cmdline_getinput(unsigned short inpseg, unsigned short inpoff) {
_asm {
push ax
push bx
push cx
push dx
push ds
 
/* is DOSKEY support present? (INT 2Fh, AX=4800h, returns non-zero in AL if present) */
mov ax, 0x4800
int 0x2f
mov bl, al /* save doskey status in BL */
 
/* set up buffered input to inpseg:inpoff */
mov ax, inpseg
push ax
pop ds
mov dx, inpoff
 
/* execute either DOS input or DOSKEY */
test bl, bl /* zf set if no DOSKEY present */
jnz DOSKEY
 
mov ah, 0x0a
int 0x21
jmp short DONE
 
DOSKEY:
mov ax, 0x4810
int 0x2f
 
DONE:
/* terminate command with a CR/LF */
mov ah, 0x02 /* display character in dl */
mov dl, 0x0d
int 0x21
mov dl, 0x0a
int 0x21
 
pop ds
pop dx
pop cx
pop bx
pop ax
}
}
 
 
int main(void) {
static struct config cfg;
static unsigned short rmod_seg;
363,8 → 412,7
}*/
 
do {
char far *cmdline = MK_FP(rmod_seg, RMOD_OFFSET_INPBUFF + 2);
unsigned char far *echostatus = MK_FP(rmod_seg, RMOD_OFFSET_ECHOFLAG);
char far *cmdline = rmod->inputbuf + 2;
 
/* (re)load translation strings if needed */
nls_langreload(BUFFER, *rmod_envseg);
376,12 → 424,12
goto EXEC_CMDLINE;
}
 
if (*echostatus != 0) outputnl(""); /* terminate the previous command with a CR/LF */
if (rmod->echoflag != 0) outputnl(""); /* terminate the previous command with a CR/LF */
 
SKIP_NEWLINE:
 
/* print shell prompt (only if ECHO is enabled) */
if (*echostatus != 0) {
if (rmod->echoflag != 0) {
char *promptptr = BUFFER;
buildprompt(promptptr, *rmod_envseg);
_asm {
400,52 → 448,9
cmdline[(unsigned short)(cmdline[-1])] = '\r';
}
 
/* wait for user input */
_asm {
push ax
push bx
push cx
push dx
push ds
/* wait for user command line */
cmdline_getinput(FP_SEG(rmod->inputbuf), FP_OFF(rmod->inputbuf));
 
/* is DOSKEY support present? (INT 2Fh, AX=4800h, returns non-zero in AL if present) */
mov ax, 0x4800
int 0x2f
mov bl, al /* save doskey status in BL */
 
/* set up buffered input */
mov ax, rmod_seg
push ax
pop ds
mov dx, RMOD_OFFSET_INPBUFF
 
/* execute either DOS input or DOSKEY */
test bl, bl /* zf set if no DOSKEY present */
jnz DOSKEY
 
mov ah, 0x0a
int 0x21
jmp short DONE
 
DOSKEY:
mov ax, 0x4810
int 0x2f
 
DONE:
/* terminate command with a CR/LF */
mov ah, 0x02 /* display character in dl */
mov dl, 0x0d
int 0x21
mov dl, 0x0a
int 0x21
 
pop ds
pop dx
pop cx
pop bx
pop ax
}
 
/* if nothing entered, loop again (but without appending an extra CR/LF) */
if (cmdline[-1] == 0) goto SKIP_NEWLINE;
 
/svarcom/trunk/rmod.asm
25,31 → 25,16
; exit code of last application
LEXCODE dw 0 ; +0Ah
 
; input buffer used for the "previous command" history
BUF000 db 128, 0 ; +0Ch
BUF064 db "0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF"
BUF128 db "0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF"
 
; offset of the COMSPEC variable in the environment block, 0 means "use
; boot drive". this value is patched by the transient part of COMMAND.COM
COMSPECPTR dw 0 ; +8Eh
COMSPECPTR dw 0 ; +0Ch
 
; fallback COMSPEC string used if no COMPSEC is present in the environment
; drive. drive is patched by the transient part of COMMAND.COM
COMSPECBOOT db "@:\COMMAND.COM", 0 ; +90h
COMSPECBOOT db "@:\COMMAND.COM", 0 ; +0Eh
 
; ECHO status used by COMMAND.COM. 0 = ECHO OFF, 1 = ECHO ON
CMDECHO db 1 ; +9Fh
skipsig: ; +1Dh
 
; segment of the first batch in batch chain. this is used by transient
; COMMAND.COM to chain multiple batch files (through CALL). 0 means "none".
BATCHCHAIN dw 0 ; +A0h
 
; original parent (segment of)
ORIGPARENT dd 0 ; +A2h
 
skipsig: ; +A6h
 
; set up CS=DS=SS and point SP to my private stack buffer
mov ax, cs
mov ds, ax
/svarcom/trunk/rmod.h
1,26 → 1,17
const char rmod[] = {
131, 25,133, 25, 23, 32, 25, 32, 0, 0, 0, 0,128, 0, 48, 49,
50, 51, 52, 53, 54, 55, 56, 57, 65, 66, 67, 68, 69, 70, 48, 49,
50, 51, 52, 53, 54, 55, 56, 57, 65, 66, 67, 68, 69, 70, 48, 49,
50, 51, 52, 53, 54, 55, 56, 57, 65, 66, 67, 68, 69, 70, 48, 49,
50, 51, 52, 53, 54, 55, 56, 57, 65, 66, 67, 68, 69, 70, 48, 49,
50, 51, 52, 53, 54, 55, 56, 57, 65, 66, 67, 68, 69, 70, 48, 49,
50, 51, 52, 53, 54, 55, 56, 57, 65, 66, 67, 68, 69, 70, 48, 49,
50, 51, 52, 53, 54, 55, 56, 57, 65, 66, 67, 68, 69, 70, 48, 49,
50, 51, 52, 53, 54, 55, 56, 57, 65, 66, 67, 68, 69, 70, 0, 0,
64, 58, 92, 67, 79, 77, 77, 65, 78, 68, 46, 67, 79, 77, 0, 1,
0, 0, 0, 0, 0, 0,140,200,142,216,142,192,142,208,188,115,
1,180, 77,205, 33, 48,228,163, 10, 0,186,144, 0,131, 14,142,
0, 0,116, 8,142, 6, 8, 0,139, 22,142, 0,161, 8, 0,163,
1, 1,184, 0, 1,163, 3, 1,140, 14, 5, 1,184, 0, 75, 6,
31, 14, 7,187, 1, 1,205, 33,115,188,140,203,142,219, 4, 48,
162, 19, 1,180, 9,186, 15, 1,205, 33,180, 8,205, 33,235,166,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 69,
82, 82, 32,120, 44, 32, 70, 65, 73, 76, 69, 68, 32, 84, 79, 32,
76, 79, 65, 68, 32, 67, 79, 77, 77, 65, 78, 68, 46, 67, 79, 77,
13, 10, 36, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 65, 66, 67,
68, 69, 70, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 65, 66, 67,
68, 69, 70, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 65, 66, 67,
68, 69, 70, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 65, 66, 67,
68, 69, 70,120,120};
#define rmod_len 373
131, 25,133, 25, 23, 32, 25, 32, 0, 0, 0, 0, 0, 0, 64, 58,
92, 67, 79, 77, 77, 65, 78, 68, 46, 67, 79, 77, 0,140,200,142,
216,142,192,142,208,188,234, 0,180, 77,205, 33, 48,228,163, 10,
0,186, 14, 0,131, 14, 12, 0, 0,116, 8,142, 6, 8, 0,139,
22, 12, 0,161, 8, 0,163,120, 0,184,119, 0,163,122, 0,140,
14,124, 0,184, 0, 75, 6, 31, 14, 7,187,120, 0,205, 33,115,
188,140,203,142,219, 4, 48,162,138, 0,180, 9,186,134, 0,205,
33,180, 8,205, 33,235,166, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 69, 82, 82, 32,120, 44, 32, 70, 65, 73,
76, 69, 68, 32, 84, 79, 32, 76, 79, 65, 68, 32, 67, 79, 77, 77,
65, 78, 68, 46, 67, 79, 77, 13, 10, 36, 48, 49, 50, 51, 52, 53,
54, 55, 56, 57, 65, 66, 67, 68, 69, 70, 48, 49, 50, 51, 52, 53,
54, 55, 56, 57, 65, 66, 67, 68, 69, 70, 48, 49, 50, 51, 52, 53,
54, 55, 56, 57, 65, 66, 67, 68, 69, 70, 48, 49, 50, 51, 52, 53,
54, 55, 56, 57, 65, 66, 67, 68, 69, 70,120,120};
#define rmod_len 236
/svarcom/trunk/rmodinit.c
139,8 → 139,10
 
/* prepare result (rmod props) */
res = MK_FP(rmodseg, rmod_len);
_fmemset(res, 0, sizeof(*res));
res->rmodseg = rmodseg;
_fmemset(res, 0, sizeof(*res)); /* zero out */
res->rmodseg = rmodseg; /* rmod segment */
res->inputbuf[0] = 128; /* input buffer for INT 0x21, AH=0Ah*/
res->echoflag = 1; /* ECHO ON */
 
/* write env segment to rmod buffer */
owner = MK_FP(rmodseg, RMOD_OFFSET_ENVSEG);
167,6 → 169,9
pop ax
}
 
/* save my original parent in rmod's memory */
res->origparent = *((unsigned long *)0x0a); /* original parent seg:off is at 0x0a of my PSP */
 
/* set the int22 handler in my PSP to rmod so DOS jumps to rmod after I
* terminate and save the original handler in rmod's memory */
_asm {
176,14 → 181,6
push di
push es
 
/* save my original parent in rmod's memory */
mov es, [rmodseg]
mov si, 0x0a
mov di, RMOD_OFFSET_ORIGPARENT
cld
movsw /* mov ES:[DI], DS:[SI] and SI += 2 and DI += 2 */
movsw
 
mov bx, 0x0a /* int22 handler is at 0x0A of the PSP */
mov ax, RMOD_OFFSET_ROUTINE
mov [bx], ax /* int handler offset */
/svarcom/trunk/rmodinit.h
29,19 → 29,18
#define FLAG_PERMANENT 2
 
struct rmod_props {
unsigned short rmodseg;
unsigned char flags;
char inputbuf[130]; /* input buffer for INT 21, AH=0x0A */
unsigned short rmodseg; /* segment where rmod is loaded */
unsigned long origparent; /* original parent (far ptr) of the shell */
unsigned char flags; /* command line parameters */
unsigned char echoflag; /* ECHO ON / ECHO OFF */
};
 
#define RMOD_OFFSET_ENVSEG 0x08
#define RMOD_OFFSET_LEXITCODE 0x0A
#define RMOD_OFFSET_INPBUFF 0x0C
#define RMOD_OFFSET_COMSPECPTR 0x8E
#define RMOD_OFFSET_BOOTDRIVE 0x90
#define RMOD_OFFSET_ECHOFLAG 0x9F
#define RMOD_OFFSET_BATCHCHAIN 0xA0
#define RMOD_OFFSET_ORIGPARENT 0xA2
#define RMOD_OFFSET_ROUTINE 0xA6
#define RMOD_OFFSET_COMSPECPTR 0x0C
#define RMOD_OFFSET_BOOTDRIVE 0x0E
#define RMOD_OFFSET_ROUTINE 0x1D
 
struct rmod_props far *rmod_install(unsigned short envsize);
struct rmod_props far *rmod_find(void);
/svarcom/trunk/sayonara.c
33,17 → 33,16
* my parent is unknown */
void sayonara(struct rmod_props far *rmod) {
unsigned short rmodseg = rmod->rmodseg;
unsigned long far *orgparent = MK_FP(rmodseg, RMOD_OFFSET_ORIGPARENT);
unsigned long *myparent = (void *)0x0A;
unsigned short far *rmodenv_ptr = MK_FP(rmodseg, RMOD_OFFSET_ENVSEG);
unsigned short rmodenv = *rmodenv_ptr;
 
/* detect "I am the origin shell" situations */
if (*orgparent == 0xffff) return; /* original parent set to 0xffff (DOS-C / FreeDOS) */
if (rmod->origparent == 0xffff) return; /* original parent set to 0xffff (DOS-C / FreeDOS) */
if (rmod->flags & FLAG_PERMANENT) return; /* COMMAND.COM /P */
 
/* set my parent back to original value */
*myparent = *orgparent;
*myparent = rmod->origparent;
 
_asm {
/* free RMOD's code segment and env segment */
/svarcom/trunk/todo.txt
13,7 → 13,9
pipes redirections
basic BAT support (without workflow controls, FOR loops etc)
merge adjacent assembly blocks in rmod_install()
investigate why COMSPEC is not set properly
COMSPEC self-setting does not work under MS-DOS 5/6 (no exepath in env block)
SET COMSPEC=something freezes under MS-DOS 5
DEBUG-ONLY "rmod" internal command for displaying internal stuff
 
 
AT SOME LATER TIME:
39,9 → 41,8
when execing a program, make sure I use the correct PATH.. -> actually I need to parse PATH and look for matches myself for BAT support
 
dynamic resizing of environment space
command line arguments to command.com (/p etc)
single-stepping AUTOEXEC with F8 at boot time (/P /Y)
skipping AUTOEXEC with F5 at boot time (/P /D)
single-stepping AUTOEXEC with F8 at boot time (/Y)
skipping AUTOEXEC with F5 at boot time (/D)
CTTY
LOADHIGH/LH