Subversion Repositories SvarDOS

Rev

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

Rev 62 Rev 65
1
/*
1
/*
2
 * SVAROG386 INSTALL
2
 * SVAROG386 INSTALL
3
 * COPYRIGHT (C) 2016 MATEUSZ VISTE
3
 * COPYRIGHT (C) 2016 MATEUSZ VISTE
4
 *
4
 *
5
 * http://svarog386.sf.net
5
 * http://svarog386.sf.net
6
 */
6
 */
7
 
7
 
8
#include <dos.h>
8
#include <dos.h>
9
#include <direct.h>  /* mkdir() */
9
#include <direct.h>  /* mkdir() */
10
#include <stdio.h>   /* printf() and friends */
10
#include <stdio.h>   /* printf() and friends */
11
#include <stdlib.h>  /* system() */
11
#include <stdlib.h>  /* system() */
12
#include <string.h>  /* memcpy() */
12
#include <string.h>  /* memcpy() */
13
#include <unistd.h>
13
#include <unistd.h>
14
 
14
 
15
#include "kitten\kitten.h"
15
#include "kitten\kitten.h"
16
 
16
 
17
#include "cdrom.h"
17
#include "cdrom.h"
18
#include "input.h"
18
#include "input.h"
19
#include "video.h"
19
#include "video.h"
20
 
20
 
21
 
21
 
22
/* color scheme (color, mono) */
22
/* color scheme (color, mono) */
23
static unsigned short COLOR_TITLEBAR[2] = {0x7000,0x7000};
23
static unsigned short COLOR_TITLEBAR[2] = {0x7000,0x7000};
24
static unsigned short COLOR_BODY[2] = {0x1700,0x0700};
24
static unsigned short COLOR_BODY[2] = {0x1700,0x0700};
25
static unsigned short COLOR_SELECT[2] = {0x7000,0x7000};
25
static unsigned short COLOR_SELECT[2] = {0x7000,0x7000};
26
static unsigned short COLOR_SELECTCUR[2] = {0x1F00,0x0700};
26
static unsigned short COLOR_SELECTCUR[2] = {0x1F00,0x0700};
27
 
27
 
28
/* mono flag */
28
/* mono flag */
29
static int mono = 0;
29
static int mono = 0;
30
 
30
 
31
/* how much disk space does Svarog386 require (in MiB) */
31
/* how much disk space does Svarog386 require (in MiB) */
32
#define SVAROG_DISK_REQ 8
32
#define SVAROG_DISK_REQ 8
33
 
33
 
34
 
34
 
35
/* reboot the computer */
35
/* reboot the computer */
36
static void reboot(void) {
36
static void reboot(void) {
37
  void ((far *bootroutine)()) = (void (far *)()) 0xFFFF0000L;
37
  void ((far *bootroutine)()) = (void (far *)()) 0xFFFF0000L;
38
  int far *rstaddr = (int far *)0x00400072L; /* BIOS boot flag is at 0040:0072 */
38
  int far *rstaddr = (int far *)0x00400072L; /* BIOS boot flag is at 0040:0072 */
39
  *rstaddr = 0x1234; /* 0x1234 = warm boot, 0 = cold boot */
39
  *rstaddr = 0x1234; /* 0x1234 = warm boot, 0 = cold boot */
40
  (*bootroutine)(); /* jump to the BIOS reboot routine at FFFF:0000 */
40
  (*bootroutine)(); /* jump to the BIOS reboot routine at FFFF:0000 */
41
}
41
}
42
 
42
 
43
 
43
 
44
/* outputs a string to screen with taking care of word wrapping. returns amount of lines. */
44
/* outputs a string to screen with taking care of word wrapping. returns amount of lines. */
45
static int putstringwrap(int y, int x, unsigned short attr, char *s) {
45
static int putstringwrap(int y, int x, unsigned short attr, char *s) {
46
  int linew, lincount;
46
  int linew, lincount;
47
  linew = 80;
47
  linew = 80;
48
  if (x >= 0) linew -= (x << 1);
48
  if (x >= 0) linew -= (x << 1);
49
 
49
 
50
  for (lincount = 1; y+lincount < 25; lincount++) {
50
  for (lincount = 1; y+lincount < 25; lincount++) {
51
    int i, len = linew;
51
    int i, len = linew;
52
    for (i = 0; i <= linew; i++) {
52
    for (i = 0; i <= linew; i++) {
53
      if (s[i] == ' ') len = i;
53
      if (s[i] == ' ') len = i;
54
      if (s[i] == '\n') {
54
      if (s[i] == '\n') {
55
        len = i;
55
        len = i;
56
        break;
56
        break;
57
      }
57
      }
58
      if (s[i] == 0) {
58
      if (s[i] == 0) {
59
        len = i;
59
        len = i;
60
        break;
60
        break;
61
      }
61
      }
62
    }
62
    }
63
    video_putstring(y++, x, attr, s, len);
63
    video_putstring(y++, x, attr, s, len);
64
    s += len;
64
    s += len;
65
    if (*s == 0) break;
65
    if (*s == 0) break;
66
    s += 1; /* skip the whitespace char */
66
    s += 1; /* skip the whitespace char */
67
  }
67
  }
68
  return(lincount);
68
  return(lincount);
69
}
69
}
70
 
70
 
71
 
71
 
72
/* an NLS wrapper around video_putstring(), also performs line wrapping when
72
/* an NLS wrapper around video_putstring(), also performs line wrapping when
73
 * needed. returns the amount of lines that were output */
73
 * needed. returns the amount of lines that were output */
74
static int putstringnls(int y, int x, unsigned short attr, int nlsmaj, int nlsmin, char *s) {
74
static int putstringnls(int y, int x, unsigned short attr, int nlsmaj, int nlsmin, char *s) {
75
  s = kittengets(nlsmaj, nlsmin, s);
75
  s = kittengets(nlsmaj, nlsmin, s);
76
  return(putstringwrap(y, x, attr, s));
76
  return(putstringwrap(y, x, attr, s));
77
}
77
}
78
 
78
 
79
 
79
 
80
#define LDEC(x,y) (((unsigned short)x << 8) | (unsigned short)y)
80
#define LDEC(x,y) (((unsigned short)x << 8) | (unsigned short)y)
81
/* provides codepage and country files required by lang */
81
/* provides codepage and country files required by lang */
82
static int getnlscp(char *lang, int *egafile) {
82
static int getnlscp(char *lang, int *egafile) {
83
  unsigned short l;
83
  unsigned short l;
84
  l = lang[0];
84
  l = lang[0];
85
  l <<= 8;
85
  l <<= 8;
86
  l |= lang[1];
86
  l |= lang[1];
87
  switch (l) {
87
  switch (l) {
88
    case LDEC('E','N'):
88
    case LDEC('E','N'):
89
      *egafile = 0;
89
      *egafile = 0;
90
      return(437);
90
      return(437);
91
    case LDEC('P','L'):
91
    case LDEC('P','L'):
92
      *egafile = 10;
92
      *egafile = 10;
93
      return(991);
93
      return(991);
94
  }
94
  }
95
  *egafile = 0;
95
  *egafile = 0;
96
  return(437);
96
  return(437);
97
}
97
}
98
 
98
 
99
 
99
 
