Subversion Repositories SvarDOS

Rev

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

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