Subversion Repositories SvarDOS

Rev

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

Rev 133 Rev 190
1
/*
1
/*
2
 * SVAROG386 INSTALL
2
 * SVARDOS INSTALL PROGRAM
3
 * COPYRIGHT (C) 2016 MATEUSZ VISTE, ALL RIGHTS RESERVED.
3
 * PUBLISHED UNDER THE TERMS OF THE MIT LICENSE
4
 *
4
 *
5
 * Redistribution and use in source and binary forms, with or without
5
 * COPYRIGHT (C) 2016-2021 MATEUSZ VISTE, ALL RIGHTS RESERVED.
6
 * modification, are permitted provided that the following conditions are met:
-
 
7
 *
6
 *
-
 
7
 * Permission is hereby granted, free of charge, to any person obtaining a
-
 
8
 * copy of this software and associated documentation files (the "Software"),
8
 * 1. Redistributions of source code must retain the above copyright notice,
9
 * to deal in the Software without restriction, including without limitation
-
 
10
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-
 
11
 * and/or sell copies of the Software, and to permit persons to whom the
9
 * this list of conditions and the following disclaimer.
12
 * Software is furnished to do so, subject to the following conditions:
10
 *
13
 *
11
 * 2. Redistributions in binary form must reproduce the above copyright
-
 
12
 * notice, this list of conditions and the following disclaimer in the
14
 * The above copyright notice and this permission notice shall be included in
13
 * documentation and/or other materials provided with the distribution.
15
 * all copies or substantial portions of the Software.
14
 *
16
 *
15
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-
 
17
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
-
 
19
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
19
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-
 
21
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-
 
22
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
20
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
21
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
24
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
22
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
25
 * POSSIBILITY OF SUCH DAMAGE.
23
 * DEALINGS IN THE SOFTWARE.
26
 *
24
 *
27
 * http://svarog386.sf.net
25
 * http://svardos.osdn.io
28
 */
26
 */
29
 
27
 
30
#include <dos.h>
28
#include <dos.h>
31
#include <direct.h>  /* mkdir() */
29
#include <direct.h>  /* mkdir() */
32
#include <stdio.h>   /* printf() and friends */
30
#include <stdio.h>   /* printf() and friends */
33
#include <stdlib.h>  /* system() */
31
#include <stdlib.h>  /* system() */
34
#include <string.h>  /* memcpy() */
32
#include <string.h>  /* memcpy() */
35
#include <unistd.h>
33
#include <unistd.h>
36
 
34
 
37
#include "kitten\kitten.h"
35
#include "kitten\kitten.h"
38
 
36
 
39
#include "cdrom.h"
37
#include "cdrom.h"
40
#include "input.h"
38
#include "input.h"
41
#include "video.h"
39
#include "video.h"
42
 
40
 
43
/* keyboard layouts and locales */
41
/* keyboard layouts and locales */
44
#include "keylay.h"
42
#include "keylay.h"
45
#include "keyoff.h"
43
#include "keyoff.h"
46
 
44
 
47
/* color scheme (color, mono) */
45
/* color scheme (color, mono) */
48
static unsigned short COLOR_TITLEBAR[2] = {0x7000,0x7000};
46
static unsigned short COLOR_TITLEBAR[2] = {0x7000,0x7000};
49
static unsigned short COLOR_BODY[2] = {0x1700,0x0700};
47
static unsigned short COLOR_BODY[2] = {0x1700,0x0700};
50
static unsigned short COLOR_SELECT[2] = {0x7000,0x7000};
48
static unsigned short COLOR_SELECT[2] = {0x7000,0x7000};
51
static unsigned short COLOR_SELECTCUR[2] = {0x1F00,0x0700};
49
static unsigned short COLOR_SELECTCUR[2] = {0x1F00,0x0700};
52
 
50
 
53
/* mono flag */
51
/* mono flag */
54
static int mono = 0;
52
static int mono = 0;
55
 
53
 
56
/* how much disk space does Svarog386 require (in MiB) */
54
/* how much disk space does SvarDOS require (in MiB) */
57
#define SVAROG_DISK_REQ 8
55
#define SVARDOS_DISK_REQ 8
58
 
56
 
59
/* menu screens can output only one of these: */
57
/* menu screens can output only one of these: */
60
#define MENUNEXT 0
58
#define MENUNEXT 0
61
#define MENUPREV -1
59
#define MENUPREV -1
62
#define MENUQUIT -2
60
#define MENUQUIT -2
63
 
61
 
64
/* a convenience 'function' used for debugging */
62
/* a convenience 'function' used for debugging */
65
#define DBG(x) { video_putstringfix(24, 0, 0x4F00u, x, 80); }
63
#define DBG(x) { video_putstringfix(24, 0, 0x4F00u, x, 80); }
66
 
64
 
67
struct slocales {
65
struct slocales {
68
  char lang[4];
66
  char lang[4];
69
  char *keybcode;
67
  char *keybcode;
70
  unsigned int codepage;
68
  unsigned int codepage;
71
  int egafile;
69
  int egafile;
72
  int keybfile;
70
  int keybfile;
73
  int keyboff;
71
  int keyboff;
74
  int keyblen;
72
  int keyblen;
75
  unsigned int keybid;
73
  unsigned int keybid;
76
};
74
};
77
 
75
 
78
 
76
 
79
/* reboot the computer */
77
/* reboot the computer */
80
static void reboot(void) {
78
static void reboot(void) {
81
  void ((far *bootroutine)()) = (void (far *)()) 0xFFFF0000L;
79
  void ((far *bootroutine)()) = (void (far *)()) 0xFFFF0000L;
82
  int far *rstaddr = (int far *)0x00400072L; /* BIOS boot flag is at 0040:0072 */
80
  int far *rstaddr = (int far *)0x00400072L; /* BIOS boot flag is at 0040:0072 */
83
  *rstaddr = 0x1234; /* 0x1234 = warm boot, 0 = cold boot */
81
  *rstaddr = 0x1234; /* 0x1234 = warm boot, 0 = cold boot */
84
  (*bootroutine)(); /* jump to the BIOS reboot routine at FFFF:0000 */
82
  (*bootroutine)(); /* jump to the BIOS reboot routine at FFFF:0000 */
85
}
83
}
86
 
84
 
87
 
85
 
88
/* outputs a string to screen with taking care of word wrapping. returns amount of lines. */
86
/* outputs a string to screen with taking care of word wrapping. returns amount of lines. */
89
static int putstringwrap(int y, int x, unsigned short attr, char *s) {
87
static int putstringwrap(int y, int x, unsigned short attr, char *s) {
90
  int linew, lincount;
88
  int linew, lincount;
91
  linew = 80;
89
  linew = 80;
92
  if (x >= 0) linew -= (x << 1);
90
  if (x >= 0) linew -= (x << 1);
93
 
91
 
94
  for (lincount = 1; y+lincount < 25; lincount++) {
92
  for (lincount = 1; y+lincount < 25; lincount++) {
95
    int i, len = linew;
93
    int i, len = linew;
96
    for (i = 0; i <= linew; i++) {
94
    for (i = 0; i <= linew; i++) {
97
      if (s[i] == ' ') len = i;
95
      if (s[i] == ' ') len = i;
98
      if (s[i] == '\n') {
96
      if (s[i] == '\n') {
99
        len = i;
97
        len = i;
100
        break;
98
        break;
101
      }
99
      }
102
      if (s[i] == 0) {
100
      if (s[i] == 0) {
103
        len = i;
101
        len = i;
104
        break;
102
        break;
105
      }
103
      }
106
    }
104
    }
107
    video_putstring(y++, x, attr, s, len);
105
    video_putstring(y++, x, attr, s, len);
108
    s += len;
106
    s += len;
109
    if (*s == 0) break;
107
    if (*s == 0) break;
110
    s += 1; /* skip the whitespace char */
108
    s += 1; /* skip the whitespace char */
111
  }
109
  }
112
  return(lincount);
110
  return(lincount);
113
}
111
}
114
 
112
 
115
 
113
 
116
/* an NLS wrapper around video_putstring(), also performs line wrapping when
114
/* an NLS wrapper around video_putstring(), also performs line wrapping when
117
 * needed. returns the amount of lines that were output */
115
 * needed. returns the amount of lines that were output */
118
static int putstringnls(int y, int x, unsigned short attr, int nlsmaj, int nlsmin, char *s) {
116
static int putstringnls(int y, int x, unsigned short attr, int nlsmaj, int nlsmin, char *s) {
119
  s = kittengets(nlsmaj, nlsmin, s);
117
  s = kittengets(nlsmaj, nlsmin, s);
120
  return(putstringwrap(y, x, attr, s));
118
  return(putstringwrap(y, x, attr, s));
121
}
119
}
122
 
120
 
123
 
121
 
