Subversion Repositories SvarDOS

Compare Revisions

Ignore whitespace Rev 350 → Rev 351

/svarcom/command.c
53,7 → 53,7
 
#include <process.h>
 
#include "rmod.h"
#include "rmodinit.h"
 
struct config {
int locate;
62,130 → 62,6
} cfg;
 
 
#define RMOD_OFFSET_ENVSEG 0x08
#define RMOD_OFFSET_INPBUFF 0x0A
#define RMOD_OFFSET_ROUTINE 0x8C
 
/* returns segment where rmod is installed */
unsigned short rmod_install(unsigned short envsize) {
char far *myptr, far *mcb;
unsigned short far *owner;
unsigned int rmodseg = 0xffff;
unsigned int envseg = 0;
 
/* read my current env segment from PSP */
_asm {
push ax
push bx
mov bx, 0x2c
mov ax, [bx]
mov envseg, ax
pop bx
pop ax
}
 
printf("original (PSP) env buffer at %04X\r\n", envseg);
/* if custom envsize requested, convert it to number of paragraphs */
if (envsize != 0) {
envsize += 15;
envsize /= 16;
}
 
 
_asm {
/* link in the UMB memory chain for enabling high-memory allocation (and save initial status on stack) */
mov ax, 0x5802 /* GET UMB LINK STATE */
int 0x21
xor ah, ah
push ax /* save link state on stack */
mov ax, 0x5803 /* SET UMB LINK STATE */
mov bx, 1
int 0x21
/* get current allocation strategy and save it in DX */
mov ax, 0x5800
int 0x21
push ax
pop dx
/* set strategy to 'last fit, try high then low memory' */
mov ax, 0x5801
mov bx, 0x0082
int 0x21
/* ask for a memory block and save the given segment to rmodseg */
mov ah, 0x48
mov bx, (rmod_len + 15) / 16
int 0x21
jc ALLOC_FAIL
mov rmodseg, ax
/* ask for a memory block for the environment and save it to envseg (only if custom size requested) */
mov bx, envsize
test bx, bx
jz ALLOC_FAIL
mov ah, 0x48
int 0x21
jc ALLOC_FAIL
mov envseg, ax
 
ALLOC_FAIL:
/* restore initial allocation strategy */
mov ax, 0x5801
mov bx, dx
int 0x21
/* restore initial UMB memory link state */
mov ax, 0x5803
pop bx /* pop initial UMB link state from stack */
int 0x21
}
 
if (rmodseg == 0xffff) {
puts("malloc error");
return(0xffff);
}
 
/* copy rmod to its destination */
myptr = MK_FP(rmodseg, 0);
_fmemcpy(myptr, rmod, rmod_len);
 
/* mark rmod memory as "self owned" */
mcb = MK_FP(rmodseg - 1, 0);
owner = (void far *)(mcb + 1);
*owner = rmodseg;
_fmemcpy(mcb + 8, "SVARCOM", 8);
 
/* mark env memory as "self owned" (only if allocated by me) */
if (envsize != 0) {
printf("envseg allocated at %04X:0000 with %u paragraphs\r\n", envseg, envsize);
mcb = MK_FP(envseg - 1, 0);
owner = (void far *)(mcb + 1);
*owner = rmodseg;
_fmemcpy(mcb + 8, "SVARENV", 8);
}
 
/* write env segment to rmod buffer */
owner = MK_FP(rmodseg, RMOD_OFFSET_ENVSEG);
*owner = envseg;
 
/*
printf("MCB sig: %c\r\nMCB owner: 0x%04X\r\n", mcb[0], *owner);
{
int i;
for (i = 0; i < 17; i++) {
printf("%02x ", mcb[i]);
}
printf("\r\n");
for (i = 0; i < 17; i++) {
if (mcb[i] > ' ') {
printf(" %c ", mcb[i]);
} else {
printf(" . ", mcb[i]);
}
}
printf("\r\n");
}*/
 
return(rmodseg);
}
 
 
/* returns zero if s1 starts with s2 */
static int strstartswith(const char *s1, const char *s2) {
while (*s2 != 0) {
213,24 → 89,6
}
 
 
/* scan memory for my shared buffer, return segment of buffer */
static unsigned short rmod_find(void) {
unsigned short i;
unsigned short far *pattern;
 
/* iterate over all paragraphs, looking for my signature */
for (i = 0; i != 65535; i++) {
pattern = MK_FP(i, 0);
if (pattern[0] != 0x1983) continue;
if (pattern[1] != 0x1985) continue;
if (pattern[2] != 0x2017) continue;
if (pattern[3] != 0x2019) continue;
return(i);
}
return(0xffff);
}
 
 
static int explode_progparams(char *s, char const **argvlist) {
int si = 0, argc = 0;
for (;;) {
302,15 → 160,6
printf("rmod_inpbuff at %04X:%04X, env_seg at %04X:0000 (env_size = %u bytes)\r\n", rmod_seg, RMOD_OFFSET_INPBUFF, *rmod_envseg, envsiz);
}
 
_asm {
/* set the int22 handler in my PSP to rmod so DOS jumps to rmod after I terminate */
mov bx, 0x0a
xor ax, ax
mov [bx], ax
mov ax, rmod_seg
mov [bx+2], ax
}
 
for (;;) {
int i, argcount;
char far *cmdline = MK_FP(rmod_seg, RMOD_OFFSET_INPBUFF + 2);
376,6 → 225,7
cmd_set(argcount, argvlist, *rmod_envseg);
continue;
}
if (strcmp(argvlist[0], "exit") == 0) break;
 
execvp(argvlist[0], argvlist);
 
/svarcom/makefile
20,8 → 20,8
 
all: command.com
 
command.com: rmod.h command.c
wcl $(CFLAGS) command.c
command.com: rmod.h command.c rmodinit.c
wcl $(CFLAGS) command.c rmodinit.c
 
rmod.h: file2c.com rmod.com
file2c rmod.com rmod.h rmod
/svarcom/rmodinit.c
0,0 → 1,137
 
#include <i86.h>
#include <stdio.h>
#include <string.h>
 
#include "rmod.h"
 
#include "rmodinit.h"
 
 
/* returns segment where rmod is installed */
unsigned short rmod_install(unsigned short envsize) {
char far *myptr, far *mcb;
unsigned short far *owner;
unsigned int rmodseg = 0xffff;
unsigned int envseg = 0;
 
/* read my current env segment from PSP */
_asm {
push ax
push bx
mov bx, 0x2c
mov ax, [bx]
mov envseg, ax
pop bx
pop ax
}
 
printf("original (PSP) env buffer at %04X\r\n", envseg);
/* if custom envsize requested, convert it to number of paragraphs */
if (envsize != 0) {
envsize += 15;
envsize /= 16;
}
 
 
_asm {
/* link in the UMB memory chain for enabling high-memory allocation (and save initial status on stack) */
mov ax, 0x5802 /* GET UMB LINK STATE */
int 0x21
xor ah, ah
push ax /* save link state on stack */
mov ax, 0x5803 /* SET UMB LINK STATE */
mov bx, 1
int 0x21
/* get current allocation strategy and save it in DX */
mov ax, 0x5800
int 0x21
push ax
pop dx
/* set strategy to 'last fit, try high then low memory' */
mov ax, 0x5801
mov bx, 0x0082
int 0x21
/* ask for a memory block and save the given segment to rmodseg */
mov ah, 0x48
mov bx, (rmod_len + 15) / 16
int 0x21
jc ALLOC_FAIL
mov rmodseg, ax
/* ask for a memory block for the environment and save it to envseg (only if custom size requested) */
mov bx, envsize
test bx, bx
jz ALLOC_FAIL
mov ah, 0x48
int 0x21
jc ALLOC_FAIL
mov envseg, ax
 
ALLOC_FAIL:
/* restore initial allocation strategy */
mov ax, 0x5801
mov bx, dx
int 0x21
/* restore initial UMB memory link state */
mov ax, 0x5803
pop bx /* pop initial UMB link state from stack */
int 0x21
}
 
if (rmodseg == 0xffff) {
puts("malloc error");
return(0xffff);
}
 
/* copy rmod to its destination */
myptr = MK_FP(rmodseg, 0);
_fmemcpy(myptr, rmod, rmod_len);
 
/* mark rmod memory as "self owned" */
mcb = MK_FP(rmodseg - 1, 0);
owner = (void far *)(mcb + 1);
*owner = rmodseg;
_fmemcpy(mcb + 8, "SVARCOM", 8);
 
/* mark env memory as "self owned" (only if allocated by me) */
if (envsize != 0) {
printf("envseg allocated at %04X:0000 with %u paragraphs\r\n", envseg, envsize);
mcb = MK_FP(envseg - 1, 0);
owner = (void far *)(mcb + 1);
*owner = rmodseg;
_fmemcpy(mcb + 8, "SVARENV", 8);
}
 
/* write env segment to rmod buffer */
owner = MK_FP(rmodseg, RMOD_OFFSET_ENVSEG);
*owner = envseg;
 
/* set the int22 handler in my PSP to rmod so DOS jumps to rmod after I terminate */
_asm {
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 */
}
 
return(rmodseg);
}
 
 
/* scan memory for rmod, returns its segment if found, 0xffff otherwise */
unsigned short rmod_find(void) {
unsigned short i;
unsigned short far *pattern;
 
/* iterate over all paragraphs, looking for my signature */
for (i = 0; i != 65535; i++) {
pattern = MK_FP(i, 0);
if (pattern[0] != 0x1983) continue;
if (pattern[1] != 0x1985) continue;
if (pattern[2] != 0x2017) continue;
if (pattern[3] != 0x2019) continue;
return(i);
}
return(0xffff);
}
/svarcom/rmodinit.h
0,0 → 1,11
#ifndef RMODINIT_H
#define RMODINIT_H
 
#define RMOD_OFFSET_ENVSEG 0x08
#define RMOD_OFFSET_INPBUFF 0x0A
#define RMOD_OFFSET_ROUTINE 0x8C
 
unsigned short rmod_install(unsigned short envsize);
unsigned short rmod_find(void);
 
#endif