Subversion Repositories SvarDOS

Rev

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

Rev 349 Rev 350
Line 46... Line 46...
46
 */
46
 */
47
 
47
 
48
#include <i86.h>
48
#include <i86.h>
49
#include <dos.h>
49
#include <dos.h>
50
#include <stdio.h>
50
#include <stdio.h>
-
 
51
#include <stdlib.h>
51
#include <string.h>
52
#include <string.h>
52
 
53
 
53
#include <process.h>
54
#include <process.h>
54
 
55
 
55
#include "rmod.h"
56
#include "rmod.h"
56
 
57
 
57
struct config {
58
struct config {
58
  int locate;
59
  int locate;
59
  int install;
60
  int install;
-
 
61
  int envsiz;
60
} cfg;
62
} cfg;
61
 
63
 
62
 
64
 
-
 
65
#define RMOD_OFFSET_ENVSEG  0x08
-
 
66
#define RMOD_OFFSET_INPBUFF 0x0A
-
 
67
#define RMOD_OFFSET_ROUTINE 0x8C
-
 
68
 
63
/* returns segment where rmod is installed */
69
/* returns segment where rmod is installed */
64
unsigned short install_routine(void) {
70
unsigned short rmod_install(unsigned short envsize) {
65
  char far *ptr, far *mcb;
71
  char far *myptr, far *mcb;
66
  unsigned short far *owner;
72
  unsigned short far *owner;
67
  unsigned int memseg = 0xffff;
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
 
68
 
94
 
69
  _asm {
95
  _asm {
70
    /* link in the UMB memory chain for enabling high-memory allocation (and save initial status on stack) */
96
    /* link in the UMB memory chain for enabling high-memory allocation (and save initial status on stack) */
71
    mov ax, 0x5802  /* GET UMB LINK STATE */
97
    mov ax, 0x5802  /* GET UMB LINK STATE */
72
    int 0x21
98
    int 0x21
Line 82... Line 108...
82
    pop dx
108
    pop dx
83
    /* set strategy to 'last fit, try high then low memory' */
109
    /* set strategy to 'last fit, try high then low memory' */
84
    mov ax, 0x5801
110
    mov ax, 0x5801
85
    mov bx, 0x0082
111
    mov bx, 0x0082
86
    int 0x21
112
    int 0x21
87
    /* ask for a memory block and save the given segment to memseg */
113
    /* ask for a memory block and save the given segment to rmodseg */
88
    mov ah, 0x48
114
    mov ah, 0x48
89
    mov bx, (rmod_len + 15) / 16
115
    mov bx, (rmod_len + 15) / 16
90
    int 0x21
116
    int 0x21
91
    jc ALLOC_FAIL
117
    jc ALLOC_FAIL
92
    mov memseg, ax
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
 
93
    ALLOC_FAIL:
128
    ALLOC_FAIL:
94
    /* restore initial allocation strategy */
129
    /* restore initial allocation strategy */
95
    mov ax, 0x5801
130
    mov ax, 0x5801
96
    mov bx, dx
131
    mov bx, dx
97
    int 0x21
132
    int 0x21
Line 99... Line 134...
99
    mov ax, 0x5803
134
    mov ax, 0x5803
100
    pop bx       /* pop initial UMB link state from stack */
135
    pop bx       /* pop initial UMB link state from stack */
101
    int 0x21
136
    int 0x21
102
  }
137
  }
103
 
138
 
104
  if (memseg == 0xffff) {
139
  if (rmodseg == 0xffff) {
105
    puts("malloc error");
140
    puts("malloc error");
106
    return(0xffff);
141
    return(0xffff);
107
  }
142
  }
-
 
143
 
-
 
144
  /* copy rmod to its destination */
108
  ptr = MK_FP(memseg, 0);
145
  myptr = MK_FP(rmodseg, 0);
-
 
146
  _fmemcpy(myptr, rmod, rmod_len);
-
 
147
 
-
 
148
  /* mark rmod memory as "self owned" */
109
  mcb = MK_FP(memseg - 1, 0);
149
  mcb = MK_FP(rmodseg - 1, 0);
110
  owner = (void far *)(mcb + 1);
150
  owner = (void far *)(mcb + 1);
-
 
151
  *owner = rmodseg;
111
  _fmemcpy(ptr, rmod, rmod_len);
152
  _fmemcpy(mcb + 8, "SVARCOM", 8);
112
 
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
/*
113
  printf("MCB sig: %c\r\nMCB owner: 0x%04X\r\n", mcb[0], *owner);
168
  printf("MCB sig: %c\r\nMCB owner: 0x%04X\r\n", mcb[0], *owner);
114
  {
169
  {
115
    int i;
170
    int i;
116
    for (i = 0; i < 17; i++) {
171
    for (i = 0; i < 17; i++) {
117
      printf("%02x ", mcb[i]);
172
      printf("%02x ", mcb[i]);
Line 123... Line 178...
123
      } else {
178
      } else {
124
        printf(" . ", mcb[i]);
179
        printf(" . ", mcb[i]);
125
      }
180
      }
126
    }
181
    }
127
    printf("\r\n");
182
    printf("\r\n");
128
  }
183
  }*/
-
 
184
 
-
 
185
  return(rmodseg);
-
 
186
}
-
 
187
 
129
 
188
 
130
  /* mark memory as "self owned" */
189
/* returns zero if s1 starts with s2 */
-
 
190
static int strstartswith(const char *s1, const char *s2) {
131
  *owner = memseg;
191
  while (*s2 != 0) {
132
  _fmemcpy(mcb + 8, "COMMAND", 8);
192
    if (*s1 != *s2) return(-1);
-
 
193
    s1++;
-
 
194
    s2++;
-
 
195
  }
133
  return(memseg);
196
  return(0);
134
}
197
}
135
 