124
static int menuselect(int ypos, int xpos, int height, char **list, int listlen) {
122
static int menuselect(int ypos, int xpos, int height, char **list, int listlen) {
125
  int i, offset = 0, res = 0, count, width = 0;
123
  int i, offset = 0, res = 0, count, width = 0;
126
  /* count how many positions there is, and check their width */
124
  /* count how many positions there is, and check their width */
127
  for (count = 0; (list[count] != NULL) && (count != listlen); count++) {
125
  for (count = 0; (list[count] != NULL) && (count != listlen); count++) {
128
    int len = strlen(list[count]);
126
    int len = strlen(list[count]);
129
    if (len > width) width = len;
127
    if (len > width) width = len;
130
  }
128
  }
131
 
129
 
132
  /* if xpos negative, means 'center out' */
130
  /* if xpos negative, means 'center out' */
133
  if (xpos < 0) xpos = 39 - (width >> 1);
131
  if (xpos < 0) xpos = 39 - (width >> 1);
134
 
132
 
135
  video_putchar(ypos, xpos+width+2, COLOR_SELECT[mono], 0xBF);         /*       \ */
133
  video_putchar(ypos, xpos+width+2, COLOR_SELECT[mono], 0xBF);         /*       \ */
136
  video_putchar(ypos, xpos-1, COLOR_SELECT[mono], 0xDA);               /*  /      */
134
  video_putchar(ypos, xpos-1, COLOR_SELECT[mono], 0xDA);               /*  /      */
137
  video_putchar(ypos+height-1, xpos-1, COLOR_SELECT[mono], 0xC0);      /*  \      */
135
  video_putchar(ypos+height-1, xpos-1, COLOR_SELECT[mono], 0xC0);      /*  \      */
138
  video_putchar(ypos+height-1, xpos+width+2, COLOR_SELECT[mono], 0xD9);/*      /  */
136
  video_putchar(ypos+height-1, xpos+width+2, COLOR_SELECT[mono], 0xD9);/*      /  */
139
  video_putcharmulti(ypos, xpos, COLOR_SELECT[mono], 0xC4, width + 2, 1);
137
  video_putcharmulti(ypos, xpos, COLOR_SELECT[mono], 0xC4, width + 2, 1);
140
  video_putcharmulti(ypos+height-1, xpos, COLOR_SELECT[mono], 0xC4, width + 2, 1);
138
  video_putcharmulti(ypos+height-1, xpos, COLOR_SELECT[mono], 0xC4, width + 2, 1);
141
  video_putcharmulti(ypos+1, xpos-1, COLOR_SELECT[mono], 0xB3, height - 2, 80);
139
  video_putcharmulti(ypos+1, xpos-1, COLOR_SELECT[mono], 0xB3, height - 2, 80);
142
  video_putcharmulti(ypos+1, xpos+width+2, COLOR_SELECT[mono], 0xB3, height - 2, 80);
140
  video_putcharmulti(ypos+1, xpos+width+2, COLOR_SELECT[mono], 0xB3, height - 2, 80);
143
 
141
 
144
  for (;;) {
142
  for (;;) {
145
    int key;
143
    int key;
146
    /* list of selectable items */
144
    /* list of selectable items */
147
    for (i = 0; i < height - 2; i++) {
145
    for (i = 0; i < height - 2; i++) {
148
      if (i + offset == res) {
146
      if (i + offset == res) {
149
        video_putchar(ypos + 1 + i, xpos, COLOR_SELECTCUR[mono], 16);
147
        video_putchar(ypos + 1 + i, xpos, COLOR_SELECTCUR[mono], 16);
150
        video_putchar(ypos + 1 + i, xpos+width+1, COLOR_SELECTCUR[mono], 17);
148
        video_putchar(ypos + 1 + i, xpos+width+1, COLOR_SELECTCUR[mono], 17);
151
        video_movecursor(ypos + 1 + i, xpos);
149
        video_movecursor(ypos + 1 + i, xpos);
152
        video_putstringfix(ypos + 1 + i, xpos+1, COLOR_SELECTCUR[mono], list[i + offset], width);
150
        video_putstringfix(ypos + 1 + i, xpos+1, COLOR_SELECTCUR[mono], list[i + offset], width);
153
      } else if (i + offset < count) {
151
      } else if (i + offset < count) {
154
        video_putchar(ypos + 1 + i, xpos, COLOR_SELECT[mono], ' ');
152
        video_putchar(ypos + 1 + i, xpos, COLOR_SELECT[mono], ' ');
155
        video_putchar(ypos + 1 + i, xpos+width+1, COLOR_SELECT[mono], ' ');
153
        video_putchar(ypos + 1 + i, xpos+width+1, COLOR_SELECT[mono], ' ');
156
        video_putstringfix(ypos + 1 + i, xpos+1, COLOR_SELECT[mono], list[i + offset], width);
154
        video_putstringfix(ypos + 1 + i, xpos+1, COLOR_SELECT[mono], list[i + offset], width);
157
      } else {
155
      } else {
158
        video_putcharmulti(ypos + 1 + i, xpos, COLOR_SELECT[mono], ' ', width+2, 1);
156
        video_putcharmulti(ypos + 1 + i, xpos, COLOR_SELECT[mono], ' ', width+2, 1);
159
      }
157
      }
160
    }
158
    }
161
    key = input_getkey();
159
    key = input_getkey();
162
    if (key == 0x0D) { /* ENTER */
160
    if (key == 0x0D) { /* ENTER */
163
      return(res);
161
      return(res);
164
    } else if (key == 0x148) { /* up */
162
    } else if (key == 0x148) { /* up */
165
      if (res > 0) {
163
      if (res > 0) {
166
        res--;
164
        res--;
167
        if (res < offset) offset = res;
165
        if (res < offset) offset = res;
168
      }
166
      }
169
    } else if (key == 0x150) { /* down */
167
    } else if (key == 0x150) { /* down */
170
      if (res+1 < count) {
168
      if (res+1 < count) {
171
        res++;
169
        res++;
172
        if (res > offset + height - 3) offset = res - (height - 3);
170
        if (res > offset + height - 3) offset = res - (height - 3);
173
      }
171
      }
174
    } else if (key == 0x147) { /* home */
172
    } else if (key == 0x147) { /* home */
175
      res = 0;
173
      res = 0;
176
      offset = 0;
174
      offset = 0;
177
    } else if (key == 0x14F) { /* end */
175
    } else if (key == 0x14F) { /* end */
178
      res = count - 1;
176
      res = count - 1;
179
      if (res > offset + height - 3) offset = res - (height - 3);
177
      if (res > offset + height - 3) offset = res - (height - 3);
180
    } else if (key == 0x1B) {  /* ESC */
178
    } else if (key == 0x1B) {  /* ESC */
181
      return(-1);
179
      return(-1);
182
    }/* else {
180
    }/* else {
183
      char buf[8];
181
      char buf[8];
184
      snprintf(buf, sizeof(buf), "0x%02X ", key);
182
      snprintf(buf, sizeof(buf), "0x%02X ", key);
185
      video_putstring(1, 0, COLOR_BODY[mono], buf, -1);
183
      video_putstring(1, 0, COLOR_BODY[mono], buf, -1);
186
    }*/
184
    }*/
187
  }
185
  }
188
}
186
}
189
 
187
 
190
static void newscreen(int statusbartype) {
188
static void newscreen(int statusbartype) {
191
  char *msg;
189
  char *msg;
192
  msg = kittengets(0, 0, "SVAROG386 INSTALLATION");
190
  msg = kittengets(0, 0, "SVARDOS INSTALLATION");
193
  video_putcharmulti(0, 0, COLOR_TITLEBAR[mono], ' ', 80, 1);
191
  video_putcharmulti(0, 0, COLOR_TITLEBAR[mono], ' ', 80, 1);
194
  video_putstring(0, 40 - (strlen(msg) >> 1), COLOR_TITLEBAR[mono], msg, -1);
192
  video_putstring(0, 40 - (strlen(msg) >> 1), COLOR_TITLEBAR[mono], msg, -1);
195
  video_clear(COLOR_BODY[mono], 80, -80);
193
  video_clear(COLOR_BODY[mono], 80, -80);
196
  switch (statusbartype) {
194
  switch (statusbartype) {
197
    case 1:
195
    case 1:
198
      msg = kittengets(0, 11, "Up/Down = Select entry | Enter = Validate your choice | ESC = Quit to DOS");
196
      msg = kittengets(0, 11, "Up/Down = Select entry | Enter = Validate your choice | ESC = Quit to DOS");
199
      break;
197
      break;
200
    case 2:
198
    case 2:
201
      msg = kittengets(0, 5, "Press any key...");
199
      msg = kittengets(0, 5, "Press any key...");
202
      break;
200
      break;
203
    case 3:
201
    case 3:
204
      msg = "";
202
      msg = "";
205
      break;
203
      break;
206
    default:
204
    default:
207
      msg = kittengets(0, 10, "Up/Down = Select entry | Enter = Validate your choice | ESC = Previous screen");
205
      msg = kittengets(0, 10, "Up/Down = Select entry | Enter = Validate your choice | ESC = Previous screen");
208
      break;
206
      break;
209
  }
207
  }
210
  video_putchar(24, 0, COLOR_TITLEBAR[mono], ' ');
208
  video_putchar(24, 0, COLOR_TITLEBAR[mono], ' ');
211
  video_putstringfix(24, 1, COLOR_TITLEBAR[mono], msg, 79);
209
  video_putstringfix(24, 1, COLOR_TITLEBAR[mono], msg, 79);
212
  video_movecursor(25,0);
210
  video_movecursor(25,0);
213
}
211
}
214
 
212
 
