Subversion Repositories SvarDOS

Rev

Rev 359 | Go to most recent revision | Only display areas with differences | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 359 Rev 366
1
 
1
 
2
#include <i86.h>
2
#include <i86.h>
3
#include <stdio.h>
3
#include <stdio.h>
4
#include <string.h>
4
#include <string.h>
5
 
5
 
6
#include "rmod.h"
6
#include "rmod.h"
7
 
7
 
8
#include "rmodinit.h"
8
#include "rmodinit.h"
9
 
9
 
10
 
10
 
11
/* returns segment where rmod is installed */
11
/* returns segment where rmod is installed */
12
unsigned short rmod_install(unsigned short envsize) {
12
unsigned short rmod_install(unsigned short envsize) {
13
  char far *myptr, far *mcb;
13
  char far *myptr, far *mcb;
14
  unsigned short far *owner;
14
  unsigned short far *owner;
15
  unsigned int rmodseg = 0xffff;
15
  unsigned int rmodseg = 0xffff;
16
  unsigned int envseg = 0;
16
  unsigned int envseg = 0;
17
 
17
 
18
  /* read my current env segment from PSP */
18
  /* read my current env segment from PSP */
19
  _asm {
19
  _asm {
20
    push ax
20
    push ax
21
    push bx
21
    push bx
22
    mov bx, 0x2c
22
    mov bx, 0x2c
23
    mov ax, [bx]
23
    mov ax, [bx]
24
    mov envseg, ax
24
    mov envseg, ax
25
    pop bx
25
    pop bx
26
    pop ax
26
    pop ax
27
  }
27
  }
28
 
28
 
29
  printf("original (PSP) env buffer at %04X\r\n", envseg);
29
  printf("original (PSP) env buffer at %04X\r\n", envseg);
30
  /* if custom envsize requested, convert it to number of paragraphs */
30
  /* if custom envsize requested, convert it to number of paragraphs */
31
  if (envsize != 0) {
31
  if (envsize != 0) {
32
    envsize += 15;
32
    envsize += 15;
33
    envsize /= 16;
33
    envsize /= 16;
34
  }
34
  }
35
 
35
 
36
 
36
 
37
  _asm {
37
  _asm {
38
    /* link in the UMB memory chain for enabling high-memory allocation (and save initial status on stack) */
38
    /* link in the UMB memory chain for enabling high-memory allocation (and save initial status on stack) */
39
    mov ax, 0x5802  /* GET UMB LINK STATE */
39
    mov ax, 0x5802  /* GET UMB LINK STATE */
40
    int 0x21
40
    int 0x21
41
    xor ah, ah
41
    xor ah, ah
42
    push ax         /* save link state on stack */
42
    push ax         /* save link state on stack */
43
    mov ax, 0x5803  /* SET UMB LINK STATE */
43
    mov ax, 0x5803  /* SET UMB LINK STATE */
44
    mov bx, 1
44
    mov bx, 1
45
    int 0x21
45
    int 0x21
46
    /* get current allocation strategy and save it in DX */
46
    /* get current allocation strategy and save it in DX */
47
    mov ax, 0x5800
47
    mov ax, 0x5800
48
    int 0x21
48
    int 0x21
49
    push ax
49
    push ax
50
    pop dx
50
    pop dx
51
    /* set strategy to 'last fit, try high then low memory' */
51
    /* set strategy to 'last fit, try high then low memory' */
52
    mov ax, 0x5801
52
    mov ax, 0x5801
53
    mov bx, 0x0082
53
    mov bx, 0x0082
54
    int 0x21
54
    int 0x21
55
    /* ask for a memory block and save the given segment to rmodseg */
55
    /* ask for a memory block and save the given segment to rmodseg */
56
    mov ah, 0x48
56
    mov ah, 0x48
57
    mov bx, (rmod_len + 15) / 16
57
    mov bx, (rmod_len + 15) / 16
58
    int 0x21
58
    int 0x21
59
    jc ALLOC_FAIL
59
    jc ALLOC_FAIL
60
    mov rmodseg, ax
60
    mov rmodseg, ax
61
    /* ask for a memory block for the environment and save it to envseg (only if custom size requested) */
61
    /* ask for a memory block for the environment and save it to envseg (only if custom size requested) */
62
    mov bx, envsize
62
    mov bx, envsize
63
    test bx, bx
63
    test bx, bx
64
    jz ALLOC_FAIL
64
    jz ALLOC_FAIL
65
    mov ah, 0x48
65
    mov ah, 0x48
66
    int 0x21
66
    int 0x21
67
    jc ALLOC_FAIL
67
    jc ALLOC_FAIL
68
    mov envseg, ax
68
    mov envseg, ax
69
 
69
 
70
    ALLOC_FAIL:
70
    ALLOC_FAIL:
71
    /* restore initial allocation strategy */
71
    /* restore initial allocation strategy */
72
    mov ax, 0x5801
72
    mov ax, 0x5801
73
    mov bx, dx
73
    mov bx, dx
74
    int 0x21
74
    int 0x21
75
    /* restore initial UMB memory link state */
75
    /* restore initial UMB memory link state */
76
    mov ax, 0x5803
76
    mov ax, 0x5803
77
    pop bx       /* pop initial UMB link state from stack */
77
    pop bx       /* pop initial UMB link state from stack */
78
    int 0x21
78
    int 0x21
79
  }
79
  }
80
 
80
 
81
  if (rmodseg == 0xffff) {
81
  if (rmodseg == 0xffff) {
82
    puts("malloc error");
82
    puts("malloc error");
83
    return(0xffff);
83
    return(0xffff);
84
  }
84
  }
85
 
85
 
86
  /* copy rmod to its destination */
86
  /* copy rmod to its destination */
87
  myptr = MK_FP(rmodseg, 0);
87
  myptr = MK_FP(rmodseg, 0);
88
  _fmemcpy(myptr, rmod, rmod_len);
88
  _fmemcpy(myptr, rmod, rmod_len);
89
 
89
 
90
  /* mark rmod memory as "self owned" */
90
  /* mark rmod memory as "self owned" */
91
  mcb = MK_FP(rmodseg - 1, 0);
91
  mcb = MK_FP(rmodseg - 1, 0);
92
  owner = (void far *)(mcb + 1);
92
  owner = (void far *)(mcb + 1);
93
  *owner = rmodseg;
93
  *owner = rmodseg;
94
  _fmemcpy(mcb + 8, "SVARCOM", 8);
94
  _fmemcpy(mcb + 8, "SVARCOM", 8);
95
 
95
 
96
  /* mark env memory as "self owned" */
96
  /* mark env memory as "self owned" */
97
  mcb = MK_FP(envseg - 1, 0);
97
  mcb = MK_FP(envseg - 1, 0);
98
  owner = (void far *)(mcb + 1);
98
  owner = (void far *)(mcb + 1);
99
  *owner = rmodseg;
99
  *owner = rmodseg;
100
  _fmemcpy(mcb + 8, "SVARENV", 8);
100
  _fmemcpy(mcb + 8, "SVARENV", 8);
101
 
101
 
102
  /* write env segment to rmod buffer */
102
  /* write env segment to rmod buffer */
103
  owner = MK_FP(rmodseg, RMOD_OFFSET_ENVSEG);
103
  owner = MK_FP(rmodseg, RMOD_OFFSET_ENVSEG);
104
  *owner = envseg;
104
  *owner = envseg;
105
 
105
 
-
 
106
  /* write boot drive to rmod bootdrive field */
-
 
107
  _asm {
-
 
108
    push ax
-
 
109
    push bx
-
 
110
    push dx
-
 
111
    push ds
-
 
112
    mov ax, 0x3305 /* DOS 4.0+ - GET BOOT DRIVE */
-
 
113
    int 0x21 /* boot drive is in DL now (1=A:, 2=B:, etc) */
-
 
114
    add dl, 'A'-1 /* convert to a proper ASCII letter */
-
 
115
    /* set DS to rmodseg */
-
 
116
    mov ax, rmodseg
-
 
117
    mov ds, ax
-
 
118
    /* write boot drive to rmod bootdrive field */
-
 
119
    mov bx, RMOD_OFFSET_BOOTDRIVE
-
 
120
    mov [bx], dl
-
 
121
    pop ds
-
 
122
    pop dx
-
 
123
    pop bx
-
 
124
    pop ax
-
 
125
  }
-
 
126
 
106
  /* set the int22 handler in my PSP to rmod so DOS jumps to rmod after I terminate */
127
  /* set the int22 handler in my PSP to rmod so DOS jumps to rmod after I terminate */
107
  _asm {
128
  _asm {
-
 
129
    push ax
-
 
130
    push bx
108
    mov bx, 0x0a                   /* int22 handler is at 0x0A of the PSP */
131
    mov bx, 0x0a                   /* int22 handler is at 0x0A of the PSP */
109
    mov ax, RMOD_OFFSET_ROUTINE
132
    mov ax, RMOD_OFFSET_ROUTINE
110
    mov [bx], ax                   /* int handler offset */
133
    mov [bx], ax                   /* int handler offset */
111
    mov ax, rmodseg
134
    mov ax, rmodseg
112
    mov [bx+2], ax                 /* int handler segment */
135
    mov [bx+2], ax                 /* int handler segment */
-
 
136
    pop bx
-
 
137
    pop ax
113
  }
138
  }
114
 
139
 
115
  return(rmodseg);
140
  return(rmodseg);
116
}
141
}
117
 
