Subversion Repositories SvarDOS

Rev

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

Rev 56 Rev 57
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",
184
    "German\0DE",
185
    "Italian\0IT",
185
    "Italian\0IT",
186
    "Polish\0PL",
186
    "Polish\0PL",
187
    "Russian\0RU",
187
    "Russian\0RU",
188
    "Slovenian\0SL",
188
    "Slovenian\0SL",
189
    "Spanish\0ES",
189
    "Spanish\0ES",
190
    "Turkish\0TR",
190
    "Turkish\0TR",
191
    NULL
191
    NULL
192
  };
192
  };
193
 
193
 
194
  newscreen();
194
  newscreen();
195
  msg = kittengets(1, 0, "Welcome to Svarog386");
195
  msg = kittengets(1, 0, "Welcome to Svarog386");
196
  x = 40 - (strlen(msg) >> 1);
196
  x = 40 - (strlen(msg) >> 1);
197
  video_putstring(4, x, COLOR_BODY[mono], msg, -1);
197
  video_putstring(4, x, COLOR_BODY[mono], msg, -1);
198
  video_putcharmulti(5, x, COLOR_BODY[mono], '=', strlen(msg), 1);
198
  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:");
199
  putstringnls(8, -1, COLOR_BODY[mono], 1, 1, "Please select your language from the list below:");
200
  choice = menuselect(10, -1, 12, langlist);
200
  choice = menuselect(10, -1, 12, langlist);
201
  if (choice < 0) return(-1);
201
  if (choice < 0) return(-1);
202
  /* write short language code into lang */
202
  /* write short language code into lang */
203
  for (code = langlist[choice]; *code != 0; code++);
203
  for (code = langlist[choice]; *code != 0; code++);
204
  memcpy(lang, code + 1, 2);
204
  memcpy(lang, code + 1, 2);
205
  lang[2] = 0;
205
  lang[2] = 0;
206
  return(0);
206
  return(0);
207
}
207
}
208
 
208
 
209
 
209
 
210
/* returns 0 if installation must proceed, non-zero otherwise */
210
/* returns 0 if installation must proceed, non-zero otherwise */
211
static int welcomescreen(void) {
211
static int welcomescreen(void) {
212
  char *choice[] = {"Install Svarog386 to disk", "Quit to DOS", NULL};
212
  char *choice[] = {"Install Svarog386 to disk", "Quit to DOS", NULL};
213
  choice[0] = kittengets(0, 1, choice[0]);
213
  choice[0] = kittengets(0, 1, choice[0]);
214
  choice[1] = kittengets(0, 2, choice[1]);
214
  choice[1] = kittengets(0, 2, choice[1]);
215
  newscreen();
215
  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.");
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.");
217
  return(menuselect(13, -1, 4, choice));
217
  return(menuselect(13, -1, 4, choice));
218
}
218
}
219
 
219
 
220
 
220
 
221
/* returns 1 if drive is removable, 0 if not, -1 on error */
221
/* returns 1 if drive is removable, 0 if not, -1 on error */
222
static int isdriveremovable(int drv) {
222
static int isdriveremovable(int drv) {
223
  union REGS r;
223
  union REGS r;
224
  r.x.ax = 0x4408;
224
  r.x.ax = 0x4408;
225
  r.h.bl = drv;
225
  r.h.bl = drv;
226
  int86(0x21, &r, &r);
226
  int86(0x21, &r, &r);
227
  /* CF set on error, AX set to 0 if removable, 1 if fixed */
227
  /* CF set on error, AX set to 0 if removable, 1 if fixed */
228
  if (r.x.cflag != 0) return(-1);
228
  if (r.x.cflag != 0) return(-1);
229
  if (r.x.ax == 0) return(1);
229
  if (r.x.ax == 0) return(1);
230
  return(0);
230
  return(0);
231
}
231
}
232
 
232
 
233
 
233
 
234
/* returns total disk space of drive drv (in MiB, max 2048), or -1 if drive invalid */
234
/* returns total disk space of drive drv (in MiB, max 2048), or -1 if drive invalid */
235
static int disksize(int drv) {
235
static int disksize(int drv) {
236
  long res;
236
  long res;
237
  union REGS r;
237
  union REGS r;
238
  r.h.ah = 0x36; /* DOS 2+ get free disk space */
238
  r.h.ah = 0x36; /* DOS 2+ get free disk space */
239
  r.h.dl = drv;
239
  r.h.dl = drv;
240
  int86(0x21, &r, &r);
240
  int86(0x21, &r, &r);
241
  if (r.x.ax == 0xffffu) return(-1); /* AX set to FFFFh if drive invalid */
241
  if (r.x.ax == 0xffffu) return(-1); /* AX set to FFFFh if drive invalid */
242
  res = r.x.ax;  /* sectors per cluster */
242
  res = r.x.ax;  /* sectors per cluster */
243
  res *= r.x.dx; /* dx contains total clusters, bx contains free clusters */
243
  res *= r.x.dx; /* dx contains total clusters, bx contains free clusters */
244
  res *= r.x.cx; /* bytes per sector */
244
  res *= r.x.cx; /* bytes per sector */
245
  res >>= 20;    /* convert bytes to MiB */
245
  res >>= 20;    /* convert bytes to MiB */
246
  return(res);
246
  return(res);
247
}
247
}
248
 