215
/* fills a slocales struct accordingly to the value of its keyboff member */
213
/* fills a slocales struct accordingly to the value of its keyboff member */
216
static void kblay2slocal(struct slocales *locales) {
214
static void kblay2slocal(struct slocales *locales) {
217
  char *m;
215
  char *m;
218
  for (m = kblayouts[locales->keyboff]; *m != 0; m++); /* skip layout name */
216
  for (m = kblayouts[locales->keyboff]; *m != 0; m++); /* skip layout name */
219
  m++;
217
  m++;
220
  /* skip keyb code and copy it to locales.keybcode */
218
  /* skip keyb code and copy it to locales.keybcode */
221
  locales->keybcode = m;
219
  locales->keybcode = m;
222
  for (; *m != 0; m++);
220
  for (; *m != 0; m++);
223
  /* */
221
  /* */
224
  locales->codepage = ((unsigned short)m[1] << 8) | m[2];
222
  locales->codepage = ((unsigned short)m[1] << 8) | m[2];
225
  locales->egafile = m[3];
223
  locales->egafile = m[3];
226
  locales->keybfile = m[4];
224
  locales->keybfile = m[4];
227
  locales->keybid = ((unsigned short)m[5] << 8) | m[6];
225
  locales->keybid = ((unsigned short)m[5] << 8) | m[6];
228
}
226
}
229
 
227
 
230
static int selectlang(struct slocales *locales) {
228
static int selectlang(struct slocales *locales) {
231
  int choice, x;
229
  int choice, x;
232
  char *msg;
230
  char *msg;
233
  char *langlist[] = {
231
  char *langlist[] = {
234
    "English",
232
    "English",
235
    "French",
233
    "French",
236
    "German",
234
    "German",
237
    "Italian",
235
    "Italian",
238
    "Polish",
236
    "Polish",
239
    "Russian",
237
    "Russian",
240
    "Slovene",
238
    "Slovene",
241
    "Swedish",
239
    "Swedish",
242
    "Turkish",
240
    "Turkish",
243
    NULL
241
    NULL
244
  };
242
  };
245
 
243
 
246
  newscreen(1);
244
  newscreen(1);
247
  msg = kittengets(1, 0, "Welcome to Svarog386");
245
  msg = kittengets(1, 0, "Welcome to SvarDOS");
248
  x = 40 - (strlen(msg) >> 1);
246
  x = 40 - (strlen(msg) >> 1);
249
  video_putstring(4, x, COLOR_BODY[mono], msg, -1);
247
  video_putstring(4, x, COLOR_BODY[mono], msg, -1);
250
  video_putcharmulti(5, x, COLOR_BODY[mono], '=', strlen(msg), 1);
248
  video_putcharmulti(5, x, COLOR_BODY[mono], '=', strlen(msg), 1);
251
  putstringnls(8, -1, COLOR_BODY[mono], 1, 1, "Please select your language from the list below:");
249
  putstringnls(8, -1, COLOR_BODY[mono], 1, 1, "Please select your language from the list below:");
252
  choice = menuselect(11, -1, 11, langlist, -1);
250
  choice = menuselect(11, -1, 11, langlist, -1);
253
  if (choice < 0) return(MENUPREV);
251
  if (choice < 0) return(MENUPREV);
254
  /* populate locales with default values */
252
  /* populate locales with default values */
255
  memset(locales, 0, sizeof(struct slocales));
253
  memset(locales, 0, sizeof(struct slocales));
256
  switch (choice) {
254
  switch (choice) {
257
    case 1:
255
    case 1:
258
      strcpy(locales->lang, "FR");
256
      strcpy(locales->lang, "FR");
259
      locales->keyboff = OFFLOC_FR;
257
      locales->keyboff = OFFLOC_FR;
260
      locales->keyblen = OFFLEN_FR;
258
      locales->keyblen = OFFLEN_FR;
261
      break;
259
      break;
262
    case 2:
260
    case 2:
263
      strcpy(locales->lang, "DE");
261
      strcpy(locales->lang, "DE");
264
      locales->keyboff = OFFLOC_DE;
262
      locales->keyboff = OFFLOC_DE;
265
      locales->keyblen = OFFLEN_DE;
263
      locales->keyblen = OFFLEN_DE;
266
      break;
264
      break;
267
    case 3:
265
    case 3:
268
      strcpy(locales->lang, "IT");
266
      strcpy(locales->lang, "IT");
269
      locales->keyboff = OFFLOC_IT;
267
      locales->keyboff = OFFLOC_IT;
270
      locales->keyblen = OFFLEN_IT;
268
      locales->keyblen = OFFLEN_IT;
271
      break;
269
      break;
272
    case 4:
270
    case 4:
273
      strcpy(locales->lang, "PL");
271
      strcpy(locales->lang, "PL");
274
      locales->keyboff = OFFLOC_PL;
272
      locales->keyboff = OFFLOC_PL;
275
      locales->keyblen = OFFLEN_PL;
273
      locales->keyblen = OFFLEN_PL;
276
      break;
274
      break;
277
    case 5:
275
    case 5:
278
      strcpy(locales->lang, "RU");
276
      strcpy(locales->lang, "RU");
279
      locales->keyboff = OFFLOC_RU;
277
      locales->keyboff = OFFLOC_RU;
280
      locales->keyblen = OFFLEN_RU;
278
      locales->keyblen = OFFLEN_RU;
281
      break;
279
      break;
282
    case 6:
280
    case 6:
283
      strcpy(locales->lang, "SI");
281
      strcpy(locales->lang, "SI");
284
      locales->keyboff = OFFLOC_SI;
282
      locales->keyboff = OFFLOC_SI;
285
      locales->keyblen = OFFLEN_SI;
283
      locales->keyblen = OFFLEN_SI;
286
      break;
284
      break;
287
    case 7:
285
    case 7:
288
      strcpy(locales->lang, "SV");
286
      strcpy(locales->lang, "SV");
289
      locales->keyboff = OFFLOC_SV;
287
      locales->keyboff = OFFLOC_SV;
290
      locales->keyblen = OFFLEN_SV;
288
      locales->keyblen = OFFLEN_SV;
291
      break;
289
      break;
292
    case 8:
290
    case 8:
293
      strcpy(locales->lang, "TR");
291
      strcpy(locales->lang, "TR");
294
      locales->keyboff = OFFLOC_TR;
292
      locales->keyboff = OFFLOC_TR;
295
      locales->keyblen = OFFLEN_TR;
293
      locales->keyblen = OFFLEN_TR;
296
      break;
294
      break;
297
    default:
295
    default:
298
      strcpy(locales->lang, "EN");
296
      strcpy(locales->lang, "EN");
299
      locales->keyboff = 0;
297
      locales->keyboff = 0;
300
      locales->keyblen = OFFCOUNT;
298
      locales->keyblen = OFFCOUNT;
301
      break;
299
      break;
302
  }
300
  }
303
  /* populate the slocales struct accordingly to the keyboff member */
301
  /* populate the slocales struct accordingly to the keyboff member */
304
  kblay2slocal(locales);
302
  kblay2slocal(locales);
305
  /* */
303
  /* */
306
  return(MENUNEXT);
304
  return(MENUNEXT);
307
}
305
}
308
 
306
 
309
 
307
 
310
static int selectkeyb(struct slocales *locales) {
308
static int selectkeyb(struct slocales *locales) {
311
  int menuheight, choice;
309
  int menuheight, choice;
312
  if (locales->keyblen == 1) return(MENUNEXT); /* do not ask for keyboard layout if only one is available for given language */
310
  if (locales->keyblen == 1) return(MENUNEXT); /* do not ask for keyboard layout if only one is available for given language */
313
  newscreen(0);
311
  newscreen(0);
314
  putstringnls(5, 1, COLOR_BODY[mono], 1, 5, "Svarog386 supports the keyboard layouts used in different countries. Choose the keyboard layout you want.");
312
  putstringnls(5, 1, COLOR_BODY[mono], 1, 5, "SvarDOS supports the keyboard layouts used in different countries. Choose the keyboard layout you want.");
315
  menuheight = locales->keyblen + 2;
313
  menuheight = locales->keyblen + 2;
316
  if (menuheight > 13) menuheight = 13;
314
  if (menuheight > 13) menuheight = 13;
317
  choice = menuselect(10, -1, menuheight, &(kblayouts[locales->keyboff]), locales->keyblen);
315
  choice = menuselect(10, -1, menuheight, &(kblayouts[locales->keyboff]), locales->keyblen);
318
  if (choice < 0) return(MENUPREV);
316
  if (choice < 0) return(MENUPREV);
319
  /* (re)load the keyboard layout & codepage setup */
317
  /* (re)load the keyboard layout & codepage setup */
320
  locales->keyboff += choice;
318
  locales->keyboff += choice;
321
  kblay2slocal(locales);
319
  kblay2slocal(locales);
322
  return(MENUNEXT);
320
  return(MENUNEXT);
323
}
321
}
324
 
322
 
325
 
323
 