100
static int menuselect(int ypos, int xpos, int height, char **list) {
100
static int menuselect(int ypos, int xpos, int height, char **list) {
101
  int i, offset = 0, res = 0, count, width = 0;
101
  int i, offset = 0, res = 0, count, width = 0;
102
  /* count how many languages there is */
102
  /* count how many languages there is */
103
  for (count = 0; list[count] != NULL; count++) {
103
  for (count = 0; list[count] != NULL; count++) {
104
    int len = strlen(list[count]);
104
    int len = strlen(list[count]);
105
    if (len > width) width = len;
105
    if (len > width) width = len;
106
  }
106
  }
107
 
107
 
108
  /* if xpos negative, means 'center out' */
108
  /* if xpos negative, means 'center out' */
109
  if (xpos < 0) xpos = 39 - (width >> 1);
109
  if (xpos < 0) xpos = 39 - (width >> 1);
110
 
110
 
111
  video_putchar(ypos, xpos+width+2, COLOR_SELECT[mono], 0xBF);         /*       \ */
111
  video_putchar(ypos, xpos+width+2, COLOR_SELECT[mono], 0xBF);         /*       \ */
112
  video_putchar(ypos, xpos-1, COLOR_SELECT[mono], 0xDA);               /*  /      */
112
  video_putchar(ypos, xpos-1, COLOR_SELECT[mono], 0xDA);               /*  /      */
113
  video_putchar(ypos+height-1, xpos-1, COLOR_SELECT[mono], 0xC0);      /*  \      */
113
  video_putchar(ypos+height-1, xpos-1, COLOR_SELECT[mono], 0xC0);      /*  \      */
114
  video_putchar(ypos+height-1, xpos+width+2, COLOR_SELECT[mono], 0xD9);/*      /  */
114
  video_putchar(ypos+height-1, xpos+width+2, COLOR_SELECT[mono], 0xD9);/*      /  */
115
  video_putcharmulti(ypos, xpos, COLOR_SELECT[mono], 0xC4, width + 2, 1);
115
  video_putcharmulti(ypos, xpos, COLOR_SELECT[mono], 0xC4, width + 2, 1);
116
  video_putcharmulti(ypos+height-1, xpos, COLOR_SELECT[mono], 0xC4, width + 2, 1);
116
  video_putcharmulti(ypos+height-1, xpos, COLOR_SELECT[mono], 0xC4, width + 2, 1);
117
  video_putcharmulti(ypos+1, xpos-1, COLOR_SELECT[mono], 0xB3, height - 2, 80);
117
  video_putcharmulti(ypos+1, xpos-1, COLOR_SELECT[mono], 0xB3, height - 2, 80);
118
  video_putcharmulti(ypos+1, xpos+width+2, COLOR_SELECT[mono], 0xB3, height - 2, 80);
118
  video_putcharmulti(ypos+1, xpos+width+2, COLOR_SELECT[mono], 0xB3, height - 2, 80);
119
 
119
 
120
  for (;;) {
120
  for (;;) {
121
    int key;
121
    int key;
122
    /* list of selectable items */
122
    /* list of selectable items */
123
    for (i = 0; i < height - 2; i++) {
123
    for (i = 0; i < height - 2; i++) {
124
      if (i + offset == res) {
124
      if (i + offset == res) {
125
        video_putchar(ypos + 1 + i, xpos, COLOR_SELECTCUR[mono], 16);
125
        video_putchar(ypos + 1 + i, xpos, COLOR_SELECTCUR[mono], 16);
126
        video_putchar(ypos + 1 + i, xpos+width+1, COLOR_SELECTCUR[mono], 17);
126
        video_putchar(ypos + 1 + i, xpos+width+1, COLOR_SELECTCUR[mono], 17);
127
        video_movecursor(ypos + 1 + i, xpos);
127
        video_movecursor(ypos + 1 + i, xpos);
128
        video_putstringfix(ypos + 1 + i, xpos+1, COLOR_SELECTCUR[mono], list[i + offset], width);
128
        video_putstringfix(ypos + 1 + i, xpos+1, COLOR_SELECTCUR[mono], list[i + offset], width);
129
      } else if (i + offset < count) {
129
      } else if (i + offset < count) {
130
        video_putchar(ypos + 1 + i, xpos, COLOR_SELECT[mono], ' ');
130
        video_putchar(ypos + 1 + i, xpos, COLOR_SELECT[mono], ' ');
131
        video_putchar(ypos + 1 + i, xpos+width+1, COLOR_SELECT[mono], ' ');
131
        video_putchar(ypos + 1 + i, xpos+width+1, COLOR_SELECT[mono], ' ');
132
        video_putstringfix(ypos + 1 + i, xpos+1, COLOR_SELECT[mono], list[i + offset], width);
132
        video_putstringfix(ypos + 1 + i, xpos+1, COLOR_SELECT[mono], list[i + offset], width);
133
      } else {
133
      } else {
134
        video_putcharmulti(ypos + 1 + i, xpos, COLOR_SELECT[mono], ' ', width+2, 1);
134
        video_putcharmulti(ypos + 1 + i, xpos, COLOR_SELECT[mono], ' ', width+2, 1);
135
      }
135
      }
136
    }
136
    }
137
    key = input_getkey();
137
    key = input_getkey();
138
    if (key == 0x0D) { /* ENTER */
138
    if (key == 0x0D) { /* ENTER */
139
      return(res);
139
      return(res);
140
    } else if (key == 0x148) { /* up */
140
    } else if (key == 0x148) { /* up */
141
      if (res > 0) {
141
      if (res > 0) {
142
        res--;
142
        res--;
143
        if (res < offset) offset = res;
143
        if (res < offset) offset = res;
144
      }
144
      }
145
    } else if (key == 0x150) { /* down */
145
    } else if (key == 0x150) { /* down */
146
      if (res+1 < count) {
146
      if (res+1 < count) {
147
        res++;
147
        res++;
148
        if (res > offset + height - 3) offset = res - (height - 3);
148
        if (res > offset + height - 3) offset = res - (height - 3);
149
      }
149
      }
150
    } else if (key == 0x147) { /* home */
150
    } else if (key == 0x147) { /* home */
151
      res = 0;
151
      res = 0;
152
      offset = 0;
152
      offset = 0;
153
    } else if (key == 0x14F) { /* end */
153
    } else if (key == 0x14F) { /* end */
154
      res = count - 1;
154
      res = count - 1;
155
      if (res > offset + height - 3) offset = res - (height - 3);
155
      if (res > offset + height - 3) offset = res - (height - 3);
156
    } else if (key == 0x1B) {  /* ESC */
156
    } else if (key == 0x1B) {  /* ESC */
157
      return(-1);
157
      return(-1);
158
    } else {
158
    } else {
159
      char buf[8];
159
      char buf[8];
160
      snprintf(buf, sizeof(buf), "0x%02X ", key);
160
      snprintf(buf, sizeof(buf), "0x%02X ", key);
161
      video_putstring(1, 0, COLOR_BODY[mono], buf, -1);
161
      video_putstring(1, 0, COLOR_BODY[mono], buf, -1);
162
    }
162
    }
163
  }
163
  }
164
}
164
}
165
 
165
 
166
static void newscreen(void) {
166
static void newscreen(void) {
167
  int x;
167
  int x;
168
  char *title;
168
  char *title;
169
  title = kittengets(0, 0, "SVAROG386 INSTALLATION");
169
  title = kittengets(0, 0, "SVAROG386 INSTALLATION");
170
  for (x = 0; x < 80; x++) video_putchar(0, x, COLOR_TITLEBAR[mono], ' ');
170
  for (x = 0; x < 80; x++) video_putchar(0, x, COLOR_TITLEBAR[mono], ' ');
171
  video_putstring(0, 40 - (strlen(title) >> 1), COLOR_TITLEBAR[mono], title, -1);
171
  video_putstring(0, 40 - (strlen(title) >> 1), COLOR_TITLEBAR[mono], title, -1);
172
  video_clear(COLOR_BODY[mono], 80);
172
  video_clear(COLOR_BODY[mono], 80);
173
  video_movecursor(25,0);
173
  video_movecursor(25,0);
174
}
174
}
175
 