248
 
249
 
249
 
250
/* returns 0 if disk is empty, non-zero otherwise */
250
/* returns 0 if disk is empty, non-zero otherwise */
251
static int diskempty(int drv) {
251
static int diskempty(int drv) {
252
  unsigned int rc;
252
  unsigned int rc;
253
  int res;
253
  int res;
254
  char buff[8];
254
  char buff[8];
255
  struct find_t fileinfo;
255
  struct find_t fileinfo;
256
  snprintf(buff, sizeof(buff), "%c:\\*.*", 'A' + drv - 1);
256
  snprintf(buff, sizeof(buff), "%c:\\*.*", 'A' + drv - 1);
257
  rc = _dos_findfirst(buff, _A_NORMAL | _A_SUBDIR | _A_HIDDEN | _A_SYSTEM, &fileinfo);
257
  rc = _dos_findfirst(buff, _A_NORMAL | _A_SUBDIR | _A_HIDDEN | _A_SYSTEM, &fileinfo);
258
  if (rc == 0) {
258
  if (rc == 0) {
259
    res = 1; /* call successfull means disk is not empty */
259
    res = 1; /* call successfull means disk is not empty */
260
  } else {
260
  } else {
261
    res = 0;
261
    res = 0;
262
  }
262
  }
263
  /* _dos_findclose(&fileinfo); */ /* apparently required only on OS/2 */
263
  /* _dos_findclose(&fileinfo); */ /* apparently required only on OS/2 */
264
  return(res);
264
  return(res);
265
}
265
}
266
 
266
 
267
 
267
 