198
 
136
 
199
 
137
static void parse_argv(struct config *cfg, int argc, char **argv) {
200
static void parse_argv(struct config *cfg, int argc, char **argv) {
138
  int i;
201
  int i;
139
  memset(cfg, 0, sizeof(*cfg));
202
  memset(cfg, 0, sizeof(*cfg));
-
 
203
 
140
  for (i = 1; i < argc; i++) {
204
  for (i = 1; i < argc; i++) {
141
    if (strcmp(argv[i], "/locate") == 0) {
205
    if (strcmp(argv[i], "/locate") == 0) {
142
      cfg->locate = 1;
206
      cfg->locate = 1;
143
    }
207
    }
-
 
208
    if (strstartswith(argv[i], "/e:") == 0) {
-
 
209
      cfg->envsiz = atoi(argv[i]+3);
-
 
210
      if (cfg->envsiz < 64) cfg->envsiz = 0;
-
 
211
    }
144
  }
212
  }
145
}
213
}
146
 
214
 
147
 
215
 
148
/* scan memory for my shared buffer, return segment of buffer */
216
/* scan memory for my shared buffer, return segment of buffer */
149
static unsigned short find_shm(void) {
217
static unsigned short rmod_find(void) {
150
  unsigned short i;
218
  unsigned short i;
151
  unsigned short far *pattern;
219
  unsigned short far *pattern;
152
 
220
 
153
  /* iterate over all paragraphs, looking for my signature */
221
  /* iterate over all paragraphs, looking for my signature */
154
  for (i = 0; i != 65535; i++) {
222
  for (i = 0; i != 65535; i++) {
155
    pattern = MK_FP(i, 0);
223
    pattern = MK_FP(i, 0);
156
    if (pattern[1] != 0x1983) continue;
224
    if (pattern[0] != 0x1983) continue;
157
    if (pattern[2] != 0x1985) continue;
225
    if (pattern[1] != 0x1985) continue;
158
    if (pattern[3] != 0x2017) continue;
226
    if (pattern[2] != 0x2017) continue;
159
    if (pattern[4] != 0x2019) continue;
227
    if (pattern[3] != 0x2019) continue;
160
    return(i);
228
    return(i);
161
  }
229
  }
162
  return(0xffff);
230
  return(0xffff);
163
}
231
}
164
 
232
 
Line 204... Line 272...
204
}
272
}
205
 
273
 
206
 
274
 