175
 
176
static int selectlang(char *lang) {
176
static int selectlang(char *lang) {
177
  int choice;
177
  int choice;
178
  int x;
178
  int x;
179
  char *msg;
179
  char *msg;
180
  char *code;
180
  char *code;
181
  char *langlist[] = {
181
  char *langlist[] = {
182
    "English\0EN",
182
    "English\0EN",
183
    "French\0FR",
183
/*    "French\0FR",*/
184
    "German\0DE",
-
 
185
    "Italian\0IT",
-
 
186
    "Polish\0PL",
184
    "Polish\0PL",
187
    "Russian\0RU",
-
 
188
    "Slovenian\0SL",
-
 
189
    "Spanish\0ES",
-
 
190
    "Turkish\0TR",
185
/*    "Turkish\0TR",*/
191
    NULL
186
    NULL
192
  };
187
  };
193
 
188
 
194
  newscreen();
189
  newscreen();
195
  msg = kittengets(1, 0, "Welcome to Svarog386");
190
  msg = kittengets(1, 0, "Welcome to Svarog386");
196
  x = 40 - (strlen(msg) >> 1);
191
  x = 40 - (strlen(msg) >> 1);
197
  video_putstring(4, x, COLOR_BODY[mono], msg, -1);
192
  video_putstring(4, x, COLOR_BODY[mono], msg, -1);
198
  video_putcharmulti(5, x, COLOR_BODY[mono], '=', strlen(msg), 1);
193
  video_putcharmulti(5, x, COLOR_BODY[mono], '=', strlen(msg), 1);
199
  putstringnls(8, -1, COLOR_BODY[mono], 1, 1, "Please select your language from the list below:");
194
  putstringnls(8, -1, COLOR_BODY[mono], 1, 1, "Please select your language from the list below:");
200
  choice = menuselect(10, -1, 12, langlist);
195
  choice = menuselect(11, -1, 3, langlist);
201
  if (choice < 0) return(-1);
196
  if (choice < 0) return(-1);
202
  /* write short language code into lang */
197
  /* write short language code into lang */
203
  for (code = langlist[choice]; *code != 0; code++);
198
  for (code = langlist[choice]; *code != 0; code++);
204
  memcpy(lang, code + 1, 2);
199
  memcpy(lang, code + 1, 2);
205
  lang[2] = 0;
200
  lang[2] = 0;
206
  return(0);
201
  return(0);
207
}
202
}
208
 
203
 
209
 
204
 
210
/* returns 0 if installation must proceed, non-zero otherwise */
205
/* returns 0 if installation must proceed, non-zero otherwise */
211
static int welcomescreen(void) {
206
static int welcomescreen(void) {
212
  char *choice[] = {"Install Svarog386 to disk", "Quit to DOS", NULL};
207
  char *choice[] = {"Install Svarog386 to disk", "Quit to DOS", NULL};
213
  choice[0] = kittengets(0, 1, choice[0]);
208
  choice[0] = kittengets(0, 1, choice[0]);
214
  choice[1] = kittengets(0, 2, choice[1]);
209
  choice[1] = kittengets(0, 2, choice[1]);
215
  newscreen();
210
  newscreen();
216
  putstringnls(4, 1, COLOR_BODY[mono], 2, 0, "You are about to install Svarog386: a free, MSDOS-compatible operating system based on the FreeDOS kernel. Svarog386 targets 386+ computers and comes with a variety of third-party applications.\n\nWARNING: If your PC has another operating system installed, this other system might be unable to boot once Svarog386 is installed.");
211
  putstringnls(4, 1, COLOR_BODY[mono], 2, 0, "You are about to install Svarog386: a free, MSDOS-compatible operating system based on the FreeDOS kernel. Svarog386 targets 386+ computers and comes with a variety of third-party applications.\n\nWARNING: If your PC has another operating system installed, this other system might be unable to boot once Svarog386 is installed.");
217
  return(menuselect(13, -1, 4, choice));
212
  return(menuselect(13, -1, 4, choice));
218
}
213
}
219
 
214
 
220
 
215
 
221
/* returns 1 if drive is removable, 0 if not, -1 on error */
216
/* returns 1 if drive is removable, 0 if not, -1 on error */
222
static int isdriveremovable(int drv) {
217
static int isdriveremovable(int drv) {
223
  union REGS r;
218
  union REGS r;
224
  r.x.ax = 0x4408;
219
  r.x.ax = 0x4408;
225
  r.h.bl = drv;
220
  r.h.bl = drv;
226
  int86(0x21, &r, &r);
221
  int86(0x21, &r, &r);
227
  /* CF set on error, AX set to 0 if removable, 1 if fixed */
222
  /* CF set on error, AX set to 0 if removable, 1 if fixed */
228
  if (r.x.cflag != 0) return(-1);
223
  if (r.x.cflag != 0) return(-1);
229
  if (r.x.ax == 0) return(1);
224
  if (r.x.ax == 0) return(1);
230
  return(0);
225
  return(0);
231
}
226
}
232
 
227
 
233
 
228
 
234
/* returns total disk space of drive drv (in MiB, max 2048), or -1 if drive invalid */
229
/* returns total disk space of drive drv (in MiB, max 2048), or -1 if drive invalid */
235
static int disksize(int drv) {
230
static int disksize(int drv) {
236
  long res;
231
  long res;
237
  union REGS r;
232
  union REGS r;
238
  r.h.ah = 0x36; /* DOS 2+ get free disk space */
233
  r.h.ah = 0x36; /* DOS 2+ get free disk space */
239
  r.h.dl = drv;
234
  r.h.dl = drv;
240
  int86(0x21, &r, &r);
235
  int86(0x21, &r, &r);
241
  if (r.x.ax == 0xffffu) return(-1); /* AX set to FFFFh if drive invalid */
236
  if (r.x.ax == 0xffffu) return(-1); /* AX set to FFFFh if drive invalid */
242
  res = r.x.ax;  /* sectors per cluster */
237
  res = r.x.ax;  /* sectors per cluster */
243
  res *= r.x.dx; /* dx contains total clusters, bx contains free clusters */
238
  res *= r.x.dx; /* dx contains total clusters, bx contains free clusters */
244
  res *= r.x.cx; /* bytes per sector */
239
  res *= r.x.cx; /* bytes per sector */
245
  res >>= 20;    /* convert bytes to MiB */
240
  res >>= 20;    /* convert bytes to MiB */
246
  return(res);
241
  return(res);
247
}
242
}
248
 
243
 
249
 
244
 
250
/* returns 0 if disk is empty, non-zero otherwise */
245
/* returns 0 if disk is empty, non-zero otherwise */
251
static int diskempty(int drv) {
246
static int diskempty(int drv) {
252
  unsigned int rc;
247
  unsigned int rc;
253
  int res;
248
  int res;
254
  char buff[8];
249
  char buff[8];
255
  struct find_t fileinfo;
250
  struct find_t fileinfo;
256
  snprintf(buff, sizeof(buff), "%c:\\*.*", 'A' + drv - 1);
251
  snprintf(buff, sizeof(buff), "%c:\\*.*", 'A' + drv - 1);
257
  rc = _dos_findfirst(buff, _A_NORMAL | _A_SUBDIR | _A_HIDDEN | _A_SYSTEM, &fileinfo);
252
  rc = _dos_findfirst(buff, _A_NORMAL | _A_SUBDIR | _A_HIDDEN | _A_SYSTEM, &fileinfo);
258
  if (rc == 0) {
253
  if (rc == 0) {
259
    res = 1; /* call successfull means disk is not empty */
254
    res = 1; /* call successfull means disk is not empty */
260
  } else {
255
  } else {
261
    res = 0;
256
    res = 0;
262
  }
257
  }
263
  /* _dos_findclose(&fileinfo); */ /* apparently required only on OS/2 */
258
  /* _dos_findclose(&fileinfo); */ /* apparently required only on OS/2 */
264
  return(res);
259
  return(res);
265
}
260
}
266
 