326
/* returns 0 if installation must proceed, non-zero otherwise */
324
/* returns 0 if installation must proceed, non-zero otherwise */
327
static int welcomescreen(void) {
325
static int welcomescreen(void) {
328
  int c;
326
  int c;
329
  char *choice[] = {"Install Svarog386 to disk", "Quit to DOS", NULL};
327
  char *choice[] = {"Install SvarDOS to disk", "Quit to DOS", NULL};
330
  choice[0] = kittengets(0, 1, choice[0]);
328
  choice[0] = kittengets(0, 1, choice[0]);
331
  choice[1] = kittengets(0, 2, choice[1]);
329
  choice[1] = kittengets(0, 2, choice[1]);
332
  newscreen(0);
330
  newscreen(0);
333
  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.");
331
  putstringnls(4, 1, COLOR_BODY[mono], 2, 0, "You are about to install SvarDOS: a free, MSDOS-compatible operating system based on the FreeDOS kernel. SvarDOS 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 SvarDOS is installed.");
334
  c = menuselect(13, -1, 4, choice, -1);
332
  c = menuselect(13, -1, 4, choice, -1);
335
  if (c < 0) return(MENUPREV);
333
  if (c < 0) return(MENUPREV);
336
  if (c == 0) return(MENUNEXT);
334
  if (c == 0) return(MENUNEXT);
337
  return(MENUQUIT);
335
  return(MENUQUIT);
338
}
336
}
339
 
337
 
340
 
338
 
341
/* returns 1 if drive is removable, 0 if not, -1 on error */
339
/* returns 1 if drive is removable, 0 if not, -1 on error */
342
static int isdriveremovable(int drv) {
340
static int isdriveremovable(int drv) {
343
  union REGS r;
341
  union REGS r;
344
  r.x.ax = 0x4408;
342
  r.x.ax = 0x4408;
345
  r.h.bl = drv;
343
  r.h.bl = drv;
346
  int86(0x21, &r, &r);
344
  int86(0x21, &r, &r);
347
  /* CF set on error, AX set to 0 if removable, 1 if fixed */
345
  /* CF set on error, AX set to 0 if removable, 1 if fixed */
348
  if (r.x.cflag != 0) return(-1);
346
  if (r.x.cflag != 0) return(-1);
349
  if (r.x.ax == 0) return(1);
347
  if (r.x.ax == 0) return(1);
350
  return(0);
348
  return(0);
351
}
349
}
352
 
350
 
353
 
351
 
354
/* returns total disk space of drive drv (in MiB, max 2048), or -1 if drive invalid */
352
/* returns total disk space of drive drv (in MiB, max 2048), or -1 if drive invalid */
355
static int disksize(int drv) {
353
static int disksize(int drv) {
356
  long res;
354
  long res;
357
  union REGS r;
355
  union REGS r;
358
  r.h.ah = 0x36; /* DOS 2+ get free disk space */
356
  r.h.ah = 0x36; /* DOS 2+ get free disk space */
359
  r.h.dl = drv;
357
  r.h.dl = drv;
360
  int86(0x21, &r, &r);
358
  int86(0x21, &r, &r);
361
  if (r.x.ax == 0xffffu) return(-1); /* AX set to FFFFh if drive invalid */
359
  if (r.x.ax == 0xffffu) return(-1); /* AX set to FFFFh if drive invalid */
362
  res = r.x.ax;  /* sectors per cluster */
360
  res = r.x.ax;  /* sectors per cluster */
363
  res *= r.x.dx; /* dx contains total clusters, bx contains free clusters */
361
  res *= r.x.dx; /* dx contains total clusters, bx contains free clusters */
364
  res *= r.x.cx; /* bytes per sector */
362
  res *= r.x.cx; /* bytes per sector */
365
  res >>= 20;    /* convert bytes to MiB */
363
  res >>= 20;    /* convert bytes to MiB */
366
  return(res);
364
  return(res);
367
}
365
}
368
 
366
 
369
 
367
 
370
/* returns 0 if disk is empty, non-zero otherwise */
368
/* returns 0 if disk is empty, non-zero otherwise */
371
static int diskempty(int drv) {
369
static int diskempty(int drv) {
372
  unsigned int rc;
370
  unsigned int rc;
373
  int res;
371
  int res;
374
  char buff[8];
372
  char buff[8];
375
  struct find_t fileinfo;
373
  struct find_t fileinfo;
376
  snprintf(buff, sizeof(buff), "%c:\\*.*", 'A' + drv - 1);
374
  snprintf(buff, sizeof(buff), "%c:\\*.*", 'A' + drv - 1);
377
  rc = _dos_findfirst(buff, _A_NORMAL | _A_SUBDIR | _A_HIDDEN | _A_SYSTEM, &fileinfo);
375
  rc = _dos_findfirst(buff, _A_NORMAL | _A_SUBDIR | _A_HIDDEN | _A_SYSTEM, &fileinfo);
378
  if (rc == 0) {
376
  if (rc == 0) {
379
    res = 1; /* call successfull means disk is not empty */
377
    res = 1; /* call successfull means disk is not empty */
380
  } else {
378
  } else {
381
    res = 0;
379
    res = 0;
382
  }
380
  }
383
  /* _dos_findclose(&fileinfo); */ /* apparently required only on OS/2 */
381
  /* _dos_findclose(&fileinfo); */ /* apparently required only on OS/2 */
384
  return(res);
382
  return(res);
385
}
383
}
386
 
384
 
387
 
385
 