268
static int preparedrive(void) {
268
static int preparedrive(void) {
269
  int driveremovable;
269
  int driveremovable;
270
  int selecteddrive = 3; /* hardcoded to 'C:' for now */
270
  int selecteddrive = 3; /* hardcoded to 'C:' for now */
271
  int cselecteddrive;
271
  int cselecteddrive;
272
  int ds;
272
  int ds;
273
  char buff[1024];
273
  char buff[1024];
274
  cselecteddrive = 'A' + selecteddrive - 1;
274
  cselecteddrive = 'A' + selecteddrive - 1;
275
  for (;;) {
275
  for (;;) {
276
    newscreen();
276
    newscreen();
277
    driveremovable = isdriveremovable(selecteddrive);
277
    driveremovable = isdriveremovable(selecteddrive);
278
    if (driveremovable < 0) {
278
    if (driveremovable < 0) {
279
      char *list[] = { "Create a partition automatically", "Run the FDISK partitioning tool", "Quit to DOS", NULL};
279
      char *list[] = { "Create a partition automatically", "Run the FDISK partitioning tool", "Quit to DOS", NULL};
280
      list[0] = kittengets(0, 3, list[0]);
280
      list[0] = kittengets(0, 3, list[0]);
281
      list[1] = kittengets(0, 4, list[1]);
281
      list[1] = kittengets(0, 4, list[1]);
282
      list[2] = kittengets(0, 2, list[2]);
282
      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);
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);
284
      video_putstring(4, 2, COLOR_BODY[mono], buff, -1);
284
      putstringwrap(4, 2, COLOR_BODY[mono], buff);
285
      switch (menuselect(14, -1, 5, list)) {
285
      switch (menuselect(14, -1, 5, list)) {
286
        case 0:
286
        case 0:
287
          system("FDISK /AUTO");
287
          system("FDISK /AUTO");
288
          break;
288
          break;
289
        case 1:
289
        case 1:
290
          video_clear(0x0700, 0);
290
          video_clear(0x0700, 0);
291
          video_movecursor(0, 0);
291
          video_movecursor(0, 0);
292
          system("FDISK");
292
          system("FDISK");
293
          break;
293
          break;
294
        default:
294
        default:
295
          return(-1);
295
          return(-1);
296
      }
296
      }
297
      newscreen();
297
      newscreen();
298
      putstringnls(11, 10, COLOR_BODY[mono], 3, 1, "Your computer will reboot now.");
298
      putstringnls(11, 10, COLOR_BODY[mono], 3, 1, "Your computer will reboot now.");
299
      putstringnls(12, 10, COLOR_BODY[mono], 0, 5, "Press any key...");
299
      putstringnls(12, 10, COLOR_BODY[mono], 0, 5, "Press any key...");
300
      input_getkey();
300
      input_getkey();
301
      reboot();
301
      reboot();
302
      return(-1);
302
      return(-1);
303
    } else if (driveremovable > 0) {
303
    } else if (driveremovable > 0) {
304
      snprintf(buff, sizeof(buff), kittengets(3, 2, "ERROR: Drive %c: is a removable device. Installation aborted."), cselecteddrive);
304
      snprintf(buff, sizeof(buff), kittengets(3, 2, "ERROR: Drive %c: is a removable device. Installation aborted."), cselecteddrive);
305
      video_putstring(9, 2, COLOR_BODY[mono], buff, -1);
305
      video_putstring(9, 2, COLOR_BODY[mono], buff, -1);
306
      putstringnls(11, 2, COLOR_BODY[mono], 0, 5, "Press any key...");
306
      putstringnls(11, 2, COLOR_BODY[mono], 0, 5, "Press any key...");
307
      return(-1);
307
      return(-1);
308
    }
308
    }
309
    /* if not formatted, propose to format it right away (try to create a directory) */
309
    /* if not formatted, propose to format it right away (try to create a directory) */
310
    snprintf(buff, sizeof(buff), "%c:\\SVWRTEST.123", cselecteddrive);
310
    snprintf(buff, sizeof(buff), "%c:\\SVWRTEST.123", cselecteddrive);
311
    if (mkdir(buff) == 0) {
311
    if (mkdir(buff) == 0) {
312
      rmdir(buff);
312
      rmdir(buff);
313
    } else {
313
    } else {
314
      char *list[] = { "Proceed with formatting", "Quit to DOS", NULL};
314
      char *list[] = { "Proceed with formatting", "Quit to DOS", NULL};
315
      list[0] = kittengets(0, 6, list[0]);
315
      list[0] = kittengets(0, 6, list[0]);
316
      list[1] = kittengets(0, 2, list[1]);
316
      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);
317
      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, 2, COLOR_BODY[mono], buff, -1);
318
      video_putstring(7, 2, COLOR_BODY[mono], buff, -1);
319
      if (menuselect(12, -1, 4, list) != 0) return(-1);
319
      if (menuselect(12, -1, 4, list) != 0) return(-1);
320
      video_clear(0x0700, 0);
320
      video_clear(0x0700, 0);
321
      video_movecursor(0, 0);
321
      video_movecursor(0, 0);
322
      snprintf(buff, sizeof(buff), "FORMAT %c: /Q /U /Z:seriously /V:SVAROG386", cselecteddrive);
322
      snprintf(buff, sizeof(buff), "FORMAT %c: /Q /U /Z:seriously /V:SVAROG386", cselecteddrive);
323
      system(buff);
323
      system(buff);
324
      continue;
324
      continue;
325
    }
325
    }
326
    /* check total disk space */
326
    /* check total disk space */
327
    ds = disksize(selecteddrive);
327
    ds = disksize(selecteddrive);
328
    if (ds < SVAROG_DISK_REQ) {
328
    if (ds < SVAROG_DISK_REQ) {
329
      int y = 9;
329
      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);
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);
331
      y += putstringwrap(y, 2, COLOR_BODY[mono], buff);
331
      y += putstringwrap(y, 2, COLOR_BODY[mono], buff);
332
      putstringnls(++y, 2, COLOR_BODY[mono], 0, 5, "Press any key...");
332
      putstringnls(++y, 2, COLOR_BODY[mono], 0, 5, "Press any key...");
333
      input_getkey();
333
      input_getkey();
334
      return(-1);
334
      return(-1);
335
    }
335
    }
336
    /* is the disk empty? */
336
    /* is the disk empty? */
337
    if (diskempty(selecteddrive) != 0) {
337
    if (diskempty(selecteddrive) != 0) {
338
      char *list[] = { "Proceed with formatting", "Quit to DOS", NULL};
338
      char *list[] = { "Proceed with formatting", "Quit to DOS", NULL};
339
      list[0] = kittengets(0, 6, list[0]);
339
      list[0] = kittengets(0, 6, list[0]);
340
      list[1] = kittengets(0, 2, list[1]);
340
      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);
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);
342
      putstringwrap(7, 2, COLOR_BODY[mono], buff);
342
      putstringwrap(7, 2, COLOR_BODY[mono], buff);
343
      if (menuselect(12, -1, 4, list) != 0) return(-1);
343
      if (menuselect(12, -1, 4, list) != 0) return(-1);
344
      video_clear(0x0700, 0);
344
      video_clear(0x0700, 0);
345
      video_movecursor(0, 0);
345
      video_movecursor(0, 0);
346
      snprintf(buff, sizeof(buff), "FORMAT %c: /Q /U /Z:seriously /V:SVAROG386", cselecteddrive);