261
 
267
 
262
 
268
static int preparedrive(void) {
263
static int preparedrive(void) {
269
  int driveremovable;
264
  int driveremovable;
270
  int selecteddrive = 3; /* hardcoded to 'C:' for now */
265
  int selecteddrive = 3; /* hardcoded to 'C:' for now */
271
  int cselecteddrive;
266
  int cselecteddrive;
272
  int ds;
267
  int ds;
273
  char buff[1024];
268
  char buff[1024];
274
  cselecteddrive = 'A' + selecteddrive - 1;
269
  cselecteddrive = 'A' + selecteddrive - 1;
275
  for (;;) {
270
  for (;;) {
276
    newscreen();
271
    newscreen();
277
    driveremovable = isdriveremovable(selecteddrive);
272
    driveremovable = isdriveremovable(selecteddrive);
278
    if (driveremovable < 0) {
273
    if (driveremovable < 0) {
279
      char *list[] = { "Create a partition automatically", "Run the FDISK partitioning tool", "Quit to DOS", NULL};
274
      char *list[] = { "Create a partition automatically", "Run the FDISK partitioning tool", "Quit to DOS", NULL};
280
      list[0] = kittengets(0, 3, list[0]);
275
      list[0] = kittengets(0, 3, list[0]);
281
      list[1] = kittengets(0, 4, list[1]);
276
      list[1] = kittengets(0, 4, list[1]);
282
      list[2] = kittengets(0, 2, list[2]);
277
      list[2] = kittengets(0, 2, list[2]);
283
      snprintf(buff, sizeof(buff), kittengets(3, 0, "ERROR: Drive %c: could not be found. Perhaps your hard disk needs to be partitioned first. Please create at least one partition on your hard disk, so Svarog386 can be installed on it. Note, that Svarog386 requires at least %d MiB of available disk space.\n\nYou can use the FDISK partitioning tool for creating the required partition manually, or you can let the installer partitioning your disk automatically. You can also abort the installation to use any other partition manager of your choice."), cselecteddrive, SVAROG_DISK_REQ);
278
      snprintf(buff, sizeof(buff), kittengets(3, 0, "ERROR: Drive %c: could not be found. Perhaps your hard disk needs to be partitioned first. Please create at least one partition on your hard disk, so Svarog386 can be installed on it. Note, that Svarog386 requires at least %d MiB of available disk space.\n\nYou can use the FDISK partitioning tool for creating the required partition manually, or you can let the installer partitioning your disk automatically. You can also abort the installation to use any other partition manager of your choice."), cselecteddrive, SVAROG_DISK_REQ);
284
      putstringwrap(4, 1, COLOR_BODY[mono], buff);
279
      putstringwrap(4, 1, COLOR_BODY[mono], buff);
285
      switch (menuselect(14, -1, 5, list)) {
280
      switch (menuselect(14, -1, 5, list)) {
286
        case 0:
281
        case 0:
287
          system("FDISK /AUTO");
282
          system("FDISK /AUTO");
288
          break;
283
          break;
289
        case 1:
284
        case 1:
290
          video_clear(0x0700, 0);
285
          video_clear(0x0700, 0);
291
          video_movecursor(0, 0);
286
          video_movecursor(0, 0);
292
          system("FDISK");
287
          system("FDISK");
293
          break;
288
          break;
294
        default:
289
        default:
295
          return(-1);
290
          return(-1);
296
      }
291
      }
297
      newscreen();
292
      newscreen();
298
      putstringnls(10, 10, COLOR_BODY[mono], 3, 1, "Your computer will reboot now.");
293
      putstringnls(10, 10, COLOR_BODY[mono], 3, 1, "Your computer will reboot now.");
299
      putstringnls(12, 10, COLOR_BODY[mono], 0, 5, "Press any key...");
294
      putstringnls(12, 10, COLOR_BODY[mono], 0, 5, "Press any key...");
300
      input_getkey();
295
      input_getkey();
301
      reboot();
296
      reboot();
302
      return(-1);
297
      return(-1);
303
    } else if (driveremovable > 0) {
298
    } else if (driveremovable > 0) {
304
      snprintf(buff, sizeof(buff), kittengets(3, 2, "ERROR: Drive %c: is a removable device. Installation aborted."), cselecteddrive);
299
      snprintf(buff, sizeof(buff), kittengets(3, 2, "ERROR: Drive %c: is a removable device. Installation aborted."), cselecteddrive);
305
      video_putstring(9, 1, COLOR_BODY[mono], buff, -1);
300
      video_putstring(9, 1, COLOR_BODY[mono], buff, -1);
306
      putstringnls(11, 2, COLOR_BODY[mono], 0, 5, "Press any key...");
301
      putstringnls(11, 2, COLOR_BODY[mono], 0, 5, "Press any key...");
307
      return(-1);
302
      return(-1);
308
    }
303
    }
309
    /* if not formatted, propose to format it right away (try to create a directory) */
304
    /* if not formatted, propose to format it right away (try to create a directory) */
310
    snprintf(buff, sizeof(buff), "%c:\\SVWRTEST.123", cselecteddrive);
305
    snprintf(buff, sizeof(buff), "%c:\\SVWRTEST.123", cselecteddrive);
311
    if (mkdir(buff) == 0) {
306
    if (mkdir(buff) == 0) {
312
      rmdir(buff);
307
      rmdir(buff);
313
    } else {
308
    } else {
314
      char *list[] = { "Proceed with formatting", "Quit to DOS", NULL};
309
      char *list[] = { "Proceed with formatting", "Quit to DOS", NULL};
315
      list[0] = kittengets(0, 6, list[0]);
310
      list[0] = kittengets(0, 6, list[0]);
316
      list[1] = kittengets(0, 2, list[1]);
311
      list[1] = kittengets(0, 2, list[1]);
317
      snprintf(buff, sizeof(buff), kittengets(3, 3, "ERROR: Drive %c: seems to be unformated. Do you wish to format it?"), cselecteddrive);
312
      snprintf(buff, sizeof(buff), kittengets(3, 3, "ERROR: Drive %c: seems to be unformated. Do you wish to format it?"), cselecteddrive);
318
      video_putstring(7, 1, COLOR_BODY[mono], buff, -1);
313
      video_putstring(7, 1, COLOR_BODY[mono], buff, -1);
319
      if (menuselect(12, -1, 4, list) != 0) return(-1);
314
      if (menuselect(12, -1, 4, list) != 0) return(-1);
320
      video_clear(0x0700, 0);
315
      video_clear(0x0700, 0);
321
      video_movecursor(0, 0);
316
      video_movecursor(0, 0);
322
      snprintf(buff, sizeof(buff), "FORMAT %c: /Q /U /Z:seriously /V:SVAROG386", cselecteddrive);
317
      snprintf(buff, sizeof(buff), "FORMAT %c: /Q /U /Z:seriously /V:SVAROG386", cselecteddrive);
323
      system(buff);
318
      system(buff);
324
      continue;
319
      continue;
325
    }
320
    }
326
    /* check total disk space */
321
    /* check total disk space */
327
    ds = disksize(selecteddrive);
322
    ds = disksize(selecteddrive);
328
    if (ds < SVAROG_DISK_REQ) {
323
    if (ds < SVAROG_DISK_REQ) {
329
      int y = 9;
324
      int y = 9;
330
      snprintf(buff, sizeof(buff), kittengets(3, 4, "ERROR: Drive %c: is not big enough! Svarog386 requires a disk of at least %d MiB."), cselecteddrive);
325
      snprintf(buff, sizeof(buff), kittengets(3, 4, "ERROR: Drive %c: is not big enough! Svarog386 requires a disk of at least %d MiB."), cselecteddrive);
331
      y += putstringwrap(y, 1, COLOR_BODY[mono], buff);
326
      y += putstringwrap(y, 1, COLOR_BODY[mono], buff);
332
      putstringnls(++y, 2, COLOR_BODY[mono], 0, 5, "Press any key...");
327
      putstringnls(++y, 2, COLOR_BODY[mono], 0, 5, "Press any key...");
333
      input_getkey();
328
      input_getkey();
334
      return(-1);
329
      return(-1);
335
    }
330
    }
336
    /* is the disk empty? */
331
    /* is the disk empty? */
337
    if (diskempty(selecteddrive) != 0) {
332
    if (diskempty(selecteddrive) != 0) {
338
      char *list[] = { "Proceed with formatting", "Quit to DOS", NULL};
333
      char *list[] = { "Proceed with formatting", "Quit to DOS", NULL};
-
 
334
      int y = 6;
339
      list[0] = kittengets(0, 6, list[0]);
335
      list[0] = kittengets(0, 6, list[0]);
340
      list[1] = kittengets(0, 2, list[1]);
336
      list[1] = kittengets(0, 2, list[1]);
341
      snprintf(buff, sizeof(buff), kittengets(3, 5, "ERROR: Drive %c: is not empty. Svarog386 must be installed on an empty disk.\n\nYou can format the disk now, to make it empty. Note however, that this will ERASE ALL CURRENT DATA on your disk."), cselecteddrive);
337
      snprintf(buff, sizeof(buff), kittengets(3, 5, "ERROR: Drive %c: is not empty. Svarog386 must be installed on an empty disk.\n\nYou can format the disk now, to make it empty. Note however, that this will ERASE ALL CURRENT DATA on your disk."), cselecteddrive);
342
      putstringwrap(7, 1, COLOR_BODY[mono], buff);
338
      y += putstringwrap(y, 1, COLOR_BODY[mono], buff);
343
      if (menuselect(12, -1, 4, list) != 0) return(-1);
339
      if (menuselect(++y, -1, 4, list) != 0) return(-1);
344
      video_clear(0x0700, 0);
340
      video_clear(0x0700, 0);
345
      video_movecursor(0, 0);
341
      video_movecursor(0, 0);
346
      snprintf(buff, sizeof(buff), "FORMAT %c: /Q /U /Z:seriously /V:SVAROG386", cselecteddrive);
342
      snprintf(buff, sizeof(buff), "FORMAT %c: /Q /U /Z:seriously /V:SVAROG386", cselecteddrive);
347
      system(buff);
343
      system(buff);
348
      continue;
344
      continue;
349
    } else {
345
    } else {
350
      /* final confirmation */
346
      /* final confirmation */
351
      char *list[] = { "Install Svarog386", "Quit to DOS", NULL};
347
      char *list[] = { "Install Svarog386", "Quit to DOS", NULL};
352
      list[0] = kittengets(0, 1, list[0]);
348
      list[0] = kittengets(0, 1, list[0]);
353
      list[1] = kittengets(0, 2, list[1]);
349
      list[1] = kittengets(0, 2, list[1]);
354
      snprintf(buff, sizeof(buff), kittengets(3, 6, "The installation of Svarog386 to %c: is about to begin."), cselecteddrive);
350
      snprintf(buff, sizeof(buff), kittengets(3, 6, "The installation of Svarog386 to %c: is about to begin."), cselecteddrive);
355
      video_putstring(7, -1, COLOR_BODY[mono], buff, -1);
351
      video_putstring(7, -1, COLOR_BODY[mono], buff, -1);
356
      if (menuselect(10, -1, 4, list) != 0) return(-1);
352
      if (menuselect(10, -1, 4, list) != 0) return(-1);
357
      snprintf(buff, sizeof(buff), "SYS A: %c: > NUL", cselecteddrive);
353
      snprintf(buff, sizeof(buff), "SYS A: %c: > NUL", cselecteddrive);
358
      system(buff);
354
      system(buff);
359
      snprintf(buff, sizeof(buff), "%c:\\TEMP", cselecteddrive);
355
      snprintf(buff, sizeof(buff), "%c:\\TEMP", cselecteddrive);
360
      mkdir(buff);
356
      mkdir(buff);
361
      return(cselecteddrive);
357
      return(cselecteddrive);
362
    }
358
    }
363
  }
359
  }
364
}
360
}
365
 
