/svarcom/command.c |
---|
54,6 → 54,7 |
#include <process.h> |
#include "cmd.h" |
#include "env.h" |
#include "helpers.h" |
#include "rmodinit.h" |
314,6 → 315,16 |
{ |
int ecode = cmd_process(*rmod_envseg, cmdline); |
if (ecode >= 0) *lastexitcode = ecode; |
/* update rmod's ptr to COMPSPEC, in case it changed */ |
{ |
unsigned short far *comspecptr = MK_FP(rmod_seg, RMOD_OFFSET_COMSPECPTR); |
char far *comspecfp = env_lookup(*rmod_envseg, "COMSPEC"); |
if (comspecfp != NULL) { |
*comspecptr = FP_OFF(comspecfp) + 8; /* +8 to skip the "COMSPEC=" prefix */ |
} else { |
*comspecptr = 0; |
} |
} |
if (ecode >= -1) continue; /* internal command executed */ |
} |
/svarcom/rmod.asm |
---|
30,9 → 30,16 |
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 |
skipsig: ; +8Eh |
; 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 |
skipsig: ; +9Fh |
; set up CS=DS=SS and point SP to my private stack buffer |
mov ax, cs |
mov ds, ax |
46,16 → 53,30 |
xor ah, ah ; clear out termination status, I only want the exit code |
mov [LEXCODE], ax |
; preset the default COMSPEC pointer to ES:DX (ES is already set to DS) |
mov dx, COMSPECBOOT |
; do I have a valid COMSPEC? |
or [COMSPECPTR], word 0 |
jz USEDEFAULTCOMSPEC |
; set ES:DX to actual COMSPEC |
mov es, [ENVSEG] |
mov dx, [COMSPECPTR] |
USEDEFAULTCOMSPEC: |
; prepare the exec param block |
mov ax, [ENVSEG] |
mov [EXEC_PARAM_REC], ax |
mov ax, COMSPEC |
mov [EXEC_PARAM_REC+2], ax |
mov [EXEC_PARAM_REC+4], ds |
mov [EXEC_PARAM_REC+2], dx |
mov [EXEC_PARAM_REC+4], es |
; execute command.com |
mov ax, 0x4B00 ; DOS 2+ - load & execute program |
mov dx, COMSPEC ; DS:DX - ASCIZ program name TODO: use real COMSPEC... |
push es ; |
pop ds ; |
;mov dx, COMSPEC ; DS:DX - ASCIZ program name (preset already) |
push cs |
pop es |
mov bx, EXEC_PARAM_REC ; ES:BX - parameter block pointer |
int 0x21 |
62,16 → 83,18 |
; if all went well, jump back to start |
jnc skipsig |
; restore DS=CS |
mov bx, cs |
mov ds, bx |
; update error string so it contains the error number |
add al, '0' |
mov [ERRLOAD + 4], al |
; display error message (with trailing COMSPEC) |
; display error message |
mov ah, 0x09 |
mov dx, ERRLOAD |
mov [COMSPCZ], byte '$' ; patch comspec terminator to be $ |
int 0x21 |
mov [COMSPCZ], byte 0 ; restore initial (NULL) compsec terminator |
; wait for keypress |
mov ah, 0x08 |
88,12 → 111,9 |
; +0Ah 4 address of an FCB to be placed at PSP:006c |
EXEC_PARAM_REC db 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 |
ERRLOAD db "ERR x, FAILED TO LOAD COMMAND.COM FROM:", 13, 10 |
ERRLOAD db "ERR x, FAILED TO LOAD COMMAND.COM", 13, 10, '$' |
COMSPEC db "C:\SVN\SVARDOS\SVARCOM\COMMAND.COM" |
COMSPCZ db 0 |
; FreeDOS int 21h functions that I use require at least 32 bytes of stack, |
; here I allocate 64 bytes to be sure |
; DOS int 21h functions that I use require at least 32 bytes of stack, here I |
; allocate 64 bytes to be sure |
STACKBUF db "0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF" |
STACKPTR db "xx" |
/svarcom/rmod.h |
---|
7,20 → 7,19 |
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,140,200, |
142,216,142,192,142,208,188,117, 1,180, 77,205, 33, 48,228,163, |
10, 0,161, 8, 0,163,219, 0,184, 18, 1,163,221, 0,140, 30, |
223, 0,184, 0, 75,186, 18, 1,187,219, 0,205, 33,115,207, 4, |
48,162,237, 0,180, 9,186,233, 0,198, 6, 52, 1, 36,205, 33, |
198, 6, 52, 1, 0,180, 8,205, 33,235,179, 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, 32, 70, 82, 79, 77, 58, |
13, 10, 67, 58, 92, 83, 86, 78, 92, 83, 86, 65, 82, 68, 79, 83, |
92, 83, 86, 65, 82, 67, 79, 77, 92, 67, 79, 77, 77, 65, 78, 68, |
46, 67, 79, 77, 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,120,120}; |
#define rmod_len 375 |
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 |
/svarcom/rmodinit.c |
---|
103,13 → 103,38 |
owner = MK_FP(rmodseg, RMOD_OFFSET_ENVSEG); |
*owner = envseg; |
/* write boot drive to rmod bootdrive field */ |
_asm { |
push ax |
push bx |
push dx |
push ds |
mov ax, 0x3305 /* DOS 4.0+ - GET BOOT DRIVE */ |
int 0x21 /* boot drive is in DL now (1=A:, 2=B:, etc) */ |
add dl, 'A'-1 /* convert to a proper ASCII letter */ |
/* set DS to rmodseg */ |
mov ax, rmodseg |
mov ds, ax |
/* write boot drive to rmod bootdrive field */ |
mov bx, RMOD_OFFSET_BOOTDRIVE |
mov [bx], dl |
pop ds |
pop dx |
pop bx |
pop ax |
} |
/* set the int22 handler in my PSP to rmod so DOS jumps to rmod after I terminate */ |
_asm { |
push ax |
push bx |
mov bx, 0x0a /* int22 handler is at 0x0A of the PSP */ |
mov ax, RMOD_OFFSET_ROUTINE |
mov [bx], ax /* int handler offset */ |
mov ax, rmodseg |
mov [bx+2], ax /* int handler segment */ |
pop bx |
pop ax |
} |
return(rmodseg); |
/svarcom/rmodinit.h |
---|
1,10 → 1,12 |
#ifndef RMODINIT_H |
#define RMODINIT_H |
#define RMOD_OFFSET_ENVSEG 0x08 |
#define RMOD_OFFSET_LEXITCODE 0x0A |
#define RMOD_OFFSET_INPBUFF 0x0C |
#define RMOD_OFFSET_ROUTINE 0x8E |
#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_ROUTINE 0x9F |
unsigned short rmod_install(unsigned short envsize); |
unsigned short rmod_find(void); |