346
      snprintf(buff, sizeof(buff), "FORMAT %c: /Q /U /Z:seriously /V:SVAROG386", cselecteddrive);
347
      system(buff);
347
      system(buff);
348
      continue;
348
      continue;
349
    } else {
349
    } else {
350
      /* final confirmation */
350
      /* final confirmation */
351
      char *list[] = { "Install Svarog386", "Quit to DOS", NULL};
351
      char *list[] = { "Install Svarog386", "Quit to DOS", NULL};
352
      list[0] = kittengets(0, 1, list[0]);
352
      list[0] = kittengets(0, 1, list[0]);
353
      list[1] = kittengets(0, 2, list[1]);
353
      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);
354
      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);
355
      video_putstring(7, -1, COLOR_BODY[mono], buff, -1);
356
      if (menuselect(10, -1, 4, list) != 0) return(-1);
356
      if (menuselect(10, -1, 4, list) != 0) return(-1);
357
      snprintf(buff, sizeof(buff), "SYS A: %c:", cselecteddrive);
357
      snprintf(buff, sizeof(buff), "SYS A: %c:", cselecteddrive);
358
      system(buff);
358
      system(buff);
359
      snprintf(buff, sizeof(buff), "%c:\\TEMP", cselecteddrive);
359
      snprintf(buff, sizeof(buff), "%c:\\TEMP", cselecteddrive);
360
      mkdir(buff);
360
      mkdir(buff);
361
      return(cselecteddrive);
361
      return(cselecteddrive);
362
    }
362
    }
363
  }
363
  }
364
}
364
}
365
 
365
 
366
 
366
 
367
/* copy file src into dst, substituting all characters c1 by c2 */
367
/* copy file src into dst, substituting all characters c1 by c2 */
368
static void fcopysub(char *dst, char *src, char c1, char c2) {
368
static void fcopysub(char *dst, char *src, char c1, char c2) {
369
  FILE *fdd, *fds;
369
  FILE *fdd, *fds;
370
  int buff;
370
  int buff;
371
  fds = fopen(src, "rb");
371
  fds = fopen(src, "rb");
372
  if (fds == NULL) return;
372
  if (fds == NULL) return;
373
  fdd = fopen(dst, "wb");
373
  fdd = fopen(dst, "wb");
374
  if (fdd == NULL) {
374
  if (fdd == NULL) {
375
    fclose(fds);
375
    fclose(fds);
376
    return;
376
    return;
377
  }
377
  }
378
  /* */
378
  /* */
379
  for (;;) {
379
  for (;;) {
380
    buff = fgetc(fds);
380
    buff = fgetc(fds);
381
    if (buff == EOF) break;
381
    if (buff == EOF) break;
382
    if (buff == c1) buff = c2;
382
    if (buff == c1) buff = c2;
383
    fprintf(fdd, "%c", buff);
383
    fprintf(fdd, "%c", buff);
384
  }
384
  }
385
  /* close files and return */
385
  /* close files and return */
386
  fclose(fdd);
386
  fclose(fdd);
387
  fclose(fds);
387
  fclose(fds);
388
}
388
}
389
 
389
 
390
 
390
 
391
static void bootfilesgen(int targetdrv, char *lang, int cdromdrv) {
391
static void bootfilesgen(int targetdrv, char *lang, int cdromdrv) {
392
  char buff[128];
392
  char buff[128];
393
  int cp, egafile;
393
  int cp, egafile;
394
  FILE *fd;
394
  FILE *fd;
395
  cp = getnlscp(lang, &egafile);
395
  cp = getnlscp(lang, &egafile);
396
  /*** CONFIG.SYS ***/
396
  /*** CONFIG.SYS ***/
397
  snprintf(buff, sizeof(buff), "%c:\\CONFIG.SYS", targetdrv);
397
  snprintf(buff, sizeof(buff), "%c:\\CONFIG.SYS", targetdrv);
398
  fd = fopen(buff, "wb");
398
  fd = fopen(buff, "wb");
399
  if (fd == NULL) return;
399
  if (fd == NULL) return;
400
  fprintf(fd, "DOS=UMB,HIGH\r\n");
400
  fprintf(fd, "DOS=UMB,HIGH\r\n");
401
  fprintf(fd, "FILES=50\r\n");
401
  fprintf(fd, "FILES=50\r\n");
402
  fprintf(fd, "DEVICE=%c:\\SYSTEM\\SVAROG.386\\BIN\\HIMEMX.EXE\r\n", targetdrv);
402
  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);
403
  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);
404
  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);
405
  fprintf(fd, "DEVICE=%c:\\SYSTEM\\DRIVERS\\UDVD2\\UDVD2.SYS /D:SVCD0001 /H\r\n", targetdrv);
406
  fclose(fd);
406
  fclose(fd);
407
  /*** AUTOEXEC.BAT ***/