361
 
366
 
362
 
367
/* copy file src into dst, substituting all characters c1 by c2 */
363
/* copy file src into dst, substituting all characters c1 by c2 */
368
static void fcopysub(char *dst, char *src, char c1, char c2) {
364
static void fcopysub(char *dst, char *src, char c1, char c2) {
369
  FILE *fdd, *fds;
365
  FILE *fdd, *fds;
370
  int buff;
366
  int buff;
371
  fds = fopen(src, "rb");
367
  fds = fopen(src, "rb");
372
  if (fds == NULL) return;
368
  if (fds == NULL) return;
373
  fdd = fopen(dst, "wb");
369
  fdd = fopen(dst, "wb");
374
  if (fdd == NULL) {
370
  if (fdd == NULL) {
375
    fclose(fds);
371
    fclose(fds);
376
    return;
372
    return;
377
  }
373
  }
378
  /* */
374
  /* */
379
  for (;;) {
375
  for (;;) {
380
    buff = fgetc(fds);
376
    buff = fgetc(fds);
381
    if (buff == EOF) break;
377
    if (buff == EOF) break;
382
    if (buff == c1) buff = c2;
378
    if (buff == c1) buff = c2;
383
    fprintf(fdd, "%c", buff);
379
    fprintf(fdd, "%c", buff);
384
  }
380
  }
385
  /* close files and return */
381
  /* close files and return */
386
  fclose(fdd);
382
  fclose(fdd);
387
  fclose(fds);
383
  fclose(fds);
388
}
384
}
389
 
385
 
390
 
386
 
