Subversion Repositories SvarDOS

Rev

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

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