407
  /*** AUTOEXEC.BAT ***/
408
  snprintf(buff, sizeof(buff), "%c:\\AUTOEXEC.BAT", targetdrv);
408
  snprintf(buff, sizeof(buff), "%c:\\AUTOEXEC.BAT", targetdrv);
409
  fd = fopen(buff, "wb");
409
  fd = fopen(buff, "wb");
410
  if (fd == NULL) return;
410
  if (fd == NULL) return;
411
  fprintf(fd, "@ECHO OFF\r\n");
411
  fprintf(fd, "@ECHO OFF\r\n");
412
  fprintf(fd, "SET TEMP=%c:\\TEMP\r\n", targetdrv);
412
  fprintf(fd, "SET TEMP=%c:\\TEMP\r\n", targetdrv);
413
  fprintf(fd, "SET DOSDIR=%c:\\SYSTEM\\SVAROG.386\r\n", targetdrv);
413
  fprintf(fd, "SET DOSDIR=%c:\\SYSTEM\\SVAROG.386\r\n", targetdrv);
414
  fprintf(fd, "SET NLSPATH=%%DOSDIR%%\\NLS\r\n");
414
  fprintf(fd, "SET NLSPATH=%%DOSDIR%%\\NLS\r\n");
415
  fprintf(fd, "SET LANG=%s\r\n", lang);
415
  fprintf(fd, "SET LANG=%s\r\n", lang);
416
  fprintf(fd, "SET DIRCMD=/OGNE/P/4\r\n");
416
  fprintf(fd, "SET DIRCMD=/OGNE/P/4\r\n");
417
  fprintf(fd, "SET FDNPKG.CFG=%c:\\SYSTEM\\CFG\\FDNPKG.CFG\r\n", targetdrv);
417
  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);
418
  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);
419
  fprintf(fd, "PATH %%DOSDIR%%\\BIN;%c:\\SYSTEM\\LINKS\r\n", targetdrv);
420
  fprintf(fd, "PROMPT $P$G\r\n");
420
  fprintf(fd, "PROMPT $P$G\r\n");
421
  fprintf(fd, "ALIAS REBOOT=FDAPM COLDBOOT\r\n");
421
  fprintf(fd, "ALIAS REBOOT=FDAPM COLDBOOT\r\n");
422
  fprintf(fd, "ALIAS HALT=FDAPM POWEROFF\r\n");
422
  fprintf(fd, "ALIAS HALT=FDAPM POWEROFF\r\n");
423
  fprintf(fd, "FDAPM APMDOS\r\n");
423
  fprintf(fd, "FDAPM APMDOS\r\n");
424
  fprintf(fd, "\r\n");
424
  fprintf(fd, "\r\n");
425
  if (egafile > 0) {
425
  if (egafile > 0) {
426
    fprintf(fd, "DISPLAY CON=(EGA,,1)\r\n");
426
    fprintf(fd, "DISPLAY CON=(EGA,,1)\r\n");
427
    if (egafile == 1) {
427
    if (egafile == 1) {
428
      fprintf(fd, "MODE CON CP PREPARE=((%d) %c:\\SYSTEM\\SVAROG.386\\CPI\\EGA.CPX)\r\n", cp, targetdrv);
428
      fprintf(fd, "MODE CON CP PREPARE=((%d) %c:\\SYSTEM\\SVAROG.386\\CPI\\EGA.CPX)\r\n", cp, targetdrv);
429
    } else {
429
    } else {
430
      fprintf(fd, "MODE CON CP PREPARE=((%d) %c:\\SYSTEM\\SVAROG.386\\CPI\\EGA%d.CPX)\r\n", cp, targetdrv, egafile);
430
      fprintf(fd, "MODE CON CP PREPARE=((%d) %c:\\SYSTEM\\SVAROG.386\\CPI\\EGA%d.CPX)\r\n", cp, targetdrv, egafile);
431
    }
431
    }
432
    fprintf(fd, "MODE CON CP SELECT=%d\r\n", cp);
432
    fprintf(fd, "MODE CON CP SELECT=%d\r\n", cp);
433
    fprintf(fd, "\r\n");
433
    fprintf(fd, "\r\n");
434
  }
434
  }
435
  fprintf(fd, "SHSUCDX /d:SVCD0001\r\n");
435
  fprintf(fd, "SHSUCDX /d:SVCD0001\r\n");
436
  fprintf(fd, "\r\n");
436
  fprintf(fd, "\r\n");
437
  fprintf(fd, "REM Uncomment the line below for automatic mouse support\r\n");
437
  fprintf(fd, "REM Uncomment the line below for automatic mouse support\r\n");
438
  fprintf(fd, "REM CTMOUSE\r\n");
438
  fprintf(fd, "REM CTMOUSE\r\n");
439
  fprintf(fd, "\r\n");