391
static void bootfilesgen(int targetdrv, char *lang, int cdromdrv) {
387
static void bootfilesgen(int targetdrv, char *lang, int cdromdrv) {
392
  char buff[128];
388
  char buff[128];
393
  int cp, egafile;
389
  int cp, egafile;
394
  FILE *fd;
390
  FILE *fd;
395
  cp = getnlscp(lang, &egafile);
391
  cp = getnlscp(lang, &egafile);
396
  /*** CONFIG.SYS ***/
392
  /*** CONFIG.SYS ***/
397
  snprintf(buff, sizeof(buff), "%c:\\CONFIG.SYS", targetdrv);
393
  snprintf(buff, sizeof(buff), "%c:\\CONFIG.SYS", targetdrv);
398
  fd = fopen(buff, "wb");
394
  fd = fopen(buff, "wb");
399
  if (fd == NULL) return;
395
  if (fd == NULL) return;
400
  fprintf(fd, "DOS=UMB,HIGH\r\n");
396
  fprintf(fd, "DOS=UMB,HIGH\r\n");
401
  fprintf(fd, "FILES=50\r\n");
397
  fprintf(fd, "FILES=50\r\n");
402
  fprintf(fd, "DEVICE=%c:\\SYSTEM\\SVAROG.386\\BIN\\HIMEMX.EXE\r\n", targetdrv);
398
  fprintf(fd, "DEVICE=%c:\\SYSTEM\\SVAROG.386\\BIN\\HIMEMX.EXE\r\n", targetdrv);
403
  fprintf(fd, "SHELLHIGH=%c:\\SYSTEM\\SVAROG.386\\BIN\\COMMAND.COM /E:512 /P\r\n", targetdrv);
399
  fprintf(fd, "SHELLHIGH=%c:\\SYSTEM\\SVAROG.386\\BIN\\COMMAND.COM /E:512 /P\r\n", targetdrv);
404
  fprintf(fd, "REM COUNTRY=001,437,%c:\\SYSTEM\\CONF\\COUNTRY.SYS\r\n", targetdrv);
400
  fprintf(fd, "REM COUNTRY=001,437,%c:\\SYSTEM\\CONF\\COUNTRY.SYS\r\n", targetdrv);
405
  fprintf(fd, "DEVICE=%c:\\SYSTEM\\DRIVERS\\UDVD2\\UDVD2.SYS /D:SVCD0001 /H\r\n", targetdrv);
401
  fprintf(fd, "DEVICE=%c:\\SYSTEM\\DRIVERS\\UDVD2\\UDVD2.SYS /D:SVCD0001 /H\r\n", targetdrv);
406
  fclose(fd);
402
  fclose(fd);
407
  /*** AUTOEXEC.BAT ***/
403
  /*** AUTOEXEC.BAT ***/
408
  snprintf(buff, sizeof(buff), "%c:\\AUTOEXEC.BAT", targetdrv);
404
  snprintf(buff, sizeof(buff), "%c:\\AUTOEXEC.BAT", targetdrv);
409
  fd = fopen(buff, "wb");
405
  fd = fopen(buff, "wb");
410
  if (fd == NULL) return;
406
  if (fd == NULL) return;
411
  fprintf(fd, "@ECHO OFF\r\n");
407
  fprintf(fd, "@ECHO OFF\r\n");
412
  fprintf(fd, "SET TEMP=%c:\\TEMP\r\n", targetdrv);
408
  fprintf(fd, "SET TEMP=%c:\\TEMP\r\n", targetdrv);
413
  fprintf(fd, "SET DOSDIR=%c:\\SYSTEM\\SVAROG.386\r\n", targetdrv);
409
  fprintf(fd, "SET DOSDIR=%c:\\SYSTEM\\SVAROG.386\r\n", targetdrv);
414
  fprintf(fd, "SET NLSPATH=%%DOSDIR%%\\NLS\r\n");
410
  fprintf(fd, "SET NLSPATH=%%DOSDIR%%\\NLS\r\n");
415
  fprintf(fd, "SET LANG=%s\r\n", lang);
411
  fprintf(fd, "SET LANG=%s\r\n", lang);
416
  fprintf(fd, "SET DIRCMD=/OGNE/P/4\r\n");
412
  fprintf(fd, "SET DIRCMD=/OGNE/P/4\r\n");
417
  fprintf(fd, "SET FDNPKG.CFG=%c:\\SYSTEM\\CFG\\FDNPKG.CFG\r\n", targetdrv);
413
  fprintf(fd, "SET FDNPKG.CFG=%c:\\SYSTEM\\CFG\\FDNPKG.CFG\r\n", targetdrv);
418
  fprintf(fd, "SET WATTCP.CFG=%c:\\SYSTEM\\CFG\\WATTCP.CFG\r\n", targetdrv);
414
  fprintf(fd, "SET WATTCP.CFG=%c:\\SYSTEM\\CFG\\WATTCP.CFG\r\n", targetdrv);
419
  fprintf(fd, "PATH %%DOSDIR%%\\BIN;%c:\\SYSTEM\\LINKS\r\n", targetdrv);
415
  fprintf(fd, "PATH %%DOSDIR%%\\BIN;%c:\\SYSTEM\\LINKS\r\n", targetdrv);
420
  fprintf(fd, "PROMPT $P$G\r\n");
416
  fprintf(fd, "PROMPT $P$G\r\n");
421
  fprintf(fd, "ALIAS REBOOT=FDAPM COLDBOOT\r\n");
417
  fprintf(fd, "ALIAS REBOOT=FDAPM COLDBOOT\r\n");
422
  fprintf(fd, "ALIAS HALT=FDAPM POWEROFF\r\n");
418
  fprintf(fd, "ALIAS HALT=FDAPM POWEROFF\r\n");
423
  fprintf(fd, "FDAPM APMDOS\r\n");
419
  fprintf(fd, "FDAPM APMDOS\r\n");
424
  fprintf(fd, "\r\n");
420
  fprintf(fd, "\r\n");
425
  if (egafile > 0) {
421
  if (egafile > 0) {
426
    fprintf(fd, "DISPLAY CON=(EGA,,1)\r\n");
422
    fprintf(fd, "DISPLAY CON=(EGA,,1)\r\n");
427
    if (egafile == 1) {
423
    if (egafile == 1) {
428
      fprintf(fd, "MODE CON CP PREPARE=((%d) %c:\\SYSTEM\\SVAROG.386\\CPI\\EGA.CPX)\r\n", cp, targetdrv);
424
      fprintf(fd, "MODE CON CP PREPARE=((%d) %c:\\SYSTEM\\SVAROG.386\\CPI\\EGA.CPX)\r\n", cp, targetdrv);
429
    } else {
425
    } else {
430
      fprintf(fd, "MODE CON CP PREPARE=((%d) %c:\\SYSTEM\\SVAROG.386\\CPI\\EGA%d.CPX)\r\n", cp, targetdrv, egafile);
426
      fprintf(fd, "MODE CON CP PREPARE=((%d) %c:\\SYSTEM\\SVAROG.386\\CPI\\EGA%d.CPX)\r\n", cp, targetdrv, egafile);
431
    }
427
    }
432
    fprintf(fd, "MODE CON CP SELECT=%d\r\n", cp);
428
    fprintf(fd, "MODE CON CP SELECT=%d\r\n", cp);
433
    fprintf(fd, "\r\n");
429
    fprintf(fd, "\r\n");
434
  }
430
  }
435
  fprintf(fd, "SHSUCDX /d:SVCD0001\r\n");
431
  fprintf(fd, "SHSUCDX /d:SVCD0001\r\n");
436
  fprintf(fd, "\r\n");
432
  fprintf(fd, "\r\n");
437
  fprintf(fd, "REM Uncomment the line below for automatic mouse support\r\n");
433
  fprintf(fd, "REM Uncomment the line below for automatic mouse support\r\n");
438
  fprintf(fd, "REM CTMOUSE\r\n");
434
  fprintf(fd, "REM CTMOUSE\r\n");
439
  fprintf(fd, "\r\n");
435
  fprintf(fd, "\r\n");
440
  fprintf(fd, "ECHO.\r\n");
436
  fprintf(fd, "ECHO.\r\n");
441
  fprintf(fd, "ECHO Welcome to Svarog386! Type 'HELP' if you need help.\r\n");
437
  fprintf(fd, "ECHO Welcome to Svarog386! Type 'HELP' if you need help.\r\n");
442
  fclose(fd);
438
  fclose(fd);
443
  /*** CREATE DIRECTORY FOR OTHER CONFIGURATION FILES ***/
439
  /*** CREATE DIRECTORY FOR OTHER CONFIGURATION FILES ***/
444
  snprintf(buff, sizeof(buff), "%c:\\SYSTEM\\CFG", targetdrv);
440
  snprintf(buff, sizeof(buff), "%c:\\SYSTEM\\CFG", targetdrv);
445
  mkdir(buff);
441
  mkdir(buff);
446
  /*** FDNPKG.CFG ***/
442
  /*** FDNPKG.CFG ***/
447
  snprintf(buff, sizeof(buff), "%c:\\SYSTEM\\CFG\\FDNPKG.CFG", targetdrv);
443
  snprintf(buff, sizeof(buff), "%c:\\SYSTEM\\CFG\\FDNPKG.CFG", targetdrv);
448
  fcopysub(buff, "A:\\DAT\\FDNPKG.CFG", '$', cdromdrv);
444
  fcopysub(buff, "A:\\DAT\\FDNPKG.CFG", '$', cdromdrv);
449
  /*** COUNTRY.SYS ***/
445
  /*** COUNTRY.SYS ***/
450
  /*** PICOTCP ***/
446
  /*** PICOTCP ***/
451
  /*** WATTCP ***/
447
  /*** WATTCP ***/
452
}
448
}
453
 
