/svarcom/trunk/cmd/echo.c |
---|
0,0 → 1,76 |
/* |
* echo |
*/ |
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_seg, RMOD_OFFSET_ECHOFLAG); |
/* display help only if /? is the only argument */ |
if ((p->argc == 1) && (imatch(p->argv[0], "/?"))) { |
outputnl("Displays messages, or turns command-echoing on or off"); |
outputnl(""); |
outputnl("ECHO [ON | OFF]"); |
outputnl("ECHO [message]"); |
outputnl(""); |
outputnl("Type ECHO without parameters to display the current echo setting."); |
return(-1); |
} |
/* ECHO without any parameter: display current state */ |
if (p->argc == 0) { |
if (*echostatus) { |
outputnl("ECHO is on"); |
} else { |
outputnl("ECHO is off"); |
} |
return(-1); |
} |
/* ECHO ON */ |
if ((p->argc == 1) && (imatch(p->argv[0], "on"))) { |
*echostatus = 1; |
return(-1); |
} |
/* ECHO OFF */ |
if ((p->argc == 1) && (imatch(p->argv[0], "off"))) { |
*echostatus = 0; |
return(-1); |
} |
/* ECHO MSG (start at cmdline+5 since first 5 are "ECHO" + separator) */ |
_asm { |
push ax |
push dx |
push ds |
push si |
mov si, [offs] |
cld /* clear direction flag (DF) so lodsb increments SI */ |
mov ah, 0x02 /* display char from DL */ |
mov ds, [segm] |
NEXTYBTE: |
lodsb /* load byte at DS:[SI] into AL and inc SI (if DF clear) */ |
or al, al /* is AL == 0? then end of string reached */ |
jz DONE |
mov dl, al |
int 0x21 |
jmp NEXTYBTE |
/* output a final CR/LF */ |
DONE: |
mov dl, 0x0D |
int 0x21 |
mov dl, 0x0A |
int 0x21 |
pop si |
pop ds |
pop dx |
pop ax |
} |
return(-1); |
} |
/svarcom/trunk/cmd.c |
---|
11,6 → 11,7 |
#include "doserr.h" |
#include "env.h" |
#include "helpers.h" |
#include "rmodinit.h" |
#define BUFFER_SIZE 2048 /* make sure this is not bigger than the static buffer in command.c */ |
18,8 → 19,9 |
int argc; /* number of arguments */ |
const char *argv[256]; /* pointers to each argument */ |
unsigned short env_seg; /* segment of environment block */ |
unsigned short rmod_seg; /* segment of the resident module */ |
unsigned short argoffset; /* offset of cmdline where first argument starts */ |
const char far *cmdline; /* original cmdline (terminated by \r) */ |
const char far *cmdline; /* original cmdline (terminated by a NULL) */ |
char BUFFER[BUFFER_SIZE]; /* a buffer for whatever is needed */ |
}; |
39,6 → 41,7 |
#include "cmd/del.c" |
#include "cmd/vol.c" /* must be included before dir.c due to dependency */ |
#include "cmd/dir.c" |
#include "cmd/echo.c" |
#include "cmd/exit.c" |
#include "cmd/mkdir.c" |
#include "cmd/path.c" |
70,7 → 73,7 |
{"DATE", cmd_notimpl}, |
{"DEL", cmd_del}, |
{"DIR", cmd_dir}, |
{"ECHO", cmd_notimpl}, |
{"ECHO", cmd_echo}, |
{"ERASE", cmd_del}, |
{"EXIT", cmd_exit}, |
{"LH", cmd_notimpl}, |
155,7 → 158,7 |
} |
int cmd_process(unsigned short env_seg, const char far *cmdline, char *BUFFER) { |
int cmd_process(unsigned short rmod_seg, unsigned short env_seg, const char far *cmdline, char *BUFFER) { |
const struct CMD_ID *cmdptr; |
unsigned short argoffset; |
struct cmd_funcparam *p = (void *)BUFFER; |
196,6 → 199,7 |
/* prepare function parameters and feed it to the cmd handling function */ |
p->argc = cmd_explode(BUFFER + sizeof(*p), cmdline + argoffset, p->argv); |
p->env_seg = env_seg; |
p->rmod_seg = rmod_seg; |
p->argoffset = argoffset; |
p->cmdline = cmdline; |
/svarcom/trunk/cmd.h |
---|
2,7 → 2,7 |
#define CMD_H |
/* process internal commands */ |
int cmd_process(unsigned short env_seg, const char far *cmdline, char *BUFFER); |
int cmd_process(unsigned short env_rmod, unsigned short env_seg, const char far *cmdline, char *BUFFER); |
/* explodes a command into an array of arguments where last arg is NULL |
* returns number of args */ |
/svarcom/trunk/command.c |
---|
15,11 → 15,6 |
* installs it by creating a new PSP, set int 22 vector to the routine, set my "parent PSP" to the routine |
* and quit. |
* |
* |
* |
* good lecture about PSP and allocating memory |
* https://retrocomputing.stackexchange.com/questions/20001/how-much-of-the-program-segment-prefix-area-can-be-reused-by-programs-with-impun/20006#20006 |
* |
* PSP structure |
* http://www.piclist.com/techref/dos/psps.htm |
* |
283,14 → 278,14 |
for (;;) { |
char far *cmdline = MK_FP(rmod_seg, RMOD_OFFSET_INPBUFF + 2); |
unsigned char far *echostatus = MK_FP(rmod_seg, RMOD_OFFSET_ECHOFLAG); |
/* revert input history terminator to \r */ |
if (cmdline[-1] != 0) { |
cmdline[(unsigned short)(cmdline[-1])] = '\r'; |
} |
if (*echostatus != 0) outputnl(""); /* terminate the previous command with a CR/LF */ |
{ |
/* print shell prompt */ |
SKIP_NEWLINE: |
/* print shell prompt (only if ECHO is enabled) */ |
if (*echostatus != 0) { |
char *promptptr = BUFFER; |
buildprompt(promptptr, *rmod_envseg); |
_asm { |
304,6 → 299,11 |
} |
} |
/* revert input history terminator to \r */ |
if (cmdline[-1] != 0) { |
cmdline[(unsigned short)(cmdline[-1])] = '\r'; |
} |
/* wait for user input */ |
_asm { |
push ax |
336,6 → 336,13 |
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 |
342,10 → 349,9 |
pop bx |
pop ax |
} |
outputnl(""); |
/* if nothing entered, loop again */ |
if (cmdline[-1] == 0) continue; |
/* if nothing entered, loop again (but without appending an extra CR/LF) */ |
if (cmdline[-1] == 0) goto SKIP_NEWLINE; |
/* replace \r by a zero terminator */ |
cmdline[(unsigned char)(cmdline[-1])] = 0; |
364,11 → 370,10 |
/* try matching (and executing) an internal command */ |
{ |
int ecode = cmd_process(*rmod_envseg, cmdline, BUFFER); |
int ecode = cmd_process(rmod_seg, *rmod_envseg, cmdline, BUFFER); |
if (ecode >= 0) *lastexitcode = ecode; |
if (ecode >= -1) { /* internal command executed */ |
redir_revert(); /* revert stdout (in case it was redirected) */ |
outputnl(""); |
continue; |
} |
} |
/svarcom/trunk/rmod.asm |
---|
38,8 → 38,11 |
; drive. drive is patched by the transient part of COMMAND.COM |
COMSPECBOOT db "@:\COMMAND.COM", 0 ; +90h |
skipsig: ; +9Fh |
; ECHO status used by COMMAND.COM. 0 = ECHO OFF, 1 = ECHO ON |
CMDECHO db 1 ; +9Fh |
skipsig: ; +A0h |
; set up CS=DS=SS and point SP to my private stack buffer |
mov ax, cs |
mov ds, ax |
/svarcom/trunk/rmod.h |
---|
8,18 → 8,18 |
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,140, |
200,142,216,142,192,142,208,188,105, 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,247, 0,137, 22,249, 0,140, |
6,251, 0,184, 0, 75, 6, 31, 14, 7,187,247, 0,205, 33,115, |
190,140,203,142,219, 4, 48,162, 9, 1,180, 9,186, 5, 1,205, |
33,180, 8,205, 33,235,168, 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 363 |
64, 58, 92, 67, 79, 77, 77, 65, 78, 68, 46, 67, 79, 77, 0, 1, |
140,200,142,216,142,192,142,208,188,106, 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,248, 0,137, 22,250, 0, |
140, 6,252, 0,184, 0, 75, 6, 31, 14, 7,187,248, 0,205, 33, |
115,190,140,203,142,219, 4, 48,162, 10, 1,180, 9,186, 6, 1, |
205, 33,180, 8,205, 33,235,168, 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 364 |
/svarcom/trunk/rmodinit.h |
---|
6,7 → 6,8 |
#define RMOD_OFFSET_INPBUFF 0x0C |
#define RMOD_OFFSET_COMSPECPTR 0x8E |
#define RMOD_OFFSET_BOOTDRIVE 0x90 |
#define RMOD_OFFSET_ROUTINE 0x9F |
#define RMOD_OFFSET_ECHOFLAG 0x9F |
#define RMOD_OFFSET_ROUTINE 0xA0 |
unsigned short rmod_install(unsigned short envsize); |
unsigned short rmod_find(void); |
/svarcom/trunk/svarcom.txt |
---|
16,7 → 16,7 |
- no support for pipes (eg. file.exe | more) |
- no batch file support |
- few internal commands missing: BREAK, CHCP, CTTY, LH, REN, DATE, TIME, ECHO, IF, SHIFT |
- few internal commands missing: BREAK, CHCP, CTTY, LH, REN, DATE, TIME, IF, SHIFT |
Latest version available here: http://svardos.osdn.io/svarcom |
32,6 → 32,7 |
COPY - copies one or more files to another location |
DEL/ERASE - deletes one or more files |
DIR - displays a list of files and subdirectories in a directory |
ECHO - displays messages, or turns command-echoing on or off |
EXIT - quits the command.com program (command interpreter) |
MD/MKDIR - creates a directory |
PATH - displays or sets a search path for executable files |