388
static int preparedrive(void) {
386
static int preparedrive(void) {
389
  int driveremovable;
387
  int driveremovable;
390
  int selecteddrive = 3; /* hardcoded to 'C:' for now */
388
  int selecteddrive = 3; /* hardcoded to 'C:' for now */
391
  int cselecteddrive;
389
  int cselecteddrive;
392
  int ds;
390
  int ds;
393
  int choice;
391
  int choice;
394
  char buff[1024];
392
  char buff[1024];
395
  cselecteddrive = 'A' + selecteddrive - 1;
393
  cselecteddrive = 'A' + selecteddrive - 1;
396
  for (;;) {
394
  for (;;) {
397
    driveremovable = isdriveremovable(selecteddrive);
395
    driveremovable = isdriveremovable(selecteddrive);
398
    if (driveremovable < 0) {
396
    if (driveremovable < 0) {
399
      char *list[] = { "Create a partition automatically", "Run the FDISK partitioning tool", "Quit to DOS", NULL};
397
      char *list[] = { "Create a partition automatically", "Run the FDISK partitioning tool", "Quit to DOS", NULL};
400
      newscreen(0);
398
      newscreen(0);
401
      list[0] = kittengets(0, 3, list[0]);
399
      list[0] = kittengets(0, 3, list[0]);
402
      list[1] = kittengets(0, 4, list[1]);
400
      list[1] = kittengets(0, 4, list[1]);
403
      list[2] = kittengets(0, 2, list[2]);
401
      list[2] = kittengets(0, 2, list[2]);
404
      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);
402
      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 SvarDOS can be installed on it. Note, that SvarDOS 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, SVARDOS_DISK_REQ);
405
      putstringwrap(4, 1, COLOR_BODY[mono], buff);
403
      putstringwrap(4, 1, COLOR_BODY[mono], buff);
406
      switch (menuselect(14, -1, 5, list, -1)) {
404
      switch (menuselect(14, -1, 5, list, -1)) {
407
        case 0:
405
        case 0:
408
          system("FDISK /AUTO");
406
          system("FDISK /AUTO");
409
          break;
407
          break;
410
        case 1:
408
        case 1:
411
          video_clear(0x0700, 0, 0);
409
          video_clear(0x0700, 0, 0);
412
          video_movecursor(0, 0);
410
          video_movecursor(0, 0);
413
          system("FDISK");
411
          system("FDISK");
414
          break;
412
          break;
415
        case 2:
413
        case 2:
416
          return(MENUQUIT);
414
          return(MENUQUIT);
417
        default:
415
        default:
418
          return(-1);
416
          return(-1);
419
      }
417
      }
420
      /* write a temporary MBR which only skips the drive (in case BIOS would
418
      /* write a temporary MBR which only skips the drive (in case BIOS would
421
       * try to boot off the not-yet-ready C: disk) */
419
       * try to boot off the not-yet-ready C: disk) */
422
      system("FDISK /AMBR"); /* writes BOOT.MBR into actual MBR */
420
      system("FDISK /AMBR"); /* writes BOOT.MBR into actual MBR */
423
      newscreen(2);
421
      newscreen(2);
424
      putstringnls(10, 10, COLOR_BODY[mono], 3, 1, "Your computer will reboot now.");
422
      putstringnls(10, 10, COLOR_BODY[mono], 3, 1, "Your computer will reboot now.");
425
      putstringnls(12, 10, COLOR_BODY[mono], 0, 5, "Press any key...");
423
      putstringnls(12, 10, COLOR_BODY[mono], 0, 5, "Press any key...");
426
      input_getkey();
424
      input_getkey();
427
      reboot();
425
      reboot();
428
      return(MENUQUIT);
426
      return(MENUQUIT);
429
    } else if (driveremovable > 0) {
427
    } else if (driveremovable > 0) {
430
      newscreen(2);
428
      newscreen(2);
431
      snprintf(buff, sizeof(buff), kittengets(3, 2, "ERROR: Drive %c: is a removable device. Installation aborted."), cselecteddrive);
429
      snprintf(buff, sizeof(buff), kittengets(3, 2, "ERROR: Drive %c: is a removable device. Installation aborted."), cselecteddrive);
432
      video_putstring(9, 1, COLOR_BODY[mono], buff, -1);
430
      video_putstring(9, 1, COLOR_BODY[mono], buff, -1);
433
      putstringnls(11, 2, COLOR_BODY[mono], 0, 5, "Press any key...");
431
      putstringnls(11, 2, COLOR_BODY[mono], 0, 5, "Press any key...");
434
      return(MENUQUIT);
432
      return(MENUQUIT);
435
    }
433
    }
436
    /* if not formatted, propose to format it right away (try to create a directory) */
434
    /* if not formatted, propose to format it right away (try to create a directory) */
437
    snprintf(buff, sizeof(buff), "%c:\\SVWRTEST.123", cselecteddrive);
435
    snprintf(buff, sizeof(buff), "%c:\\SVWRTEST.123", cselecteddrive);
438
    if (mkdir(buff) == 0) {
436
    if (mkdir(buff) == 0) {
439
      rmdir(buff);
437
      rmdir(buff);
440
    } else {
438
    } else {
441
      char *list[] = { "Proceed with formatting", "Quit to DOS", NULL};
439
      char *list[] = { "Proceed with formatting", "Quit to DOS", NULL};
442
      newscreen(0);
440
      newscreen(0);
443
      list[0] = kittengets(0, 6, list[0]);
441
      list[0] = kittengets(0, 6, list[0]);
444
      list[1] = kittengets(0, 2, list[1]);
442
      list[1] = kittengets(0, 2, list[1]);
445
      snprintf(buff, sizeof(buff), kittengets(3, 3, "ERROR: Drive %c: seems to be unformated. Do you wish to format it?"), cselecteddrive);
443
      snprintf(buff, sizeof(buff), kittengets(3, 3, "ERROR: Drive %c: seems to be unformated. Do you wish to format it?"), cselecteddrive);
446
      video_putstring(7, 1, COLOR_BODY[mono], buff, -1);
444
      video_putstring(7, 1, COLOR_BODY[mono], buff, -1);
447
      choice = menuselect(12, -1, 4, list, -1);
445
      choice = menuselect(12, -1, 4, list, -1);
448
      if (choice < 0) return(MENUPREV);
446
      if (choice < 0) return(MENUPREV);
449
      if (choice == 1) return(MENUQUIT);
447
      if (choice == 1) return(MENUQUIT);
450
      video_clear(0x0700, 0, 0);
448
      video_clear(0x0700, 0, 0);
451
      video_movecursor(0, 0);
449
      video_movecursor(0, 0);
452
      snprintf(buff, sizeof(buff), "FORMAT %c: /Q /U /Z:seriously /V:SVAROG386", cselecteddrive);
450
      snprintf(buff, sizeof(buff), "FORMAT %c: /Q /U /Z:seriously /V:SVARDOS", cselecteddrive);
453
      system(buff);
451
      system(buff);
454
      continue;
452
      continue;
455
    }
453
    }
456
    /* check total disk space */
454
    /* check total disk space */
457
    ds = disksize(selecteddrive);
455
    ds = disksize(selecteddrive);
458
    if (ds < SVAROG_DISK_REQ) {
456
    if (ds < SVARDOS_DISK_REQ) {
459
      int y = 9;
457
      int y = 9;
460
      newscreen(2);
458
      newscreen(2);
461
      snprintf(buff, sizeof(buff), kittengets(3, 4, "ERROR: Drive %c: is not big enough! Svarog386 requires a disk of at least %d MiB."), cselecteddrive);
459
      snprintf(buff, sizeof(buff), kittengets(3, 4, "ERROR: Drive %c: is not big enough! SvarDOS requires a disk of at least %d MiB."), cselecteddrive);
462
      y += putstringwrap(y, 1, COLOR_BODY[mono], buff);
460
      y += putstringwrap(y, 1, COLOR_BODY[mono], buff);
463
      putstringnls(++y, 1, COLOR_BODY[mono], 0, 5, "Press any key...");
461
      putstringnls(++y, 1, COLOR_BODY[mono], 0, 5, "Press any key...");
464
      input_getkey();
462
      input_getkey();
465
      return(MENUQUIT);
463
      return(MENUQUIT);
466
    }
464
    }
467
    /* is the disk empty? */
465
    /* is the disk empty? */
468
    newscreen(0);
466
    newscreen(0);
469
    if (diskempty(selecteddrive) != 0) {
467
    if (diskempty(selecteddrive) != 0) {
470
      char *list[] = { "Proceed with formatting", "Quit to DOS", NULL};
468
      char *list[] = { "Proceed with formatting", "Quit to DOS", NULL};
471
      int y = 6;
469
      int y = 6;
472
      list[0] = kittengets(0, 6, list[0]);
470
      list[0] = kittengets(0, 6, list[0]);
473
      list[1] = kittengets(0, 2, list[1]);
471
      list[1] = kittengets(0, 2, list[1]);
474
      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);
472
      snprintf(buff, sizeof(buff), kittengets(3, 5, "ERROR: Drive %c: is not empty. SvarDOS 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);
475
      y += putstringwrap(y, 1, COLOR_BODY[mono], buff);
473
      y += putstringwrap(y, 1, COLOR_BODY[mono], buff);
476
      choice = menuselect(++y, -1, 4, list, -1);
474
      choice = menuselect(++y, -1, 4, list, -1);
477
      if (choice < 0) return(MENUPREV);
475
      if (choice < 0) return(MENUPREV);
478
      if (choice == 1) return(MENUQUIT);
476
      if (choice == 1) return(MENUQUIT);
479
      video_clear(0x0700, 0, 0);
477
      video_clear(0x0700, 0, 0);
480
      video_movecursor(0, 0);
478
      video_movecursor(0, 0);
481
      snprintf(buff, sizeof(buff), "FORMAT %c: /Q /U /Z:seriously /V:SVAROG386", cselecteddrive);
479
      snprintf(buff, sizeof(buff), "FORMAT %c: /Q /U /Z:seriously /V:SVARDOS", cselecteddrive);
482
      system(buff);
480
      system(buff);
483
      continue;
481
      continue;
484
    } else {
482
    } else {
485
      /* final confirmation */
483
      /* final confirmation */
486
      char *list[] = { "Install Svarog386", "Quit to DOS", NULL};
484
      char *list[] = { "Install SvarDOS", "Quit to DOS", NULL};
487
      list[0] = kittengets(0, 1, list[0]);
485
      list[0] = kittengets(0, 1, list[0]);
488
      list[1] = kittengets(0, 2, list[1]);
486
      list[1] = kittengets(0, 2, list[1]);
489
      snprintf(buff, sizeof(buff), kittengets(3, 6, "The installation of Svarog386 to %c: is about to begin."), cselecteddrive);
487
      snprintf(buff, sizeof(buff), kittengets(3, 6, "The installation of SvarDOS to %c: is about to begin."), cselecteddrive);
490
      video_putstring(7, -1, COLOR_BODY[mono], buff, -1);
488
      video_putstring(7, -1, COLOR_BODY[mono], buff, -1);
491
      choice = menuselect(10, -1, 4, list, -1);
489
      choice = menuselect(10, -1, 4, list, -1);
492
      if (choice < 0) return(MENUPREV);
490
      if (choice < 0) return(MENUPREV);
493
      if (choice == 1) return(MENUQUIT);
491
      if (choice == 1) return(MENUQUIT);
494
      snprintf(buff, sizeof(buff), "SYS A: %c: > NUL", cselecteddrive);
492
      snprintf(buff, sizeof(buff), "SYS A: %c: > NUL", cselecteddrive);
495
      system(buff);
493
      system(buff);
496
      system("FDISK /MBR");
494
      system("FDISK /MBR");
497
      snprintf(buff, sizeof(buff), "%c:\\TEMP", cselecteddrive);
495
      snprintf(buff, sizeof(buff), "%c:\\TEMP", cselecteddrive);
498
      mkdir(buff);
496
      mkdir(buff);
499
      return(cselecteddrive);
497
      return(cselecteddrive);
500
    }
498
    }
501
  }
499
  }
502
}
500
}
503
 
501
 
504
 
502
 
505
/* copy file src into dst, substituting all characters c1 by c2 */
503
/* copy file src into dst, substituting all characters c1 by c2 */
506
static void fcopysub(char *dst, char *src, char c1, char c2) {
504
static void fcopysub(char *dst, char *src, char c1, char c2) {
507
  FILE *fdd, *fds;
505
  FILE *fdd, *fds;
508
  int buff;
506
  int buff;
509
  fds = fopen(src, "rb");
507
  fds = fopen(src, "rb");
510
  if (fds == NULL) return;
508
  if (fds == NULL) return;
511
  fdd = fopen(dst, "wb");
509
  fdd = fopen(dst, "wb");
512
  if (fdd == NULL) {
510
  if (fdd == NULL) {
513
    fclose(fds);
511
    fclose(fds);
514
    return;
512
    return;
515
  }
513
  }
516
  /* */
514
  /* */
517
  for (;;) {
515
  for (;;) {
518
    buff = fgetc(fds);
516
    buff = fgetc(fds);
519
    if (buff == EOF) break;
517
    if (buff == EOF) break;
520
    if (buff == c1) buff = c2;
518
    if (buff == c1) buff = c2;
521
    fprintf(fdd, "%c", buff);
519
    fprintf(fdd, "%c", buff);
522
  }
520
  }
523
  /* close files and return */
521
  /* close files and return */
524
  fclose(fdd);
522
  fclose(fdd);
525
  fclose(fds);
523
  fclose(fds);
526
}
524
}
527
 
