Subversion Repositories SvarDOS

Rev

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

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