449
 
454
 
450
 
455
static void installpackages(int targetdrv, int cdromdrv) {
451
static void installpackages(int targetdrv, int cdromdrv) {
456
  char *pkglist[] = {
452
  char *pkglist[] = {
457
    "A:\\UDVD2", /* this one's not part of CORE, hence it's stored right on the floppy */
453
    "A:\\UDVD2", /* this one's not part of CORE, hence it's stored right on the floppy */
458
    "APPEND",
454
    "APPEND",
459
    "ASSIGN",
455
    "ASSIGN",
460
    "ATTRIB",
456
    "ATTRIB",
461
    "CHKDSK",
457
    "CHKDSK",
462
    "CHOICE",
458
    "CHOICE",
463
    "COMMAND",
459
    "COMMAND",
464
    "COMP",
460
    "COMP",
465
    "CPIDOS",
461
    "CPIDOS",
466
    "CTMOUSE",
462
    "CTMOUSE",
467
    "DEBUG",
463
    "DEBUG",
468
    "DEFRAG",
464
    "DEFRAG",
469
    "DELTREE",
465
    "DELTREE",
470
    "DEVLOAD",
466
    "DEVLOAD",
471
    "DISKCOMP",
467
    "DISKCOMP",
472
    "DISKCOPY",
468
    "DISKCOPY",
473
    "DISPLAY",
469
    "DISPLAY",
474
    "DOSFSCK",
470
    "DOSFSCK",
475
    "EDIT",
471
    "EDIT",
476
    "EDLIN",
472
    "EDLIN",
477
    "EXE2BIN",
473
    "EXE2BIN",
478
    "FC",
474
    "FC",
479
    "FDAPM",
475
    "FDAPM",
480
    "FDISK",
476
    "FDISK",
481
    "FDNPKG",
477
    "FDNPKG",
482
    "FIND",
478
    "FIND",
483
    "FORMAT",
479
    "FORMAT",
484
    "HELP",
480
    "HELP",
485
    "HIMEMX",
481
    "HIMEMX",
486
    "KERNEL",
482
    "KERNEL",
487
    "KEYB",
483
    "KEYB",
-
 
484
    "KEYB_LAY",
488
    "LABEL",
485
    "LABEL",
489
    "LBACACHE",
486
    "LBACACHE",
490
    "MEM",
487
    "MEM",
491
    "MIRROR",
488
    "MIRROR",
492
    "MODE",
489
    "MODE",
493
    "MORE",
490
    "MORE",
494
    "MOVE",
491
    "MOVE",
495
    "NANSI",
492
    "NANSI",
496
    "NLSFUNC",
493
    "NLSFUNC",
497
    "PRINT",
494
    "PRINT",
498
    "RDISK",
495
    "RDISK",
499
    "RECOVER",
496
    "RECOVER",
500
    "REPLACE",
497
    "REPLACE",
501
    "SHARE",
498
    "SHARE",
502
    "SHSUCDX",
499
    "SHSUCDX",
503
    "SORT",
500
    "SORT",
504
    "SWSUBST",
501
    "SWSUBST",
505
    "TREE",
502
    "TREE",
506
    "UNDELETE",
503
    "UNDELETE",
507
    "XCOPY",
504
    "XCOPY",
508
    NULL
505
    NULL
509
  };
506
  };
510
  int i, pkglistlen;
507
  int i, pkglistlen;
511
  char buff[64];
508
  char buff[64];
512
  newscreen();
509
  newscreen();
513
  /* count how long the pkg list is */
510
  /* count how long the pkg list is */
514
  for (pkglistlen = 0; pkglist[pkglistlen] != NULL; pkglistlen++);
511
  for (pkglistlen = 0; pkglist[pkglistlen] != NULL; pkglistlen++);
515
  /* set DOSDIR and friends */
512
  /* set DOSDIR and friends */
516
  snprintf(buff, sizeof(buff), "%c:\\SYSTEM\\SVAROG.386", targetdrv);
513
  snprintf(buff, sizeof(buff), "%c:\\SYSTEM\\SVAROG.386", targetdrv);
517
  setenv("DOSDIR", buff, 1);
514
  setenv("DOSDIR", buff, 1);
518
  snprintf(buff, sizeof(buff), "%c:\\TEMP", targetdrv);
515
  snprintf(buff, sizeof(buff), "%c:\\TEMP", targetdrv);
519
  setenv("TEMP", buff, 1);
516
  setenv("TEMP", buff, 1);
520
  /* install packages */
517
  /* install packages */
521
  for (i = 0; pkglist[i] != NULL; i++) {
518
  for (i = 0; pkglist[i] != NULL; i++) {
522
    char buff[128];
519
    char buff[128];
523
    snprintf(buff, sizeof(buff), kittengets(4, 0, "Installing package %d/%d: %s"), i+1, pkglistlen, pkglist[i]);
520
    snprintf(buff, sizeof(buff), kittengets(4, 0, "Installing package %d/%d: %s"), i+1, pkglistlen, pkglist[i]);
524
    strcat(buff, "       ");
521
    strcat(buff, "       ");
525
    video_putstring(10, 1, COLOR_BODY[mono], buff, -1);
522
    video_putstring(10, 1, COLOR_BODY[mono], buff, -1);
526
    if (pkglist[i][1] == ':') {
523
    if (pkglist[i][1] == ':') {
527
      snprintf(buff, sizeof(buff), "FDINST INSTALL %s.ZIP > NUL", pkglist[i]);
524
      snprintf(buff, sizeof(buff), "FDINST INSTALL %s.ZIP > NUL", pkglist[i]);
528
    } else {
525
    } else {
529
      snprintf(buff, sizeof(buff), "FDINST INSTALL %c:\\CORE\\%s.ZIP > NUL", cdromdrv, pkglist[i]);
526
      snprintf(buff, sizeof(buff), "FDINST INSTALL %c:\\CORE\\%s.ZIP > NUL", cdromdrv, pkglist[i]);
530
    }
527
    }
531
    system(buff);
528
    system(buff);
532
  }
529
  }
533
}
530
}
534
 
531
 
535
 
532
 
536
static void finalreboot(void) {
533
static void finalreboot(void) {
537
  int y = 9;
534
  int y = 9;
538
  newscreen();
535
  newscreen();
539
  y += putstringnls(y, 2, COLOR_BODY[mono], 5, 0, "Svarog386 installation is over. Your computer will reboot now.\nPlease remove the installation disk from your drive.");
536
  y += putstringnls(y, 2, COLOR_BODY[mono], 5, 0, "Svarog386 installation is over. Your computer will reboot now.\nPlease remove the installation disk from your drive.");
540
  putstringnls(++y, 1, COLOR_BODY[mono], 0, 5, "Press any key...");
537
  putstringnls(++y, 1, COLOR_BODY[mono], 0, 5, "Press any key...");
541
  input_getkey();
538
  input_getkey();
542
  reboot();
539
  reboot();
543
}
540
}
544
 