525
 
528
 
526
 
529
static void bootfilesgen(int targetdrv, struct slocales *locales, int cdromdrv) {
527
static void bootfilesgen(int targetdrv, struct slocales *locales, int cdromdrv) {
530
  char buff[128];
528
  char buff[128];
531
  char buff2[16];
529
  char buff2[16];
532
  char buff3[16];
530
  char buff3[16];
533
  FILE *fd;
531
  FILE *fd;
534
  /*** CONFIG.SYS ***/
532
  /*** CONFIG.SYS ***/
535
  snprintf(buff, sizeof(buff), "%c:\\CONFIG.SYS", targetdrv);
533
  snprintf(buff, sizeof(buff), "%c:\\CONFIG.SYS", targetdrv);
536
  fd = fopen(buff, "wb");
534
  fd = fopen(buff, "wb");
537
  if (fd == NULL) return;
535
  if (fd == NULL) return;
538
  fprintf(fd, "DOS=UMB,HIGH\r\n"
536
  fprintf(fd, "DOS=UMB,HIGH\r\n"
539
              "LASTDRIVE=Z\r\n"
537
              "LASTDRIVE=Z\r\n"
540
              "FILES=50\r\n");
538
              "FILES=50\r\n");
541
  fprintf(fd, "DEVICE=%c:\\SYSTEM\\SVAROG.386\\BIN\\HIMEMX.EXE\r\n", targetdrv);
539
  fprintf(fd, "DEVICE=%c:\\SYSTEM\\SVARDOS\\BIN\\HIMEMX.EXE\r\n", targetdrv);
542
  if (strcmp(locales->lang, "EN") == 0) {
540
  if (strcmp(locales->lang, "EN") == 0) {
543
    strcpy(buff, "COMMAND");
541
    strcpy(buff, "COMMAND");
544
  } else {
542
  } else {
545
    snprintf(buff, sizeof(buff), "CMD-%s", locales->lang);
543
    snprintf(buff, sizeof(buff), "CMD-%s", locales->lang);
546
  }
544
  }
547
  fprintf(fd, "SHELLHIGH=%c:\\SYSTEM\\SVAROG.386\\BIN\\%s.COM /E:512 /P\r\n", targetdrv, buff);
545
  fprintf(fd, "SHELLHIGH=%c:\\SYSTEM\\SVARDOS\\BIN\\%s.COM /E:512 /P\r\n", targetdrv, buff);
548
  fprintf(fd, "REM COUNTRY=001,437,%c:\\SYSTEM\\CONF\\COUNTRY.SYS\r\n", targetdrv);
546
  fprintf(fd, "REM COUNTRY=001,437,%c:\\SYSTEM\\CONF\\COUNTRY.SYS\r\n", targetdrv);
549
  fprintf(fd, "DEVICE=%c:\\SYSTEM\\DRIVERS\\UDVD2\\UDVD2.SYS /D:SVCD0001 /H\r\n", targetdrv);
547
  fprintf(fd, "DEVICE=%c:\\SYSTEM\\DRIVERS\\UDVD2\\UDVD2.SYS /D:SVCD0001 /H\r\n", targetdrv);
550
  fclose(fd);
548
  fclose(fd);
551
  /*** AUTOEXEC.BAT ***/
549
  /*** AUTOEXEC.BAT ***/
552
  snprintf(buff, sizeof(buff), "%c:\\AUTOEXEC.BAT", targetdrv);
550
  snprintf(buff, sizeof(buff), "%c:\\AUTOEXEC.BAT", targetdrv);
553
  fd = fopen(buff, "wb");
551
  fd = fopen(buff, "wb");
554
  if (fd == NULL) return;
552
  if (fd == NULL) return;
555
  fprintf(fd, "@ECHO OFF\r\n");
553
  fprintf(fd, "@ECHO OFF\r\n");
556
  fprintf(fd, "SET TEMP=%c:\\TEMP\r\n", targetdrv);
554
  fprintf(fd, "SET TEMP=%c:\\TEMP\r\n", targetdrv);
557
  fprintf(fd, "SET DOSDIR=%c:\\SYSTEM\\SVAROG.386\r\n", targetdrv);
555
  fprintf(fd, "SET DOSDIR=%c:\\SYSTEM\\SVARDOS\r\n", targetdrv);
558
  fprintf(fd, "SET NLSPATH=%%DOSDIR%%\\NLS\r\n");
556
  fprintf(fd, "SET NLSPATH=%%DOSDIR%%\\NLS\r\n");
559
  fprintf(fd, "SET LANG=%s\r\n", locales->lang);
557
  fprintf(fd, "SET LANG=%s\r\n", locales->lang);
560
  fprintf(fd, "SET DIRCMD=/OGNE/P/4\r\n");
558
  fprintf(fd, "SET DIRCMD=/OGNE/P/4\r\n");
561
  fprintf(fd, "SET FDNPKG.CFG=%c:\\SYSTEM\\CFG\\FDNPKG.CFG\r\n", targetdrv);
559
  fprintf(fd, "SET FDNPKG.CFG=%c:\\SYSTEM\\CFG\\FDNPKG.CFG\r\n", targetdrv);
562
  fprintf(fd, "SET WATTCP.CFG=%c:\\SYSTEM\\CFG\\WATTCP.CFG\r\n", targetdrv);
560
  fprintf(fd, "SET WATTCP.CFG=%c:\\SYSTEM\\CFG\\WATTCP.CFG\r\n", targetdrv);
563
  fprintf(fd, "PATH %%DOSDIR%%\\BIN;%c:\\SYSTEM\\LINKS\r\n", targetdrv);
561
  fprintf(fd, "PATH %%DOSDIR%%\\BIN;%c:\\SYSTEM\\LINKS\r\n", targetdrv);
564
  fprintf(fd, "PROMPT $P$G\r\n");
562
  fprintf(fd, "PROMPT $P$G\r\n");
565
  fprintf(fd, "ALIAS REBOOT=FDAPM COLDBOOT\r\n");
563
  fprintf(fd, "ALIAS REBOOT=FDAPM COLDBOOT\r\n");
566
  fprintf(fd, "ALIAS HALT=FDAPM POWEROFF\r\n");
564
  fprintf(fd, "ALIAS HALT=FDAPM POWEROFF\r\n");
567
  fprintf(fd, "FDAPM APMDOS\r\n");
565
  fprintf(fd, "FDAPM APMDOS\r\n");
568
  fprintf(fd, "\r\n");
566
  fprintf(fd, "\r\n");
569
  if (locales->egafile > 0) {
567
  if (locales->egafile > 0) {
570
    fprintf(fd, "DISPLAY CON=(EGA,,1)\r\n");
568
    fprintf(fd, "DISPLAY CON=(EGA,,1)\r\n");
571
    if (locales->egafile == 1) {
569
    if (locales->egafile == 1) {
572
      fprintf(fd, "MODE CON CP PREPARE=((%u) %c:\\SYSTEM\\SVAROG.386\\CPI\\EGA.CPX)\r\n", locales->codepage, targetdrv);
570
      fprintf(fd, "MODE CON CP PREPARE=((%u) %c:\\SYSTEM\\SVARDOS\\CPI\\EGA.CPX)\r\n", locales->codepage, targetdrv);
573
    } else {
571
    } else {
574
      fprintf(fd, "MODE CON CP PREPARE=((%u) %c:\\SYSTEM\\SVAROG.386\\CPI\\EGA%d.CPX)\r\n", locales->codepage, targetdrv, locales->egafile);
572
      fprintf(fd, "MODE CON CP PREPARE=((%u) %c:\\SYSTEM\\SVARDOS\\CPI\\EGA%d.CPX)\r\n", locales->codepage, targetdrv, locales->egafile);
575
    }
573
    }
576
    fprintf(fd, "MODE CON CP SELECT=%u\r\n", locales->codepage);
574
    fprintf(fd, "MODE CON CP SELECT=%u\r\n", locales->codepage);
577
  }
575
  }
578
  if (locales->keybfile > 0) {
576
  if (locales->keybfile > 0) {
579
    if (locales->keybfile == 1) {
577
    if (locales->keybfile == 1) {
580
      snprintf(buff2, sizeof(buff2), "KEYBOARD.SYS");
578
      snprintf(buff2, sizeof(buff2), "KEYBOARD.SYS");
581
    } else {
579
    } else {
582
      snprintf(buff2, sizeof(buff2), "KEYBRD%d.SYS", locales->keybfile);
580
      snprintf(buff2, sizeof(buff2), "KEYBRD%d.SYS", locales->keybfile);
583
    }
581
    }
584
    if (locales->keybid == 0) {
582
    if (locales->keybid == 0) {
585
      buff3[0] = 0;
583
      buff3[0] = 0;
586
    } else {
584
    } else {
587
      snprintf(buff3, sizeof(buff3), " /ID:%d", locales->keybid);
585
      snprintf(buff3, sizeof(buff3), " /ID:%d", locales->keybid);
588
    }
586
    }
589
    fprintf(fd, "KEYB %s,%d,%c:\\SYSTEM\\SVAROG.386\\BIN\\%s%s\r\n", locales->keybcode, locales->codepage, targetdrv, buff2, buff3);
587
    fprintf(fd, "KEYB %s,%d,%c:\\SYSTEM\\SVARDOS\\BIN\\%s%s\r\n", locales->keybcode, locales->codepage, targetdrv, buff2, buff3);
590
    fprintf(fd, "\r\n");
588
    fprintf(fd, "\r\n");
591
  }
589
  }
592
  fprintf(fd, "SHSUCDX /d:SVCD0001\r\n");
590
  fprintf(fd, "SHSUCDX /d:SVCD0001\r\n");
593
  fprintf(fd, "\r\n");
591
  fprintf(fd, "\r\n");
594
  fprintf(fd, "REM Uncomment the line below for automatic mouse support\r\n");
592
  fprintf(fd, "REM Uncomment the line below for automatic mouse support\r\n");
595
  fprintf(fd, "REM CTMOUSE\r\n");
593
  fprintf(fd, "REM CTMOUSE\r\n");
596
  fprintf(fd, "\r\n");
594
  fprintf(fd, "\r\n");
597
  fprintf(fd, "ECHO.\r\n");
595
  fprintf(fd, "ECHO.\r\n");
598
  fprintf(fd, "ECHO %s\r\n", kittengets(6, 0, "Welcome to Svarog386! Type 'HELP' if you need help."));
596
  fprintf(fd, "ECHO %s\r\n", kittengets(6, 0, "Welcome to SvarDOS! Type 'HELP' if you need help."));
599
  fclose(fd);
597
  fclose(fd);
600
  /*** CREATE DIRECTORY FOR OTHER CONFIGURATION FILES ***/
598
  /*** CREATE DIRECTORY FOR OTHER CONFIGURATION FILES ***/
601
  snprintf(buff, sizeof(buff), "%c:\\SYSTEM\\CFG", targetdrv);
599
  snprintf(buff, sizeof(buff), "%c:\\SYSTEM\\CFG", targetdrv);
602
  mkdir(buff);
600
  mkdir(buff);
603
  /*** FDNPKG.CFG ***/
601
  /*** FDNPKG.CFG ***/
604
  snprintf(buff, sizeof(buff), "%c:\\SYSTEM\\CFG\\FDNPKG.CFG", targetdrv);
602
  snprintf(buff, sizeof(buff), "%c:\\SYSTEM\\CFG\\FDNPKG.CFG", targetdrv);
605
  fcopysub(buff, "A:\\DAT\\FDNPKG.CFG", '$', cdromdrv);
603
  fcopysub(buff, "A:\\DAT\\FDNPKG.CFG", '$', cdromdrv);
606
  /*** COUNTRY.SYS ***/
604
  /*** COUNTRY.SYS ***/
607
  /*** PICOTCP ***/
605
  /*** PICOTCP ***/
608
  /*** WATTCP ***/
606
  /*** WATTCP ***/
609
}
607
}
610
 
