Subversion Repositories SvarDOS

Rev

Rev 350 | Rev 352 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 350 Rev 351
Line 51... Line 51...
51
#include <stdlib.h>
51
#include <stdlib.h>
52
#include <string.h>
52
#include <string.h>
53
 
53
 
54
#include <process.h>
54
#include <process.h>
55
 
55
 
56
#include "rmod.h"
56
#include "rmodinit.h"
57
 
57
 
58
struct config {
58
struct config {
59
  int locate;
59
  int locate;
60
  int install;
60
  int install;
61
  int envsiz;
61
  int envsiz;
62
} cfg;
62
} cfg;
63
 
63
 
64
 
64
 
65
#define RMOD_OFFSET_ENVSEG  0x08
-
 
66
#define RMOD_OFFSET_INPBUFF 0x0A
-
 
67
#define RMOD_OFFSET_ROUTINE 0x8C
-
 
68
 
-
 
69
/* returns segment where rmod is installed */
-
 
70
unsigned short rmod_install(unsigned short envsize) {
-
 
71
  char far *myptr, far *mcb;
-
 
72
  unsigned short far *owner;
-
 
73
  unsigned int rmodseg = 0xffff;
-
 
74
  unsigned int envseg = 0;
-
 
75
 
-
 
76
  /* read my current env segment from PSP */
-
 
77
  _asm {
-
 
78
    push ax
-
 
79
    push bx
-
 
80
    mov bx, 0x2c
-
 
81
    mov ax, [bx]
-
 
82
    mov envseg, ax
-
 
83
    pop bx
-
 
84
    pop ax
-
 
85
  }
-
 
86
 
-
 
87
  printf("original (PSP) env buffer at %04X\r\n", envseg);
-
 
88
  /* if custom envsize requested, convert it to number of paragraphs */
-
 
89
  if (envsize != 0) {
-
 
90
    envsize += 15;
-
 
91
    envsize /= 16;
-
 
92
  }
-
 
93
 
-
 
94
 
-
 
95
  _asm {
-
 
96
    /* link in the UMB memory chain for enabling high-memory allocation (and save initial status on stack) */
-
 
97
    mov ax, 0x5802  /* GET UMB LINK STATE */
-
 
98
    int 0x21
-
 
99
    xor ah, ah
-
 
100
    push ax         /* save link state on stack */
-
 
101
    mov ax, 0x5803  /* SET UMB LINK STATE */
-
 
102
    mov bx, 1
-
 
103
    int 0x21
-
 
104
    /* get current allocation strategy and save it in DX */
-
 
105
    mov ax, 0x5800
-
 
106
    int 0x21
-
 
107
    push ax
-
 
108
    pop dx
-
 
109
    /* set strategy to 'last fit, try high then low memory' */
-
 
110
    mov ax, 0x5801
-
 
111
    mov bx, 0x0082
-
 
112
    int 0x21
-
 
113
    /* ask for a memory block and save the given segment to rmodseg */
-
 
114
    mov ah, 0x48
-
 
115
    mov bx, (rmod_len + 15) / 16
-
 
116
    int 0x21
-
 
117
    jc ALLOC_FAIL
-
 
118
    mov rmodseg, ax
-
 
119
    /* ask for a memory block for the environment and save it to envseg (only if custom size requested) */
-
 
120
    mov bx, envsize
-
 
121
    test bx, bx
-
 
122
    jz ALLOC_FAIL
-
 
123
    mov ah, 0x48
-
 
124
    int 0x21
-
 
125
    jc ALLOC_FAIL
-
 
126
    mov envseg, ax
-
 
127
 
-
 
128
    ALLOC_FAIL:
-
 
129
    /* restore initial allocation strategy */
-
 
130
    mov ax, 0x5801
-
 
131
    mov bx, dx
-
 
132
    int 0x21
-
 
133
    /* restore initial UMB memory link state */
-
 
134
    mov ax, 0x5803
-
 
135
    pop bx       /* pop initial UMB link state from stack */
-
 
136
    int 0x21
-
 
137
  }
-
 
138
 
-
 
139
  if (rmodseg == 0xffff) {
-
 
140
    puts("malloc error");
-
 
141
    return(0xffff);
-
 
142
  }
-
 
143
 
-
 
144
  /* copy rmod to its destination */
-
 
145
  myptr = MK_FP(rmodseg, 0);
-
 
146
  _fmemcpy(myptr, rmod, rmod_len);
-
 
147
 
-
 
148
  /* mark rmod memory as "self owned" */
-
 
149
  mcb = MK_FP(rmodseg - 1, 0);
-
 
150
  owner = (void far *)(mcb + 1);
-
 
151
  *owner = rmodseg;
-
 
152
  _fmemcpy(mcb + 8, "SVARCOM", 8);
-
 
153
 
-
 
154
  /* mark env memory as "self owned" (only if allocated by me) */
-
 
155
  if (envsize != 0) {
-
 
156
    printf("envseg allocated at %04X:0000 with %u paragraphs\r\n", envseg, envsize);
-
 
157
    mcb = MK_FP(envseg - 1, 0);
-
 
158
    owner = (void far *)(mcb + 1);
-
 
159
    *owner = rmodseg;
-
 
160
    _fmemcpy(mcb + 8, "SVARENV", 8);
-
 
161
  }
-
 
162
 
-
 
163
  /* write env segment to rmod buffer */
-
 
164
  owner = MK_FP(rmodseg, RMOD_OFFSET_ENVSEG);
-
 
165
  *owner = envseg;
-
 
166
 
-
 
167
/*
-
 
168
  printf("MCB sig: %c\r\nMCB owner: 0x%04X\r\n", mcb[0], *owner);
-
 
169
  {
-
 
170
    int i;
-
 
171
    for (i = 0; i < 17; i++) {
-
 
172
      printf("%02x ", mcb[i]);
-
 
173
    }
-
 
174
    printf("\r\n");
-
 
175
    for (i = 0; i < 17; i++) {
-
 
176
      if (mcb[i] > ' ') {
-
 
177
        printf(" %c ", mcb[i]);
-
 
178
      } else {
-
 
179
        printf(" . ", mcb[i]);
-
 
180
      }
-
 
181
    }
-
 
182
    printf("\r\n");
-
 
183
  }*/
-
 
184
 
-
 
185
  return(rmodseg);
-
 
186
}
-
 