439
  fprintf(fd, "\r\n");
440
  fprintf(fd, "ECHO.\r\n");
440
  fprintf(fd, "ECHO.\r\n");
441
  fprintf(fd, "ECHO Welcome to Svarog386! Type 'HELP' if you need help.\r\n");
441
  fprintf(fd, "ECHO Welcome to Svarog386! Type 'HELP' if you need help.\r\n");
442
  fclose(fd);
442
  fclose(fd);
443
  /*** CREATE DIRECTORY FOR OTHER CONFIGURATION FILES ***/
443
  /*** CREATE DIRECTORY FOR OTHER CONFIGURATION FILES ***/
444
  snprintf(buff, sizeof(buff), "%c:\\SYSTEM\\CFG", targetdrv);
444
  snprintf(buff, sizeof(buff), "%c:\\SYSTEM\\CFG", targetdrv);
445
  mkdir(buff);
445
  mkdir(buff);
446
  /*** FDNPKG.CFG ***/
446
  /*** FDNPKG.CFG ***/
447
  snprintf(buff, sizeof(buff), "%c:\\SYSTEM\\CFG\\FDNPKG.CFG", targetdrv);
447
  snprintf(buff, sizeof(buff), "%c:\\SYSTEM\\CFG\\FDNPKG.CFG", targetdrv);
448
  fcopysub(buff, "A:\\DAT\\FDNPKG.CFG", '$', cdromdrv);
448
  fcopysub(buff, "A:\\DAT\\FDNPKG.CFG", '$', cdromdrv);
449
  /*** COUNTRY.SYS ***/
449
  /*** COUNTRY.SYS ***/
450
  /*** PICOTCP ***/
450
  /*** PICOTCP ***/
451
  /*** WATTCP ***/
451
  /*** WATTCP ***/
452
}
452
}
453
 
453
 
454
 
454
 