608
 
611
 
609
 
612
static void installpackages(int targetdrv, int cdromdrv) {
610
static void installpackages(int targetdrv, int cdromdrv) {
613
  char *pkglist[] = {
611
  char *pkglist[] = {
614
    "A:\\UDVD2", /* this one's not part of CORE, hence it's stored right on the floppy */
612
    "A:\\UDVD2", /* this one's not part of CORE, hence it's stored right on the floppy */
615
    "APPEND",
613
    "APPEND",
616
    "ASSIGN",
614
    "ASSIGN",
617
    "ATTRIB",
615
    "ATTRIB",
618
    "CHKDSK",
616
    "CHKDSK",
619
    "CHOICE",
617
    "CHOICE",
620
    "COMMAND",
618
    "COMMAND",
621
    "COMP",
619
    "COMP",
622
    "CPIDOS",
620
    "CPIDOS",
623
    "CTMOUSE",
621
    "CTMOUSE",
624
    "DEBUG",
622
    "DEBUG",
625
    "DEFRAG",
623
    "DEFRAG",
626
    "DELTREE",
624
    "DELTREE",
627
    "DEVLOAD",
625
    "DEVLOAD",
628
    "DISKCOMP",
626
    "DISKCOMP",
629
    "DISKCOPY",
627
    "DISKCOPY",
630
    "DISPLAY",
628
    "DISPLAY",
631
    "DOSFSCK",
629
    "DOSFSCK",
632
    "EDIT",
630
    "EDIT",
633
    "EDLIN",
631
    "EDLIN",
634
    "EXE2BIN",
632
    "EXE2BIN",
635
    "FC",
633
    "FC",
636
    "FDAPM",
634
    "FDAPM",
637
    "FDISK",
635
    "FDISK",
638
    "FDNPKG",
636
    "FDNPKG",
639
    "FIND",
637
    "FIND",
640
    "FORMAT",
638
    "FORMAT",
641
    "HELP",
639
    "HELP",
642
    "HIMEMX",
640
    "HIMEMX",
643
    "KERNEL",
641
    "KERNEL",
644
    "KEYB",
642
    "KEYB",
645
    "KEYB_LAY",
643
    "KEYB_LAY",
646
    "LABEL",
644
    "LABEL",
647
    "LBACACHE",
645
    "LBACACHE",
648
    "MEM",
646
    "MEM",
649
    "MIRROR",
647
    "MIRROR",
650
    "MODE",
648
    "MODE",
651
    "MORE",
649
    "MORE",
652
    "MOVE",
650
    "MOVE",
653
    "NANSI",
651
    "NANSI",
654
    "NLSFUNC",
652
    "NLSFUNC",
655
    "PRINT",
653
    "PRINT",
656
    "RDISK",
654
    "RDISK",
657
    "RECOVER",
655
    "RECOVER",
658
    "REPLACE",
656
    "REPLACE",
659
    "SHARE",
657
    "SHARE",
660
    "SHSUCDX",
658
    "SHSUCDX",
661
    "SORT",
659
    "SORT",
662
    "SWSUBST",
660
    "SWSUBST",
663
    "TREE",
661
    "TREE",
664
    "UNDELETE",
662
    "UNDELETE",
665
    "XCOPY",
663
    "XCOPY",
666
    NULL
664
    NULL
667
  };
665
  };
668
  int i, pkglistlen;
666
  int i, pkglistlen;
669
  char buff[64];
667
  char buff[64];
670
  newscreen(3);
668
  newscreen(3);
671
  /* count how long the pkg list is */
669
  /* count how long the pkg list is */
672
  for (pkglistlen = 0; pkglist[pkglistlen] != NULL; pkglistlen++);
670
  for (pkglistlen = 0; pkglist[pkglistlen] != NULL; pkglistlen++);
673
  /* set DOSDIR and friends */
671
  /* set DOSDIR and friends */
674
  snprintf(buff, sizeof(buff), "%c:\\SYSTEM\\SVAROG.386", targetdrv);
672
  snprintf(buff, sizeof(buff), "%c:\\SYSTEM\\SVARDOS", targetdrv);
675
  setenv("DOSDIR", buff, 1);
673
  setenv("DOSDIR", buff, 1);
676
  snprintf(buff, sizeof(buff), "%c:\\TEMP", targetdrv);
674
  snprintf(buff, sizeof(buff), "%c:\\TEMP", targetdrv);
677
  setenv("TEMP", buff, 1);
675
  setenv("TEMP", buff, 1);
678
  /* install packages */
676
  /* install packages */
679
  for (i = 0; pkglist[i] != NULL; i++) {
677
  for (i = 0; pkglist[i] != NULL; i++) {
680
    char buff[128];
678
    char buff[128];
681
    snprintf(buff, sizeof(buff), kittengets(4, 0, "Installing package %d/%d: %s"), i+1, pkglistlen, pkglist[i]);
679
    snprintf(buff, sizeof(buff), kittengets(4, 0, "Installing package %d/%d: %s"), i+1, pkglistlen, pkglist[i]);
682
    strcat(buff, "       ");
680
    strcat(buff, "       ");
683
    video_putstring(10, 1, COLOR_BODY[mono], buff, -1);
681
    video_putstring(10, 1, COLOR_BODY[mono], buff, -1);
684
    if (pkglist[i][1] == ':') {
682
    if (pkglist[i][1] == ':') {
685
      snprintf(buff, sizeof(buff), "FDINST INSTALL %s.ZIP > NUL", pkglist[i]);
683
      snprintf(buff, sizeof(buff), "FDINST INSTALL %s.ZIP > NUL", pkglist[i]);
686
    } else {
684
    } else {
687
      snprintf(buff, sizeof(buff), "FDINST INSTALL %c:\\CORE\\%s.ZIP > NUL", cdromdrv, pkglist[i]);
685
      snprintf(buff, sizeof(buff), "FDINST INSTALL %c:\\CORE\\%s.ZIP > NUL", cdromdrv, pkglist[i]);
688
    }
686
    }
689
    system(buff);
687
    system(buff);
690
  }
688
  }
691
}
689
}
692
 
690
 
693
 
691
 