541
 
545
 
542
 
546
static void loadcp(char *lang) {
543
static void loadcp(char *lang) {
547
  int cp, egafile;
544
  int cp, egafile;
548
  char buff[64];
545
  char buff[64];
549
  cp = getnlscp(lang, &egafile);
546
  cp = getnlscp(lang, &egafile);
550
  if (cp == 437) return;
547
  if (cp == 437) return;
551
  video_movecursor(1, 0);
548
  video_movecursor(1, 0);
552
  if (egafile == 1) {
549
  if (egafile == 1) {
553
    snprintf(buff, sizeof(buff), "MODE CON CP PREP=((%d) A:\\EGA.CPX) > NUL", cp);
550
    snprintf(buff, sizeof(buff), "MODE CON CP PREP=((%d) A:\\EGA.CPX) > NUL", cp);
554
  } else {
551
  } else {
555
    snprintf(buff, sizeof(buff), "MODE CON CP PREP=((%d) A:\\EGA%d.CPX) > NUL", cp, egafile);
552
    snprintf(buff, sizeof(buff), "MODE CON CP PREP=((%d) A:\\EGA%d.CPX) > NUL", cp, egafile);
556
  }
553
  }
557
  system(buff);
554
  system(buff);
558
  snprintf(buff, sizeof(buff), "MODE CON CP SEL=%d > NUL", cp);
555
  snprintf(buff, sizeof(buff), "MODE CON CP SEL=%d > NUL", cp);
559
  system(buff);
556
  system(buff);
560
  /* below I re-init the video controller - apparently this is required if
557
  /* below I re-init the video controller - apparently this is required if
561
   * I want the new glyph symbols to be actually applied */
558
   * I want the new glyph symbols to be actually applied, at least some
-
 
559
   * (broken?) BIOSes, like VBox, apply glyphs only at next video mode change */
562
  {
560
  {
563
  union REGS r;
561
  union REGS r;
564
  r.h.ah = 0x0F; /* get current video mode */
562
  r.h.ah = 0x0F; /* get current video mode */
565
  int86(0x10, &r, &r); /* r.h.al contains the current video mode now */
563
  int86(0x10, &r, &r); /* r.h.al contains the current video mode now */
566
  r.h.al |= 128; /* set the high bit of AL to instruct BIOS not to flush VRAM's content (EGA+) */
564
  r.h.al |= 128; /* set the high bit of AL to instruct BIOS not to flush VRAM's content (EGA+) */
567
  r.h.ah = 0; /* re-set video mode (to whatever is set in AL) */
565
  r.h.ah = 0; /* re-set video mode (to whatever is set in AL) */
568
  int86(0x10, &r, &r);
566
  int86(0x10, &r, &r);
569
  }
567
  }
570
}
568
}
571
 
569
 
572
 
570
 
-
 
571
/* checks CD drive drv for the presence of the Svarog386 install CD
-
 
572
 * returns 0 if found, non-zero otherwise */
-
 
573
static int checkcd(char drv) {
-
 
574
  FILE *fd;
-
 
575
  char fname[32];
-
 
576
  snprintf(fname, sizeof(fname), "%c:\\CORE\\MEM.ZIP", drv);
-
 
577
  fd = fopen(fname, "rb");
-
 
578
  if (fd == NULL) return(-1);
-
 
579
  fclose(fd);
-
 
580
  return(0);
-
 
581
}
-
 
582
 
-
 
583
 
573
int main(void) {
584
int main(void) {
574
  char lang[4];
585
  char lang[4];
575
  int targetdrv;
586
  int targetdrv;
576
  int cdromdrv;
587
  int cdromdrv;
577
 
588
 
578
  /* find where the cdrom drive is */
589
  /* find where the cdrom drive is */
579
  cdromdrv = cdrom_findfirst();
590
  cdromdrv = cdrom_findfirst();
580
  if (cdromdrv < 0) {
591
  if (cdromdrv < 0) {
581
    printf("ERROR: CD-ROM DRIVE NOT FOUND\r\n");
592
    printf("ERROR: CD-ROM DRIVE NOT FOUND\r\n");
582
    return(1);
593
    return(1);
583
  }
594
  }
584
  cdromdrv += 'A'; /* convert the cdrom 'id' (A=0) to an actual drive letter */
595
  cdromdrv += 'A'; /* convert the cdrom 'id' (A=0) to an actual drive letter */
-
 
596
  if (checkcd(cdromdrv) != 0) {
-
 
597
    printf("ERROR: SVAROG386 INSTALLATION CD NOT FOUND IN THE DRIVE.\r\n");
-
 
598
    return(1);
-
 
599
  }
585
 
600
 
586
  /* init screen and detect mono status */
601
  /* init screen and detect mono status */
587
  mono = video_init();
602
  mono = video_init();
588
 
603
 
589
  for (;;) { /* fake loop, it's here just to break out easily */
604
  for (;;) { /* fake loop, it's here just to break out easily */
590
    kittenopen("INSTALL"); /* NLS support */
605
    kittenopen("INSTALL"); /* NLS support */
591
    if (selectlang(lang) < 0) break; /* welcome to svarog, select your language */
606
    if (selectlang(lang) < 0) break; /* welcome to svarog, select your language */
592
    setenv("LANG", lang, 1);
607
    setenv("LANG", lang, 1);
593
    loadcp(lang);
608
    loadcp(lang);
594
    kittenclose(); /* reload NLS with new language */
609
    kittenclose(); /* reload NLS with new language */
595
    kittenopen("INSTALL"); /* NLS support */
610
    kittenopen("INSTALL"); /* NLS support */
596
    /*selectkeyb();*/ /* what keyb layout should we use? */
611
    /*selectkeyb();*/ /* what keyb layout should we use? */
597
    if (welcomescreen() != 0) break; /* what svarog386 is, ask whether to run live dos or install */
612
    if (welcomescreen() != 0) break; /* what svarog386 is, ask whether to run live dos or install */
598
    targetdrv = preparedrive(); /* what drive should we install to? check avail. space */
613
    targetdrv = preparedrive(); /* what drive should we install to? check avail. space */
599
    if (targetdrv < 0) break;
614
    if (targetdrv < 0) break;
600
    /*askaboutsources();*/ /* IF sources are available, ask if installing with them */
615
    /*askaboutsources();*/ /* IF sources are available, ask if installing with them */
601
    installpackages(targetdrv, cdromdrv);    /* install packages */
616
    installpackages(targetdrv, cdromdrv);    /* install packages */
602
    bootfilesgen(targetdrv, lang, cdromdrv); /* generate boot files and other configurations */
617
    bootfilesgen(targetdrv, lang, cdromdrv); /* generate boot files and other configurations */
603
    /*localcfg();*/ /* show local params (currency, etc), and propose to change them (based on localcfg) */
618
    /*localcfg();*/ /* show local params (currency, etc), and propose to change them (based on localcfg) */
604
    /*netcfg();*/ /* basic networking config */
619
    /*netcfg();*/ /* basic networking config */
605
    finalreboot(); /* remove the CD and reboot */
620
    finalreboot(); /* remove the CD and reboot */
606
    break;
621
    break;
607
  }
622
  }
608
  kittenclose(); /* close NLS support */
623
  kittenclose(); /* close NLS support */
609
  video_clear(0x0700, 0);
624
  video_clear(0x0700, 0);
610
  video_movecursor(0, 0);
625
  video_movecursor(0, 0);
611
  return(0);
626
  return(0);
612
}
627
}
613
 
628