455
static void installpackages(int targetdrv, int cdromdrv) {
455
static void installpackages(int targetdrv, int cdromdrv) {
456
  char *pkglist[] = {
456
  char *pkglist[] = {
457
    "A:\\UDVD2", /* this one's not part of CORE, hence it's stored right on the floppy */
457
    "A:\\UDVD2", /* this one's not part of CORE, hence it's stored right on the floppy */
458
    "APPEND",
458
    "APPEND",
459
    "ASSIGN",
459
    "ASSIGN",
460
    "ATTRIB",
460
    "ATTRIB",
461
    "CHKDSK",
461
    "CHKDSK",
462
    "CHOICE",
462
    "CHOICE",
463
    "COMMAND",
463
    "COMMAND",
464
    "COMP",
464
    "COMP",
465
    "CPIDOS",
465
    "CPIDOS",
466
    "CTMOUSE",
466
    "CTMOUSE",
467
    "DEBUG",
467
    "DEBUG",
468
    "DEFRAG",
468
    "DEFRAG",
469
    "DELTREE",
469
    "DELTREE",
470
    "DEVLOAD",
470
    "DEVLOAD",
471
    "DISKCOMP",
471
    "DISKCOMP",
472
    "DISKCOPY",
472
    "DISKCOPY",
473
    "DISPLAY",
473
    "DISPLAY",
474
    "DOSFSCK",
474
    "DOSFSCK",
475
    "EDIT",
475
    "EDIT",
476
    "EDLIN",
476
    "EDLIN",
477
    "EXE2BIN",
477
    "EXE2BIN",
478
    "FC",
478
    "FC",
479
    "FDAPM",
479
    "FDAPM",
480
    "FDISK",
480
    "FDISK",
481
    "FDNPKG",
481
    "FDNPKG",
482
    "FIND",
482
    "FIND",
483
    "FORMAT",
483
    "FORMAT",
484
    "HELP",
484
    "HELP",
485
    "HIMEMX",
485
    "HIMEMX",
486
    "KERNEL",
486
    "KERNEL",
487
    "KEYB",
487
    "KEYB",
488
    "LABEL",
488
    "LABEL",
489
    "LBACACHE",
489
    "LBACACHE",
490
    "MEM",
490
    "MEM",
491
    "MIRROR",
491
    "MIRROR",
492
    "MODE",
492
    "MODE",
493
    "MORE",
493
    "MORE",
494
    "MOVE",
494
    "MOVE",
495
    "NANSI",
495
    "NANSI",
496
    "NLSFUNC",
496
    "NLSFUNC",
497
    "PRINT",
497
    "PRINT",
498
    "RDISK",
498
    "RDISK",
499
    "RECOVER",
499
    "RECOVER",
500
    "REPLACE",
500
    "REPLACE",
501
    "SHARE",
501
    "SHARE",
502
    "SHSUCDX",
502
    "SHSUCDX",
503
    "SORT",
503
    "SORT",
504
    "SWSUBST",
504
    "SWSUBST",
505
    "TREE",
505
    "TREE",
506
    "UNDELETE",
506
    "UNDELETE",
507
    "XCOPY",
507
    "XCOPY",
508
    NULL
508
    NULL
509
  };
509
  };
510
  int i, pkglistlen;
510
  int i, pkglistlen;
511
  char buff[64];
511
  char buff[64];
512
  newscreen();
512
  newscreen();
513
  /* count how long the pkg list is */
513
  /* count how long the pkg list is */
514
  for (pkglistlen = 0; pkglist[pkglistlen] != NULL; pkglistlen++);
514
  for (pkglistlen = 0; pkglist[pkglistlen] != NULL; pkglistlen++);
515
  /* set DOSDIR and friends */
515
  /* set DOSDIR and friends */
516
  snprintf(buff, sizeof(buff), "%c:\\SYSTEM\\SVAROG.386", targetdrv);
516
  snprintf(buff, sizeof(buff), "%c:\\SYSTEM\\SVAROG.386", targetdrv);
517
  setenv("DOSDIR", buff, 1);
517
  setenv("DOSDIR", buff, 1);
518
  snprintf(buff, sizeof(buff), "%c:\\TEMP", targetdrv);
518
  snprintf(buff, sizeof(buff), "%c:\\TEMP", targetdrv);
519
  setenv("TEMP", buff, 1);
519
  setenv("TEMP", buff, 1);
520
  /* install packages */
520
  /* install packages */
521
  for (i = 0; pkglist[i] != NULL; i++) {
521
  for (i = 0; pkglist[i] != NULL; i++) {
522
    char buff[128];
522
    char buff[128];
523
    snprintf(buff, sizeof(buff), kittengets(4, 0, "Installing package %d/%d: %s"), i+1, pkglistlen, pkglist[i]);
523
    snprintf(buff, sizeof(buff), kittengets(4, 0, "Installing package %d/%d: %s"), i+1, pkglistlen, pkglist[i]);
524
    strcat(buff, "       ");
524
    strcat(buff, "       ");
525
    video_putstring(10, 2, COLOR_BODY[mono], buff, -1);
525
    video_putstring(10, 2, COLOR_BODY[mono], buff, -1);
526
    if (pkglist[i][1] == ':') {
526
    if (pkglist[i][1] == ':') {
527
      snprintf(buff, sizeof(buff), "FDINST INSTALL %s.ZIP > NUL", pkglist[i]);
527
      snprintf(buff, sizeof(buff), "FDINST INSTALL %s.ZIP > NUL", pkglist[i]);
528
    } else {
528
    } else {
529
      snprintf(buff, sizeof(buff), "FDINST INSTALL %c:\\CORE\\%s.ZIP > NUL", cdromdrv, pkglist[i]);
529
      snprintf(buff, sizeof(buff), "FDINST INSTALL %c:\\CORE\\%s.ZIP > NUL", cdromdrv, pkglist[i]);
530
    }
530
    }
531
    system(buff);
531
    system(buff);
532
  }
532
  }
533
}
533
}
534
 
534
 
535
 
535
 
536
static void finalreboot(void) {
536
static void finalreboot(void) {
537
  int y = 9;
537
  int y = 9;
538
  newscreen();
538
  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.");
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.");
540
  putstringnls(++y, 2, COLOR_BODY[mono], 0, 5, "Press any key...");
540
  putstringnls(++y, 2, COLOR_BODY[mono], 0, 5, "Press any key...");
541
  input_getkey();
541
  input_getkey();
542
  reboot();
542
  reboot();
543
}
543
}
544
 
544
 
545
 
545
 
546
static void loadcp(char *lang) {
546
static void loadcp(char *lang) {
547
  int cp, egafile;
547
  int cp, egafile;
548
  char buff[64];
548
  char buff[64];
549
  cp = getnlscp(lang, &egafile);
549
  cp = getnlscp(lang, &egafile);
550
  if (cp == 437) return;
550
  if (cp == 437) return;
551
  video_movecursor(1, 0);
551
  video_movecursor(1, 0);
552
  if (egafile == 1) {
552
  if (egafile == 1) {
553
    snprintf(buff, sizeof(buff), "MODE CON CP PREP=((%d) A:\\EGA.CPX) > NUL", cp);
553
    snprintf(buff, sizeof(buff), "MODE CON CP PREP=((%d) A:\\EGA.CPX) > NUL", cp);
554
  } else {
554
  } else {
555
    snprintf(buff, sizeof(buff), "MODE CON CP PREP=((%d) A:\\EGA%d.CPX) > NUL", cp, egafile);
555
    snprintf(buff, sizeof(buff), "MODE CON CP PREP=((%d) A:\\EGA%d.CPX) > NUL", cp, egafile);
556
  }
556
  }
557
  system(buff);
557
  system(buff);
558
  snprintf(buff, sizeof(buff), "MODE CON CP SEL=%d > NUL", cp);
558
  snprintf(buff, sizeof(buff), "MODE CON CP SEL=%d > NUL", cp);
559
  system(buff);
559
  system(buff);
560
  /* below I re-init the video controller - apparently this is required if
560
  /* below I re-init the video controller - apparently this is required if
561
   * I want the new glyph symbols to be actually applied */
561
   * I want the new glyph symbols to be actually applied */
562
  {
562
  {
563
  union REGS r;
563
  union REGS r;
564
  r.h.ah = 0x0F; /* get current video mode */
564
  r.h.ah = 0x0F; /* get current video mode */
565
  int86(0x10, &r, &r); /* r.h.al contains the current video mode now */
565
  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+) */
566
  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) */
567
  r.h.ah = 0; /* re-set video mode (to whatever is set in AL) */
568
  int86(0x10, &r, &r);
568
  int86(0x10, &r, &r);
569
  }
569
  }