694
static void finalreboot(void) {
692
static void finalreboot(void) {
695
  int y = 9;
693
  int y = 9;
696
  newscreen(2);
694
  newscreen(2);
697
  y += putstringnls(y, 1, COLOR_BODY[mono], 5, 0, "Svarog386 installation is over. Your computer will reboot now.\nPlease remove the installation disk from your drive.");
695
  y += putstringnls(y, 1, COLOR_BODY[mono], 5, 0, "SvarDOS installation is over. Your computer will reboot now.\nPlease remove the installation disk from your drive.");
698
  putstringnls(++y, 1, COLOR_BODY[mono], 0, 5, "Press any key...");
696
  putstringnls(++y, 1, COLOR_BODY[mono], 0, 5, "Press any key...");
699
  input_getkey();
697
  input_getkey();
700
  reboot();
698
  reboot();
701
}
699
}
702
 
700
 
703
 
701
 
704
static void loadcp(struct slocales *locales) {
702
static void loadcp(struct slocales *locales) {
705
  char buff[64];
703
  char buff[64];
706
  if (locales->codepage == 437) return;
704
  if (locales->codepage == 437) return;
707
  video_movecursor(1, 0);
705
  video_movecursor(1, 0);
708
  if (locales->egafile == 1) {
706
  if (locales->egafile == 1) {
709
    snprintf(buff, sizeof(buff), "MODE CON CP PREP=((%u) A:\\EGA.CPX) > NUL", locales->codepage);
707
    snprintf(buff, sizeof(buff), "MODE CON CP PREP=((%u) A:\\EGA.CPX) > NUL", locales->codepage);
710
  } else {
708
  } else {
711
    snprintf(buff, sizeof(buff), "MODE CON CP PREP=((%u) A:\\EGA%d.CPX) > NUL", locales->codepage, locales->egafile);
709
    snprintf(buff, sizeof(buff), "MODE CON CP PREP=((%u) A:\\EGA%d.CPX) > NUL", locales->codepage, locales->egafile);
712
  }
710
  }
713
  system(buff);
711
  system(buff);
714
  snprintf(buff, sizeof(buff), "MODE CON CP SEL=%u > NUL", locales->codepage);
712
  snprintf(buff, sizeof(buff), "MODE CON CP SEL=%u > NUL", locales->codepage);
715
  system(buff);
713
  system(buff);
716
  /* below I re-init the video controller - apparently this is required if
714
  /* below I re-init the video controller - apparently this is required if
717
   * I want the new glyph symbols to be actually applied, at least some
715
   * I want the new glyph symbols to be actually applied, at least some
718
   * (broken?) BIOSes, like VBox, apply glyphs only at next video mode change */
716
   * (broken?) BIOSes, like VBox, apply glyphs only at next video mode change */
719
  {
717
  {
720
  union REGS r;
718
  union REGS r;
721
  r.h.ah = 0x0F; /* get current video mode */
719
  r.h.ah = 0x0F; /* get current video mode */
722
  int86(0x10, &r, &r); /* r.h.al contains the current video mode now */
720
  int86(0x10, &r, &r); /* r.h.al contains the current video mode now */
723
  r.h.al |= 128; /* set the high bit of AL to instruct BIOS not to flush VRAM's content (EGA+) */
721
  r.h.al |= 128; /* set the high bit of AL to instruct BIOS not to flush VRAM's content (EGA+) */
724
  r.h.ah = 0; /* re-set video mode (to whatever is set in AL) */
722
  r.h.ah = 0; /* re-set video mode (to whatever is set in AL) */
725
  int86(0x10, &r, &r);
723
  int86(0x10, &r, &r);
726
  }
724
  }
727
}
725
}
728
 
726
 
729
/* checks CD drive drv for the presence of the Svarog386 install CD
727
/* checks CD drive drv for the presence of the SvarDOS install CD
730
 * returns 0 if found, non-zero otherwise */
728
 * returns 0 if found, non-zero otherwise */
731
static int checkcd(char drv) {
729
static int checkcd(char drv) {
732
  FILE *fd;
730
  FILE *fd;
733
  char fname[32];
731
  char fname[32];
734
  snprintf(fname, sizeof(fname), "%c:\\CORE\\MEM.ZIP", drv);
732
  snprintf(fname, sizeof(fname), "%c:\\CORE\\MEM.ZIP", drv);
735
  fd = fopen(fname, "rb");
733
  fd = fopen(fname, "rb");
736
  if (fd == NULL) return(-1);
734
  if (fd == NULL) return(-1);
737
  fclose(fd);
735
  fclose(fd);
738
  return(0);
736
  return(0);
739
}
737
}
740
 
738
 
741
 
739
 
742
int main(void) {
740
int main(void) {
743
  struct slocales locales;
741
  struct slocales locales;
744
  int targetdrv;
742
  int targetdrv;
745
  int cdromdrv;
743
  int cdromdrv;
746
  int action;
744
  int action;
747
 
745
 
748
  /* find where the cdrom drive is */
746
  /* find where the cdrom drive is */
749
  cdromdrv = cdrom_findfirst();
747
  cdromdrv = cdrom_findfirst();
750
  if (cdromdrv < 0) {
748
  if (cdromdrv < 0) {
751
    printf("ERROR: CD-ROM DRIVE NOT FOUND\r\n");
749
    printf("ERROR: CD-ROM DRIVE NOT FOUND\r\n");
752
    return(1);
750
    return(1);
753
  }
751
  }
754
  cdromdrv += 'A'; /* convert the cdrom 'id' (A=0) to an actual drive letter */
752
  cdromdrv += 'A'; /* convert the cdrom 'id' (A=0) to an actual drive letter */
755
  if (checkcd(cdromdrv) != 0) {
753
  if (checkcd(cdromdrv) != 0) {
756
    printf("ERROR: SVAROG386 INSTALLATION CD NOT FOUND IN THE DRIVE.\r\n");
754
    printf("ERROR: SVARDOS INSTALLATION CD NOT FOUND IN THE DRIVE.\r\n");
757
    return(1);
755
    return(1);
758
  }
756
  }
759
 
757
 
760
  /* init screen and detect mono status */
758
  /* init screen and detect mono status */
761
  mono = video_init();
759
  mono = video_init();
762
 
760
 
763
  kittenopen("INSTALL"); /* load initial NLS support */
761
  kittenopen("INSTALL"); /* load initial NLS support */
764
 
762
 
765
 SelectLang:
763
 SelectLang:
766
  action = selectlang(&locales); /* welcome to svarog, select your language */
764
  action = selectlang(&locales); /* welcome to svardos, select your language */
767
  if (action != MENUNEXT) goto Quit;
765
  if (action != MENUNEXT) goto Quit;
768
  setenv("LANG", locales.lang, 1);
766
  setenv("LANG", locales.lang, 1);
769
  loadcp(&locales);
767
  loadcp(&locales);
770
  kittenclose(); /* reload NLS with new language */
768
  kittenclose(); /* reload NLS with new language */
771
  kittenopen("INSTALL"); /* NLS support */
769
  kittenopen("INSTALL"); /* NLS support */
772
  action = selectkeyb(&locales);  /* what keyb layout should we use? */
770
  action = selectkeyb(&locales);  /* what keyb layout should we use? */
773
  if (action == MENUQUIT) goto Quit;
771
  if (action == MENUQUIT) goto Quit;
774
  if (action == MENUPREV) goto SelectLang;
772
  if (action == MENUPREV) goto SelectLang;
775
 
773
 
776
 WelcomeScreen:
774
 WelcomeScreen:
777
  action = welcomescreen(); /* what svarog386 is, ask whether to run live dos or install */
775
  action = welcomescreen(); /* what svardos is, ask whether to run live dos or install */
778
  if (action == MENUQUIT) goto Quit;
776
  if (action == MENUQUIT) goto Quit;
779
  if (action == MENUPREV) goto SelectLang;
777
  if (action == MENUPREV) goto SelectLang;
780
  targetdrv = preparedrive(); /* what drive should we install to? check avail. space */
778
  targetdrv = preparedrive(); /* what drive should we install to? check avail. space */
781
  if (targetdrv == MENUQUIT) goto Quit;
779
  if (targetdrv == MENUQUIT) goto Quit;
782
  if (targetdrv == MENUPREV) goto WelcomeScreen;
780
  if (targetdrv == MENUPREV) goto WelcomeScreen;
783
  /*askaboutsources();*/ /* IF sources are available, ask if installing with them */
781
  /*askaboutsources();*/ /* IF sources are available, ask if installing with them */
784
  installpackages(targetdrv, cdromdrv);    /* install packages */
782
  installpackages(targetdrv, cdromdrv);    /* install packages */
785
  bootfilesgen(targetdrv, &locales, cdromdrv); /* generate boot files and other configurations */
783
  bootfilesgen(targetdrv, &locales, cdromdrv); /* generate boot files and other configurations */
786
  /*localcfg();*/ /* show local params (currency, etc), and propose to change them (based on localcfg) */
784
  /*localcfg();*/ /* show local params (currency, etc), and propose to change them (based on localcfg) */
787
  /*netcfg();*/ /* basic networking config */
785
  /*netcfg();*/ /* basic networking config */
788
  finalreboot(); /* remove the CD and reboot */
786
  finalreboot(); /* remove the CD and reboot */
789
 
787
 
790
 Quit:
788
 Quit:
791
  kittenclose(); /* close NLS support */
789
  kittenclose(); /* close NLS support */
792
  video_clear(0x0700, 0, 0);
790
  video_clear(0x0700, 0, 0);
793
  video_movecursor(0, 0);
791
  video_movecursor(0, 0);
794
  return(0);
792
  return(0);
795
}
793
}
796
 
794