207
int main(int argc, char **argv) {
275
int main(int argc, char **argv) {
208
  struct config cfg;
276
  struct config cfg;
209
  unsigned short env_seg = 0, rmod_seg, rmod_buff = 0;
277
  unsigned short rmod_seg;
210
  void far *rmod_func;
278
  unsigned short far *rmod_envseg;
211
 
279
 
212
  parse_argv(&cfg, argc, argv);
280
  parse_argv(&cfg, argc, argv);
213
 
281
 
214
  rmod_seg = find_shm();
282
  rmod_seg = rmod_find();
215
  if (rmod_seg == 0xffff) {
283
  if (rmod_seg == 0xffff) {
216
    rmod_seg = install_routine();
284
    rmod_seg = rmod_install(cfg.envsiz);
217
    if (rmod_seg == 0xffff) {
285
    if (rmod_seg == 0xffff) {
218
      puts("ERROR: install_rmod() failed");
286
      puts("ERROR: rmod_install() failed");
219
      return(1);
287
      return(1);
220
    } else {
288
    } else {
221
      printf("rmod installed at seg 0x%04X\r\n", rmod_seg);
289
      printf("rmod installed at seg 0x%04X\r\n", rmod_seg);
222
    }
290
    }
223
  } else {
291
  } else {
224
    printf("rmod found at seg 0x%04x\r\n", rmod_seg);
292
    printf("rmod found at seg 0x%04x\r\n", rmod_seg);
225
  }
293
  }
226
 
294
 
227
  rmod_func = MK_FP(rmod_seg, 0x0A);
295
  rmod_envseg = MK_FP(rmod_seg, RMOD_OFFSET_ENVSEG);
228
  /* fetch offset of buffer (result in AX) */
-
 
229
  _asm {
-
 
230
    call dword ptr [rmod_func]
-
 
231
    mov rmod_buff, ax
-
 
232
  }
-
 
233
 
296
 
-
 
297
  {
-
 
298
    unsigned short envsiz;
234
  printf("rmod_buff at %04X:%04X\r\n", rmod_seg, rmod_buff);
299
    unsigned short far *sizptr = MK_FP(*rmod_envseg - 1, 3);
-
 
300
    envsiz = *sizptr;
-
 
301
    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);
-
 
303
  }
235
 
304
 
236
  _asm {
305
  _asm {
237
    /* set the int22 handler in my PSP to rmod so DOS jumps to rmod after I terminate */
306
    /* set the int22 handler in my PSP to rmod so DOS jumps to rmod after I terminate */
238
    mov bx, 0x0a
307
    mov bx, 0x0a
239
    xor ax, ax
308
    xor ax, ax
240
    mov [bx], ax
309
    mov [bx], ax
241
    mov ax, rmod_seg
310
    mov ax, rmod_seg
242
    mov [bx+2], ax
311
    mov [bx+2], ax
243
    /* get the segment of my environment */
-
 
244
    mov bx, 0x2c
-
 
245
    mov ax, [bx]
-
 
246
    mov env_seg, ax
-
 
247
  }
312
  }
248
 
313
 
249
  printf("env_seg at %04X\r\n", env_seg);
-
 
250
 
-
 
251
  for (;;) {
314
  for (;;) {
252
    int i, argcount;
315
    int i, argcount;
253
    char far *cmdline = MK_FP(rmod_seg, rmod_buff + 2);
316
    char far *cmdline = MK_FP(rmod_seg, RMOD_OFFSET_INPBUFF + 2);
254
    char path[256] = "C:\\>$";
317
    char path[256] = "C:\\>$";
255
    char const *argvlist[256];
318
    char const *argvlist[256];
256
    union REGS r;
319
    union REGS r;
257
 
320
 
258
    /* print shell prompt */
321
    /* print shell prompt */
Line 271... Line 334...
271
 
334
 
272
      /* set up buffered input */
335
      /* set up buffered input */
273
      mov ax, rmod_seg
336
      mov ax, rmod_seg
274
      push ax
337
      push ax
275
      pop ds
338
      pop ds
276
      mov dx, rmod_buff
339
      mov dx, RMOD_OFFSET_INPBUFF
277
 
340
 
278
      /* execute either DOS input or DOSKEY */
341
      /* execute either DOS input or DOSKEY */
279
      test bl, bl /* zf set if no DOSKEY present */
342
      test bl, bl /* zf set if no DOSKEY present */
280
      jnz DOSKEY
343
      jnz DOSKEY
281
 
344
 
Line 308... Line 371...
308
      printf("arg #%d = '%s'\r\n", i, argvlist[i]);
371
      printf("arg #%d = '%s'\r\n", i, argvlist[i]);
309
    }
372
    }
310
 
373
 
311
    /* TODO is it an internal command? */
374
    /* TODO is it an internal command? */
312
    if (strcmp(argvlist[0], "set") == 0) {
375
    if (strcmp(argvlist[0], "set") == 0) {
313
      cmd_set(argcount, argvlist, env_seg);
376
      cmd_set(argcount, argvlist, *rmod_envseg);
314
      continue;
377
      continue;
315
    }
378
    }
316
 
379
 
317
    execvp(argvlist[0], argvlist);
380
    execvp(argvlist[0], argvlist);
318
 
381