187
 
-
 
188
 
-
 
189
/* returns zero if s1 starts with s2 */
65
/* returns zero if s1 starts with s2 */
190
static int strstartswith(const char *s1, const char *s2) {
66
static int strstartswith(const char *s1, const char *s2) {
191
  while (*s2 != 0) {
67
  while (*s2 != 0) {
192
    if (*s1 != *s2) return(-1);
68
    if (*s1 != *s2) return(-1);
193
    s1++;
69
    s1++;
Line 211... Line 87...
211
    }
87
    }
212
  }
88
  }
213
}
89
}
214
 
90
 
215
 
91
 
216
/* scan memory for my shared buffer, return segment of buffer */
-
 
217
static unsigned short rmod_find(void) {
-
 
218
  unsigned short i;
-
 
219
  unsigned short far *pattern;
-
 
220
 
-
 
221
  /* iterate over all paragraphs, looking for my signature */
-
 
222
  for (i = 0; i != 65535; i++) {
-
 
223
    pattern = MK_FP(i, 0);
-
 
224
    if (pattern[0] != 0x1983) continue;
-
 
225
    if (pattern[1] != 0x1985) continue;
-
 
226
    if (pattern[2] != 0x2017) continue;
-
 
227
    if (pattern[3] != 0x2019) continue;
-
 
228
    return(i);
-
 
229
  }
-
 
230
  return(0xffff);
-
 
231
}
-
 
232
 
-
 
233
 
-
 
234
static int explode_progparams(char *s, char const **argvlist) {
92
static int explode_progparams(char *s, char const **argvlist) {
235
  int si = 0, argc = 0;
93
  int si = 0, argc = 0;
236
  for (;;) {
94
  for (;;) {
237
    /* skip to next non-space character */
95
    /* skip to next non-space character */
238
    while (s[si] == ' ') si++;
96
    while (s[si] == ' ') si++;
Line 300... Line 158...
300
    envsiz = *sizptr;
158
    envsiz = *sizptr;
301
    envsiz *= 16;
159
    envsiz *= 16;
302
    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);
160
    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);
303
  }
161
  }
304
 
162
 
305
  _asm {
-
 
306
    /* set the int22 handler in my PSP to rmod so DOS jumps to rmod after I terminate */
-
 
307
    mov bx, 0x0a
-
 
308
    xor ax, ax
-
 
309
    mov [bx], ax
-
 
310
    mov ax, rmod_seg
-
 
311
    mov [bx+2], ax
-
 
312
  }
-
 
313
 
-
 
314
  for (;;) {
163
  for (;;) {
315
    int i, argcount;
164
    int i, argcount;
316
    char far *cmdline = MK_FP(rmod_seg, RMOD_OFFSET_INPBUFF + 2);
165
    char far *cmdline = MK_FP(rmod_seg, RMOD_OFFSET_INPBUFF + 2);
317
    char path[256] = "C:\\>$";
166
    char path[256] = "C:\\>$";
318
    char const *argvlist[256];
167
    char const *argvlist[256];
Line 374... Line 223...
374
    /* TODO is it an internal command? */
223
    /* TODO is it an internal command? */
375
    if (strcmp(argvlist[0], "set") == 0) {
224
    if (strcmp(argvlist[0], "set") == 0) {
376
      cmd_set(argcount, argvlist, *rmod_envseg);
225
      cmd_set(argcount, argvlist, *rmod_envseg);
377
      continue;
226
      continue;
378
    }
227
    }
-
 
228
    if (strcmp(argvlist[0], "exit") == 0) break;
379
 
229
 
380
    execvp(argvlist[0], argvlist);
230
    execvp(argvlist[0], argvlist);
381
 
231
 
382
    /* execvp() replaces the current process by the new one
232
    /* execvp() replaces the current process by the new one
383
    if I am still alive then external command failed to execute */
233
    if I am still alive then external command failed to execute */