142
 
118
 
143
 
119
/* scan memory for rmod, returns its segment if found, 0xffff otherwise */
144
/* scan memory for rmod, returns its segment if found, 0xffff otherwise */
120
unsigned short rmod_find(void) {
145
unsigned short rmod_find(void) {
121
  unsigned short i;
146
  unsigned short i;
122
  unsigned short far *ptrword;
147
  unsigned short far *ptrword;
123
  unsigned char far *ptrbyte;
148
  unsigned char far *ptrbyte;
124
 
149
 
125
  /* iterate over all paragraphs, looking for my signature */
150
  /* iterate over all paragraphs, looking for my signature */
126
  for (i = 1; i != 65535; i++) {
151
  for (i = 1; i != 65535; i++) {
127
    ptrword = MK_FP(i, 0);
152
    ptrword = MK_FP(i, 0);
128
    if (ptrword[0] != 0x1983) continue;
153
    if (ptrword[0] != 0x1983) continue;
129
    if (ptrword[1] != 0x1985) continue;
154
    if (ptrword[1] != 0x1985) continue;
130
    if (ptrword[2] != 0x2017) continue;
155
    if (ptrword[2] != 0x2017) continue;
131
    if (ptrword[3] != 0x2019) continue;
156
    if (ptrword[3] != 0x2019) continue;
132
    /* extra check: make sure the paragraph before is an MCB block and that it
157
    /* extra check: make sure the paragraph before is an MCB block and that it
133
     * belongs to itself. otherwise I could find the rmod code embedded inside
158
     * belongs to itself. otherwise I could find the rmod code embedded inside
134
     * the command.com binary... */
159
     * the command.com binary... */
135
    ptrbyte = MK_FP(i - 1, 0);
160
    ptrbyte = MK_FP(i - 1, 0);
136
    if ((*ptrbyte != 'M') && (*ptrbyte != 'Z')) continue; /* not an MCB */
161
    if ((*ptrbyte != 'M') && (*ptrbyte != 'Z')) continue; /* not an MCB */
137
    ptrword = MK_FP(i - 1, 1);
162
    ptrword = MK_FP(i - 1, 1);
138
    if (*ptrword != i) continue; /* not belonging to self */
163
    if (*ptrword != i) continue; /* not belonging to self */
139
    return(i);
164
    return(i);
140
  }
165
  }
141
  return(0xffff);
166
  return(0xffff);
142
}
167
}
143
 
168