570
}
570
}
571
 
571
 
572
 
572
 
573
int main(void) {
573
int main(void) {
574
  char lang[4];
574
  char lang[4];
575
  int targetdrv;
575
  int targetdrv;
576
  int cdromdrv;
576
  int cdromdrv;
577
 
577
 
578
  /* find where the cdrom drive is */
578
  /* find where the cdrom drive is */
579
  cdromdrv = cdrom_findfirst();
579
  cdromdrv = cdrom_findfirst();
580
  cdromdrv = 3;
-
 
581
  if (cdromdrv < 0) {
580
  if (cdromdrv < 0) {
582
    printf("ERROR: CD-ROM DRIVE NOT FOUND\r\n");
581
    printf("ERROR: CD-ROM DRIVE NOT FOUND\r\n");
583
    return(1);
582
    return(1);
584
  }
583
  }
585
  cdromdrv += 'A'; /* convert the cdrom 'id' (A=0) to an actual drive letter */
584
  cdromdrv += 'A'; /* convert the cdrom 'id' (A=0) to an actual drive letter */
586
 
585
 
587
  /* init screen and detect mono status */
586
  /* init screen and detect mono status */
588
  mono = video_init();
587
  mono = video_init();
589
 
588
 
590
  for (;;) { /* fake loop, it's here just to break out easily */
589
  for (;;) { /* fake loop, it's here just to break out easily */
591
    if (selectlang(lang) < 0) break; /* welcome to svarog, select your language */
590
    if (selectlang(lang) < 0) break; /* welcome to svarog, select your language */
592
    setenv("LANG", lang, 1);
591
    setenv("LANG", lang, 1);
593
    loadcp(lang);
592
    loadcp(lang);
594
    kittenopen("INSTALL"); /* NLS support */
593
    kittenopen("INSTALL"); /* NLS support */
595
    /*selectkeyb();*/ /* what keyb layout should we use? */
594
    /*selectkeyb();*/ /* what keyb layout should we use? */
596
    if (welcomescreen() != 0) break; /* what svarog386 is, ask whether to run live dos or install */
595
    if (welcomescreen() != 0) break; /* what svarog386 is, ask whether to run live dos or install */
597
    targetdrv = preparedrive(); /* what drive should we install to? check avail. space */
596
    targetdrv = preparedrive(); /* what drive should we install to? check avail. space */
598
    if (targetdrv < 0) break;
597
    if (targetdrv < 0) break;
599
    /*askaboutsources();*/ /* IF sources are available, ask if installing with them */
598
    /*askaboutsources();*/ /* IF sources are available, ask if installing with them */
600
    installpackages(targetdrv, cdromdrv);    /* install packages */
599
    installpackages(targetdrv, cdromdrv);    /* install packages */
601
    bootfilesgen(targetdrv, lang, cdromdrv); /* generate boot files and other configurations */
600
    bootfilesgen(targetdrv, lang, cdromdrv); /* generate boot files and other configurations */
602
    /*localcfg();*/ /* show local params (currency, etc), and propose to change them (based on localcfg) */
601
    /*localcfg();*/ /* show local params (currency, etc), and propose to change them (based on localcfg) */
603
    /*netcfg();*/ /* basic networking config */
602
    /*netcfg();*/ /* basic networking config */
604
    finalreboot(); /* remove the CD and reboot */
603
    finalreboot(); /* remove the CD and reboot */
605
    break;
604
    break;
606
  }
605
  }
607
  kittenclose(); /* close NLS support */
606
  kittenclose(); /* close NLS support */
608
  video_clear(0x0700, 0);
607
  video_clear(0x0700, 0);
609
  video_movecursor(0, 0);
608
  video_movecursor(0, 0);
610
  return(0);
609
  return(0);
611
}
610
}
612
 
611