Subversion Repositories SvarDOS

Rev

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

Rev 277 Rev 280
1
/*
1
/*
2
 * SVARDOS INSTALL PROGRAM
2
 * SVARDOS INSTALL PROGRAM
3
 * Copyright (C) 2021 Mateusz Viste
3
 * Copyright (C) 2021 Mateusz Viste
4
 *
4
 *
5
 * PUBLISHED UNDER THE TERMS OF THE MIT LICENSE
5
 * PUBLISHED UNDER THE TERMS OF THE MIT LICENSE
6
 *
6
 *
7
 * COPYRIGHT (C) 2016-2021 MATEUSZ VISTE, ALL RIGHTS RESERVED.
7
 * COPYRIGHT (C) 2016-2021 MATEUSZ VISTE, ALL RIGHTS RESERVED.
8
 *
8
 *
9
 * Permission is hereby granted, free of charge, to any person obtaining a
9
 * Permission is hereby granted, free of charge, to any person obtaining a
10
 * copy of this software and associated documentation files (the "Software"),
10
 * copy of this software and associated documentation files (the "Software"),
11
 * to deal in the Software without restriction, including without limitation
11
 * to deal in the Software without restriction, including without limitation
12
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
12
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
13
 * and/or sell copies of the Software, and to permit persons to whom the
13
 * and/or sell copies of the Software, and to permit persons to whom the
14
 * Software is furnished to do so, subject to the following conditions:
14
 * Software is furnished to do so, subject to the following conditions:
15
 *
15
 *
16
 * The above copyright notice and this permission notice shall be included in
16
 * The above copyright notice and this permission notice shall be included in
17
 * all copies or substantial portions of the Software.
17
 * all copies or substantial portions of the Software.
18
 *
18
 *
19
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
23
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
24
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
24
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
25
 * DEALINGS IN THE SOFTWARE.
25
 * DEALINGS IN THE SOFTWARE.
26
 *
26
 *
27
 * http://svardos.osdn.io
27
 * http://svardos.osdn.io
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 SvarDOS require (in MiB) */
56
/* how much disk space does SvarDOS require (in MiB) */
57
#define SVARDOS_DISK_REQ 8
57
#define SVARDOS_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
/* copy file f1 to f2 using buff as a buffer of buffsz bytes. f2 will be overwritten if it
-
 
125
 * exists already! returns 0 on success. */
-
 
126
static int fcopy(const char *f2, const char *f1, void *buff, size_t buffsz) {
-
 
127
  FILE *fd1, *fd2;
-
 
128
  size_t sz;
-
 
129
  int res = -1; /* assume failure */
-
 
130
 
-
 
131
  /* open files */
-
 
132
  fd1 = fopen(f1, "rb");
-
 
133
  fd2 = fopen(f2, "wb");
-
 
134
  if ((fd1 == NULL) || (fd2 == NULL)) goto QUIT;
-
 
135
 
-
 
136
  /* copy data */
-
 
137
  for (;;) {
-
 
138
    sz = fread(buff, 1, buffsz, fd1);
-
 
139
    if (sz == 0) {
-
 
140
      if (feof(fd1) != 0) break;
-
 
141
      goto QUIT;
-
 
142
    }
-
 
143
    if (fwrite(buff, 1, sz, fd2) != sz) goto QUIT;
-
 
144
  }
-
 
145
 
-
 
146
  res = 0; /* success */
-
 
147
 
-
 
148
  QUIT:
-
 
149
  if (fd1 != NULL) fclose(fd1);
-
 
150
  if (fd2 != NULL) fclose(fd2);
-
 
151
  return(res);
-
 
152
}
-
 
153
 
-
 
154
 
124
static int menuselect(int ypos, int xpos, int height, char **list, int listlen) {
155
static int menuselect(int ypos, int xpos, int height, char **list, int listlen) {
125
  int i, offset = 0, res = 0, count, width = 0;
156
  int i, offset = 0, res = 0, count, width = 0;
126
  /* count how many positions there is, and check their width */
157
  /* count how many positions there is, and check their width */
127
  for (count = 0; (list[count] != NULL) && (count != listlen); count++) {
158
  for (count = 0; (list[count] != NULL) && (count != listlen); count++) {
128
    int len = strlen(list[count]);
159
    int len = strlen(list[count]);
129
    if (len > width) width = len;
160
    if (len > width) width = len;
130
  }
161
  }
131
 
162
 
132
  /* if xpos negative, means 'center out' */
163
  /* if xpos negative, means 'center out' */
133
  if (xpos < 0) xpos = 39 - (width >> 1);
164
  if (xpos < 0) xpos = 39 - (width >> 1);
134
 
165
 
135
  video_putchar(ypos, xpos+width+2, COLOR_SELECT[mono], 0xBF);         /*       \ */
166
  video_putchar(ypos, xpos+width+2, COLOR_SELECT[mono], 0xBF);         /*       \ */
136
  video_putchar(ypos, xpos-1, COLOR_SELECT[mono], 0xDA);               /*  /      */
167
  video_putchar(ypos, xpos-1, COLOR_SELECT[mono], 0xDA);               /*  /      */
137
  video_putchar(ypos+height-1, xpos-1, COLOR_SELECT[mono], 0xC0);      /*  \      */
168
  video_putchar(ypos+height-1, xpos-1, COLOR_SELECT[mono], 0xC0);      /*  \      */
138
  video_putchar(ypos+height-1, xpos+width+2, COLOR_SELECT[mono], 0xD9);/*      /  */
169
  video_putchar(ypos+height-1, xpos+width+2, COLOR_SELECT[mono], 0xD9);/*      /  */
139
  video_putcharmulti(ypos, xpos, COLOR_SELECT[mono], 0xC4, width + 2, 1);
170
  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);
171
  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);
172
  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);
173
  video_putcharmulti(ypos+1, xpos+width+2, COLOR_SELECT[mono], 0xB3, height - 2, 80);
143
 
174
 
144
  for (;;) {
175
  for (;;) {
145
    int key;
176
    int key;
146
    /* list of selectable items */
177
    /* list of selectable items */
147
    for (i = 0; i < height - 2; i++) {
178
    for (i = 0; i < height - 2; i++) {
148
      if (i + offset == res) {
179
      if (i + offset == res) {
149
        video_putchar(ypos + 1 + i, xpos, COLOR_SELECTCUR[mono], 16);
180
        video_putchar(ypos + 1 + i, xpos, COLOR_SELECTCUR[mono], 16);
150
        video_putchar(ypos + 1 + i, xpos+width+1, COLOR_SELECTCUR[mono], 17);
181
        video_putchar(ypos + 1 + i, xpos+width+1, COLOR_SELECTCUR[mono], 17);
151
        video_movecursor(ypos + 1 + i, xpos);
182
        video_movecursor(ypos + 1 + i, xpos);
152
        video_putstringfix(ypos + 1 + i, xpos+1, COLOR_SELECTCUR[mono], list[i + offset], width);
183
        video_putstringfix(ypos + 1 + i, xpos+1, COLOR_SELECTCUR[mono], list[i + offset], width);
153
      } else if (i + offset < count) {
184
      } else if (i + offset < count) {
154
        video_putchar(ypos + 1 + i, xpos, COLOR_SELECT[mono], ' ');
185
        video_putchar(ypos + 1 + i, xpos, COLOR_SELECT[mono], ' ');
155
        video_putchar(ypos + 1 + i, xpos+width+1, COLOR_SELECT[mono], ' ');
186
        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);
187
        video_putstringfix(ypos + 1 + i, xpos+1, COLOR_SELECT[mono], list[i + offset], width);
157
      } else {
188
      } else {
158
        video_putcharmulti(ypos + 1 + i, xpos, COLOR_SELECT[mono], ' ', width+2, 1);
189
        video_putcharmulti(ypos + 1 + i, xpos, COLOR_SELECT[mono], ' ', width+2, 1);
159
      }
190
      }
160
    }
191
    }
161
    key = input_getkey();
192
    key = input_getkey();
162
    if (key == 0x0D) { /* ENTER */
193
    if (key == 0x0D) { /* ENTER */
163
      return(res);
194
      return(res);
164
    } else if (key == 0x148) { /* up */
195
    } else if (key == 0x148) { /* up */
165
      if (res > 0) {
196
      if (res > 0) {
166
        res--;
197
        res--;
167
        if (res < offset) offset = res;
198
        if (res < offset) offset = res;
168
      }
199
      }
169
    } else if (key == 0x150) { /* down */
200
    } else if (key == 0x150) { /* down */
170
      if (res+1 < count) {
201
      if (res+1 < count) {
171
        res++;
202
        res++;
172
        if (res > offset + height - 3) offset = res - (height - 3);
203
        if (res > offset + height - 3) offset = res - (height - 3);
173
      }
204
      }
174
    } else if (key == 0x147) { /* home */
205
    } else if (key == 0x147) { /* home */
175
      res = 0;
206
      res = 0;
176
      offset = 0;
207
      offset = 0;
177
    } else if (key == 0x14F) { /* end */
208
    } else if (key == 0x14F) { /* end */
178
      res = count - 1;
209
      res = count - 1;
179
      if (res > offset + height - 3) offset = res - (height - 3);
210
      if (res > offset + height - 3) offset = res - (height - 3);
180
    } else if (key == 0x1B) {  /* ESC */
211
    } else if (key == 0x1B) {  /* ESC */
181
      return(-1);
212
      return(-1);
182
    }/* else {
213
    }/* else {
183
      char buf[8];
214
      char buf[8];
184
      snprintf(buf, sizeof(buf), "0x%02X ", key);
215
      snprintf(buf, sizeof(buf), "0x%02X ", key);
185
      video_putstring(1, 0, COLOR_BODY[mono], buf, -1);
216
      video_putstring(1, 0, COLOR_BODY[mono], buf, -1);
186
    }*/
217
    }*/
187
  }
218
  }
188
}
219
}
189
 
220
 
190
static void newscreen(int statusbartype) {
221
static void newscreen(int statusbartype) {
191
  char *msg;
222
  char *msg;
192
  msg = kittengets(0, 0, "SVARDOS INSTALLATION");
223
  msg = kittengets(0, 0, "SVARDOS INSTALLATION");
193
  video_putcharmulti(0, 0, COLOR_TITLEBAR[mono], ' ', 80, 1);
224
  video_putcharmulti(0, 0, COLOR_TITLEBAR[mono], ' ', 80, 1);
194
  video_putstring(0, 40 - (strlen(msg) >> 1), COLOR_TITLEBAR[mono], msg, -1);
225
  video_putstring(0, 40 - (strlen(msg) >> 1), COLOR_TITLEBAR[mono], msg, -1);
195
  video_clear(COLOR_BODY[mono], 80, -80);
226
  video_clear(COLOR_BODY[mono], 80, -80);
196
  switch (statusbartype) {
227
  switch (statusbartype) {
197
    case 1:
228
    case 1:
198
      msg = kittengets(0, 11, "Up/Down = Select entry | Enter = Validate your choice | ESC = Quit to DOS");
229
      msg = kittengets(0, 11, "Up/Down = Select entry | Enter = Validate your choice | ESC = Quit to DOS");
199
      break;
230
      break;
200
    case 2:
231
    case 2:
201
      msg = kittengets(0, 5, "Press any key...");
232
      msg = kittengets(0, 5, "Press any key...");
202
      break;
233
      break;
203
    case 3:
234
    case 3:
204
      msg = "";
235
      msg = "";
205
      break;
236
      break;
206
    default:
237
    default:
207
      msg = kittengets(0, 10, "Up/Down = Select entry | Enter = Validate your choice | ESC = Previous screen");
238
      msg = kittengets(0, 10, "Up/Down = Select entry | Enter = Validate your choice | ESC = Previous screen");
208
      break;
239
      break;
209
  }
240
  }
210
  video_putchar(24, 0, COLOR_TITLEBAR[mono], ' ');
241
  video_putchar(24, 0, COLOR_TITLEBAR[mono], ' ');
211
  video_putstringfix(24, 1, COLOR_TITLEBAR[mono], msg, 79);
242
  video_putstringfix(24, 1, COLOR_TITLEBAR[mono], msg, 79);
212
  video_movecursor(25,0);
243
  video_movecursor(25,0);
213
}
244
}
214
 
245
 
215
/* fills a slocales struct accordingly to the value of its keyboff member */
246
/* fills a slocales struct accordingly to the value of its keyboff member */
216
static void kblay2slocal(struct slocales *locales) {
247
static void kblay2slocal(struct slocales *locales) {
217
  char *m;
248
  char *m;
218
  for (m = kblayouts[locales->keyboff]; *m != 0; m++); /* skip layout name */
249
  for (m = kblayouts[locales->keyboff]; *m != 0; m++); /* skip layout name */
219
  m++;
250
  m++;
220
  /* skip keyb code and copy it to locales.keybcode */
251
  /* skip keyb code and copy it to locales.keybcode */
221
  locales->keybcode = m;
252
  locales->keybcode = m;
222
  for (; *m != 0; m++);
253
  for (; *m != 0; m++);
223
  /* */
254
  /* */
224
  locales->codepage = ((unsigned short)m[1] << 8) | m[2];
255
  locales->codepage = ((unsigned short)m[1] << 8) | m[2];
225
  locales->egafile = m[3];
256
  locales->egafile = m[3];
226
  locales->keybfile = m[4];
257
  locales->keybfile = m[4];
227
  locales->keybid = ((unsigned short)m[5] << 8) | m[6];
258
  locales->keybid = ((unsigned short)m[5] << 8) | m[6];
228
}
259
}
229
 
260
 
230
static int selectlang(struct slocales *locales) {
261
static int selectlang(struct slocales *locales) {
231
  int choice, x;
262
  int choice, x;
232
  char *msg;
263
  char *msg;
233
  char *langlist[] = {
264
  char *langlist[] = {
234
    "English",
265
    "English",
235
    "French",
266
    "French",
236
    "German",
267
    "German",
237
    "Italian",
268
    "Italian",
238
    "Polish",
269
    "Polish",
239
    "Russian",
270
    "Russian",
240
    "Slovene",
271
    "Slovene",
241
    "Swedish",
272
    "Swedish",
242
    "Turkish",
273
    "Turkish",
243
    NULL
274
    NULL
244
  };
275
  };
245
 
276
 
246
  newscreen(1);
277
  newscreen(1);
247
  msg = kittengets(1, 0, "Welcome to SvarDOS");
278
  msg = kittengets(1, 0, "Welcome to SvarDOS");
248
  x = 40 - (strlen(msg) >> 1);
279
  x = 40 - (strlen(msg) >> 1);
249
  video_putstring(4, x, COLOR_BODY[mono], msg, -1);
280
  video_putstring(4, x, COLOR_BODY[mono], msg, -1);
250
  video_putcharmulti(5, x, COLOR_BODY[mono], '=', strlen(msg), 1);
281
  video_putcharmulti(5, x, COLOR_BODY[mono], '=', strlen(msg), 1);
251
  putstringnls(8, -1, COLOR_BODY[mono], 1, 1, "Please select your language from the list below:");
282
  putstringnls(8, -1, COLOR_BODY[mono], 1, 1, "Please select your language from the list below:");
252
  choice = menuselect(11, -1, 11, langlist, -1);
283
  choice = menuselect(11, -1, 11, langlist, -1);
253
  if (choice < 0) return(MENUPREV);
284
  if (choice < 0) return(MENUPREV);
254
  /* populate locales with default values */
285
  /* populate locales with default values */
255
  memset(locales, 0, sizeof(struct slocales));
286
  memset(locales, 0, sizeof(struct slocales));
256
  switch (choice) {
287
  switch (choice) {
257
    case 1:
288
    case 1:
258
      strcpy(locales->lang, "FR");
289
      strcpy(locales->lang, "FR");
259
      locales->keyboff = OFFLOC_FR;
290
      locales->keyboff = OFFLOC_FR;
260
      locales->keyblen = OFFLEN_FR;
291
      locales->keyblen = OFFLEN_FR;
261
      break;
292
      break;
262
    case 2:
293
    case 2:
263
      strcpy(locales->lang, "DE");
294
      strcpy(locales->lang, "DE");
264
      locales->keyboff = OFFLOC_DE;
295
      locales->keyboff = OFFLOC_DE;
265
      locales->keyblen = OFFLEN_DE;
296
      locales->keyblen = OFFLEN_DE;
266
      break;
297
      break;
267
    case 3:
298
    case 3:
268
      strcpy(locales->lang, "IT");
299
      strcpy(locales->lang, "IT");
269
      locales->keyboff = OFFLOC_IT;
300
      locales->keyboff = OFFLOC_IT;
270
      locales->keyblen = OFFLEN_IT;
301
      locales->keyblen = OFFLEN_IT;
271
      break;
302
      break;
272
    case 4:
303
    case 4:
273
      strcpy(locales->lang, "PL");
304
      strcpy(locales->lang, "PL");
274
      locales->keyboff = OFFLOC_PL;
305
      locales->keyboff = OFFLOC_PL;
275
      locales->keyblen = OFFLEN_PL;
306
      locales->keyblen = OFFLEN_PL;
276
      break;
307
      break;
277
    case 5:
308
    case 5:
278
      strcpy(locales->lang, "RU");
309
      strcpy(locales->lang, "RU");
279
      locales->keyboff = OFFLOC_RU;
310
      locales->keyboff = OFFLOC_RU;
280
      locales->keyblen = OFFLEN_RU;
311
      locales->keyblen = OFFLEN_RU;
281
      break;
312
      break;
282
    case 6:
313
    case 6:
283
      strcpy(locales->lang, "SI");
314
      strcpy(locales->lang, "SI");
284
      locales->keyboff = OFFLOC_SI;
315
      locales->keyboff = OFFLOC_SI;
285
      locales->keyblen = OFFLEN_SI;
316
      locales->keyblen = OFFLEN_SI;
286
      break;
317
      break;
287
    case 7:
318
    case 7:
288
      strcpy(locales->lang, "SV");
319
      strcpy(locales->lang, "SV");
289
      locales->keyboff = OFFLOC_SV;
320
      locales->keyboff = OFFLOC_SV;
290
      locales->keyblen = OFFLEN_SV;
321
      locales->keyblen = OFFLEN_SV;
291
      break;
322
      break;
292
    case 8:
323
    case 8:
293
      strcpy(locales->lang, "TR");
324
      strcpy(locales->lang, "TR");
294
      locales->keyboff = OFFLOC_TR;
325
      locales->keyboff = OFFLOC_TR;
295
      locales->keyblen = OFFLEN_TR;
326
      locales->keyblen = OFFLEN_TR;
296
      break;
327
      break;
297
    default:
328
    default:
298
      strcpy(locales->lang, "EN");
329
      strcpy(locales->lang, "EN");
299
      locales->keyboff = 0;
330
      locales->keyboff = 0;
300
      locales->keyblen = OFFCOUNT;
331
      locales->keyblen = OFFCOUNT;
301
      break;
332
      break;
302
  }
333
  }
303
  /* populate the slocales struct accordingly to the keyboff member */
334
  /* populate the slocales struct accordingly to the keyboff member */
304
  kblay2slocal(locales);
335
  kblay2slocal(locales);
305
  /* */
336
  /* */
306
  return(MENUNEXT);
337
  return(MENUNEXT);
307
}
338
}
308
 
339
 
309
 
340
 
310
static int selectkeyb(struct slocales *locales) {
341
static int selectkeyb(struct slocales *locales) {
311
  int menuheight, choice;
342
  int menuheight, choice;
312
  if (locales->keyblen == 1) return(MENUNEXT); /* do not ask for keyboard layout if only one is available for given language */
343
  if (locales->keyblen == 1) return(MENUNEXT); /* do not ask for keyboard layout if only one is available for given language */
313
  newscreen(0);
344
  newscreen(0);
314
  putstringnls(5, 1, COLOR_BODY[mono], 1, 5, "SvarDOS supports different keyboard layouts. Choose the keyboard layout that you want.");
345
  putstringnls(5, 1, COLOR_BODY[mono], 1, 5, "SvarDOS supports different keyboard layouts. Choose the keyboard layout that you want.");
315
  menuheight = locales->keyblen + 2;
346
  menuheight = locales->keyblen + 2;
316
  if (menuheight > 13) menuheight = 13;
347
  if (menuheight > 13) menuheight = 13;
317
  choice = menuselect(10, -1, menuheight, &(kblayouts[locales->keyboff]), locales->keyblen);
348
  choice = menuselect(10, -1, menuheight, &(kblayouts[locales->keyboff]), locales->keyblen);
318
  if (choice < 0) return(MENUPREV);
349
  if (choice < 0) return(MENUPREV);
319
  /* (re)load the keyboard layout & codepage setup */
350
  /* (re)load the keyboard layout & codepage setup */
320
  locales->keyboff += choice;
351
  locales->keyboff += choice;
321
  kblay2slocal(locales);
352
  kblay2slocal(locales);
322
  return(MENUNEXT);
353
  return(MENUNEXT);
323
}
354
}
324
 
355
 
325
 
356
 
326
/* returns 0 if installation must proceed, non-zero otherwise */
357
/* returns 0 if installation must proceed, non-zero otherwise */
327
static int welcomescreen(void) {
358
static int welcomescreen(void) {
328
  int c;
359
  int c;
329
  char *choice[] = {"Install SvarDOS to disk", "Quit to DOS", NULL};
360
  char *choice[] = {"Install SvarDOS to disk", "Quit to DOS", NULL};
330
  choice[0] = kittengets(0, 1, choice[0]);
361
  choice[0] = kittengets(0, 1, choice[0]);
331
  choice[1] = kittengets(0, 2, choice[1]);
362
  choice[1] = kittengets(0, 2, choice[1]);
332
  newscreen(0);
363
  newscreen(0);
333
  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.");
364
  putstringnls(4, 1, COLOR_BODY[mono], 2, 0, "You are about to install SvarDOS: a free, MSDOS-compatible operating system based on the FreeDOS kernel. SvarDOS targets 386+ computers and comes with a variety of third-party applications.\n\nWARNING: If your PC has another operating system installed, this other system might be unable to boot once SvarDOS is installed.");
334
  c = menuselect(13, -1, 4, choice, -1);
365
  c = menuselect(13, -1, 4, choice, -1);
335
  if (c < 0) return(MENUPREV);
366
  if (c < 0) return(MENUPREV);
336
  if (c == 0) return(MENUNEXT);
367
  if (c == 0) return(MENUNEXT);
337
  return(MENUQUIT);
368
  return(MENUQUIT);
338
}
369
}
339
 
370
 
340
 
371
 
341
/* returns 1 if drive is removable, 0 if not, -1 on error */
372
/* returns 1 if drive is removable, 0 if not, -1 on error */
342
static int isdriveremovable(int drv) {
373
static int isdriveremovable(int drv) {
343
  union REGS r;
374
  union REGS r;
344
  r.x.ax = 0x4408;
375
  r.x.ax = 0x4408;
345
  r.h.bl = drv;
376
  r.h.bl = drv;
346
  int86(0x21, &r, &r);
377
  int86(0x21, &r, &r);
347
  /* CF set on error, AX set to 0 if removable, 1 if fixed */
378
  /* CF set on error, AX set to 0 if removable, 1 if fixed */
348
  if (r.x.cflag != 0) return(-1);
379
  if (r.x.cflag != 0) return(-1);
349
  if (r.x.ax == 0) return(1);
380
  if (r.x.ax == 0) return(1);
350
  return(0);
381
  return(0);
351
}
382
}
352
 
383
 
353
 
384
 
354
/* returns total disk space of drive drv (in MiB, max 2048), or -1 if drive invalid */
385
/* returns total disk space of drive drv (in MiB, max 2048), or -1 if drive invalid */
355
static int disksize(int drv) {
386
static int disksize(int drv) {
356
  long res;
387
  long res;
357
  union REGS r;
388
  union REGS r;
358
  r.h.ah = 0x36; /* DOS 2+ get free disk space */
389
  r.h.ah = 0x36; /* DOS 2+ get free disk space */
359
  r.h.dl = drv;
390
  r.h.dl = drv;
360
  int86(0x21, &r, &r);
391
  int86(0x21, &r, &r);
361
  if (r.x.ax == 0xffffu) return(-1); /* AX set to FFFFh if drive invalid */
392
  if (r.x.ax == 0xffffu) return(-1); /* AX set to FFFFh if drive invalid */
362
  res = r.x.ax;  /* sectors per cluster */
393
  res = r.x.ax;  /* sectors per cluster */
363
  res *= r.x.dx; /* dx contains total clusters, bx contains free clusters */
394
  res *= r.x.dx; /* dx contains total clusters, bx contains free clusters */
364
  res *= r.x.cx; /* bytes per sector */
395
  res *= r.x.cx; /* bytes per sector */
365
  res >>= 20;    /* convert bytes to MiB */
396
  res >>= 20;    /* convert bytes to MiB */
366
  return(res);
397
  return(res);
367
}
398
}
368
 
399
 
369
 
400
 
370
/* returns 0 if disk is empty, non-zero otherwise */
401
/* returns 0 if disk is empty, non-zero otherwise */
371
static int diskempty(int drv) {
402
static int diskempty(int drv) {
372
  unsigned int rc;
403
  unsigned int rc;
373
  int res;
404
  int res;
374
  char buff[8];
405
  char buff[8];
375
  struct find_t fileinfo;
406
  struct find_t fileinfo;
376
  snprintf(buff, sizeof(buff), "%c:\\*.*", 'A' + drv - 1);
407
  snprintf(buff, sizeof(buff), "%c:\\*.*", 'A' + drv - 1);
377
  rc = _dos_findfirst(buff, _A_NORMAL | _A_SUBDIR | _A_HIDDEN | _A_SYSTEM, &fileinfo);
408
  rc = _dos_findfirst(buff, _A_NORMAL | _A_SUBDIR | _A_HIDDEN | _A_SYSTEM, &fileinfo);
378
  if (rc == 0) {
409
  if (rc == 0) {
379
    res = 1; /* call successfull means disk is not empty */
410
    res = 1; /* call successfull means disk is not empty */
380
  } else {
411
  } else {
381
    res = 0;
412
    res = 0;
382
  }
413
  }
383
  /* _dos_findclose(&fileinfo); */ /* apparently required only on OS/2 */
414
  /* _dos_findclose(&fileinfo); */ /* apparently required only on OS/2 */
384
  return(res);
415
  return(res);
385
}
416
}
386
 
417
 
387
 
418
#ifdef DEADCODE
388
/* set new DOS "current drive" to drv ('A', 'B', etc). returns 0 on success */
419
/* set new DOS "current drive" to drv ('A', 'B', etc). returns 0 on success */
389
static int set_cur_drive(char drv) {
420
static int set_cur_drive(char drv) {
390
  union REGS r;
421
  union REGS r;
391
  if ((drv < 'A') || (drv > 'Z')) return(-1);
422
  if ((drv < 'A') || (drv > 'Z')) return(-1);
392
  r.h.ah = 0x0E; /* DOS 1+ SELECT DEFAULT DRIVE */
423
  r.h.ah = 0x0E; /* DOS 1+ SELECT DEFAULT DRIVE */
393
  r.h.dl = drv - 'A';
424
  r.h.dl = drv - 'A';
394
  int86(0x21, &r, &r);
425
  int86(0x21, &r, &r);
395
  if (r.h.al < drv - 'A') return(-1);
426
  if (r.h.al < drv - 'A') return(-1);
396
  return(0);
427
  return(0);
397
}
428
}
398
 
429
#endif
399
 
430
 
400
/* returns 0 if file exists, non-zero otherwise */
431
/* returns 0 if file exists, non-zero otherwise */
401
static int fileexists(const char *fname) {
432
static int fileexists(const char *fname) {
402
  FILE *fd;
433
  FILE *fd;
403
  fd = fopen(fname, "rb");
434
  fd = fopen(fname, "rb");
404
  if (fd == NULL) return(-1);
435
  if (fd == NULL) return(-1);
405
  fclose(fd);
436
  fclose(fd);
406
  return(0);
437
  return(0);
407
}
438
}
408
 
439
 
409
 
440
 
410
static int preparedrive(void) {
441
static int preparedrive(void) {
411
  int driveremovable;
442
  int driveremovable;
412
  int selecteddrive = 3; /* hardcoded to 'C:' for now */
443
  int selecteddrive = 3; /* hardcoded to 'C:' for now */
413
  int cselecteddrive;
444
  int cselecteddrive;
414
  int ds;
445
  int ds;
415
  int choice;
446
  int choice;
416
  char buff[1024];
447
  char buff[1024];
417
  cselecteddrive = 'A' + selecteddrive - 1;
448
  cselecteddrive = 'A' + selecteddrive - 1;
418
  for (;;) {
449
  for (;;) {
419
    driveremovable = isdriveremovable(selecteddrive);
450
    driveremovable = isdriveremovable(selecteddrive);
420
    if (driveremovable < 0) {
451
    if (driveremovable < 0) {
421
      char *list[] = { "Create a partition automatically", "Run the FDISK partitioning tool", "Quit to DOS", NULL};
452
      char *list[] = { "Create a partition automatically", "Run the FDISK partitioning tool", "Quit to DOS", NULL};
422
      newscreen(0);
453
      newscreen(0);
423
      list[0] = kittengets(0, 3, list[0]);
454
      list[0] = kittengets(0, 3, list[0]);
424
      list[1] = kittengets(0, 4, list[1]);
455
      list[1] = kittengets(0, 4, list[1]);
425
      list[2] = kittengets(0, 2, list[2]);
456
      list[2] = kittengets(0, 2, list[2]);
426
      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);
457
      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);
427
      putstringwrap(4, 1, COLOR_BODY[mono], buff);
458
      putstringwrap(4, 1, COLOR_BODY[mono], buff);
428
      switch (menuselect(14, -1, 5, list, -1)) {
459
      switch (menuselect(14, -1, 5, list, -1)) {
429
        case 0:
460
        case 0:
430
          system("FDISK /AUTO");
461
          system("FDISK /AUTO");
431
          break;
462
          break;
432
        case 1:
463
        case 1:
433
          video_clear(0x0700, 0, 0);
464
          video_clear(0x0700, 0, 0);
434
          video_movecursor(0, 0);
465
          video_movecursor(0, 0);
435
          system("FDISK");
466
          system("FDISK");
436
          break;
467
          break;
437
        case 2:
468
        case 2:
438
          return(MENUQUIT);
469
          return(MENUQUIT);
439
        default:
470
        default:
440
          return(-1);
471
          return(-1);
441
      }
472
      }
442
      /* write a temporary MBR which only skips the drive (in case BIOS would
473
      /* write a temporary MBR which only skips the drive (in case BIOS would
443
       * try to boot off the not-yet-ready C: disk) */
474
       * try to boot off the not-yet-ready C: disk) */
444
      system("FDISK /AMBR"); /* writes BOOT.MBR into actual MBR */
475
      system("FDISK /AMBR"); /* writes BOOT.MBR into actual MBR */
445
      newscreen(2);
476
      newscreen(2);
446
      putstringnls(10, 10, COLOR_BODY[mono], 3, 1, "Your computer will reboot now.");
477
      putstringnls(10, 10, COLOR_BODY[mono], 3, 1, "Your computer will reboot now.");
447
      putstringnls(12, 10, COLOR_BODY[mono], 0, 5, "Press any key...");
478
      putstringnls(12, 10, COLOR_BODY[mono], 0, 5, "Press any key...");
448
      input_getkey();
479
      input_getkey();
449
      reboot();
480
      reboot();
450
      return(MENUQUIT);
481
      return(MENUQUIT);
451
    } else if (driveremovable > 0) {
482
    } else if (driveremovable > 0) {
452
      newscreen(2);
483
      newscreen(2);
453
      snprintf(buff, sizeof(buff), kittengets(3, 2, "ERROR: Drive %c: is a removable device. Installation aborted."), cselecteddrive);
484
      snprintf(buff, sizeof(buff), kittengets(3, 2, "ERROR: Drive %c: is a removable device. Installation aborted."), cselecteddrive);
454
      video_putstring(9, 1, COLOR_BODY[mono], buff, -1);
485
      video_putstring(9, 1, COLOR_BODY[mono], buff, -1);
455
      putstringnls(11, 2, COLOR_BODY[mono], 0, 5, "Press any key...");
486
      putstringnls(11, 2, COLOR_BODY[mono], 0, 5, "Press any key...");
456
      return(MENUQUIT);
487
      return(MENUQUIT);
457
    }
488
    }
458
    /* if not formatted, propose to format it right away (try to create a directory) */
489
    /* if not formatted, propose to format it right away (try to create a directory) */
459
    snprintf(buff, sizeof(buff), "%c:\\SVWRTEST.123", cselecteddrive);
490
    snprintf(buff, sizeof(buff), "%c:\\SVWRTEST.123", cselecteddrive);
460
    if (mkdir(buff) == 0) {
491
    if (mkdir(buff) == 0) {
461
      rmdir(buff);
492
      rmdir(buff);
462
    } else {
493
    } else {
463
      char *list[] = { "Proceed with formatting", "Quit to DOS", NULL};
494
      char *list[] = { "Proceed with formatting", "Quit to DOS", NULL};
464
      newscreen(0);
495
      newscreen(0);
465
      list[0] = kittengets(0, 6, list[0]);
496
      list[0] = kittengets(0, 6, list[0]);
466
      list[1] = kittengets(0, 2, list[1]);
497
      list[1] = kittengets(0, 2, list[1]);
467
      snprintf(buff, sizeof(buff), kittengets(3, 3, "ERROR: Drive %c: seems to be unformated. Do you wish to format it?"), cselecteddrive);
498
      snprintf(buff, sizeof(buff), kittengets(3, 3, "ERROR: Drive %c: seems to be unformated. Do you wish to format it?"), cselecteddrive);
468
      video_putstring(7, 1, COLOR_BODY[mono], buff, -1);
499
      video_putstring(7, 1, COLOR_BODY[mono], buff, -1);
469
      choice = menuselect(12, -1, 4, list, -1);
500
      choice = menuselect(12, -1, 4, list, -1);
470
      if (choice < 0) return(MENUPREV);
501
      if (choice < 0) return(MENUPREV);
471
      if (choice == 1) return(MENUQUIT);
502
      if (choice == 1) return(MENUQUIT);
472
      video_clear(0x0700, 0, 0);
503
      video_clear(0x0700, 0, 0);
473
      video_movecursor(0, 0);
504
      video_movecursor(0, 0);
474
      snprintf(buff, sizeof(buff), "FORMAT %c: /Q /U /Z:seriously /V:SVARDOS", cselecteddrive);
505
      snprintf(buff, sizeof(buff), "FORMAT %c: /Q /U /Z:seriously /V:SVARDOS", cselecteddrive);
475
      system(buff);
506
      system(buff);
476
      continue;
507
      continue;
477
    }
508
    }
478
    /* check total disk space */
509
    /* check total disk space */
479
    ds = disksize(selecteddrive);
510
    ds = disksize(selecteddrive);
480
    if (ds < SVARDOS_DISK_REQ) {
511
    if (ds < SVARDOS_DISK_REQ) {
481
      int y = 9;
512
      int y = 9;
482
      newscreen(2);
513
      newscreen(2);
483
      snprintf(buff, sizeof(buff), kittengets(3, 4, "ERROR: Drive %c: is not big enough! SvarDOS requires a disk of at least %d MiB."), cselecteddrive);
514
      snprintf(buff, sizeof(buff), kittengets(3, 4, "ERROR: Drive %c: is not big enough! SvarDOS requires a disk of at least %d MiB."), cselecteddrive);
484
      y += putstringwrap(y, 1, COLOR_BODY[mono], buff);
515
      y += putstringwrap(y, 1, COLOR_BODY[mono], buff);
485
      putstringnls(++y, 1, COLOR_BODY[mono], 0, 5, "Press any key...");
516
      putstringnls(++y, 1, COLOR_BODY[mono], 0, 5, "Press any key...");
486
      input_getkey();
517
      input_getkey();
487
      return(MENUQUIT);
518
      return(MENUQUIT);
488
    }
519
    }
489
    /* is the disk empty? */
520
    /* is the disk empty? */
490
    newscreen(0);
521
    newscreen(0);
491
    if (diskempty(selecteddrive) != 0) {
522
    if (diskempty(selecteddrive) != 0) {
492
      char *list[] = { "Proceed with formatting", "Quit to DOS", NULL};
523
      char *list[] = { "Proceed with formatting", "Quit to DOS", NULL};
493
      int y = 6;
524
      int y = 6;
494
      list[0] = kittengets(0, 6, list[0]);
525
      list[0] = kittengets(0, 6, list[0]);
495
      list[1] = kittengets(0, 2, list[1]);
526
      list[1] = kittengets(0, 2, list[1]);
496
      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);
527
      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);
497
      y += putstringwrap(y, 1, COLOR_BODY[mono], buff);
528
      y += putstringwrap(y, 1, COLOR_BODY[mono], buff);
498
      choice = menuselect(++y, -1, 4, list, -1);
529
      choice = menuselect(++y, -1, 4, list, -1);
499
      if (choice < 0) return(MENUPREV);
530
      if (choice < 0) return(MENUPREV);
500
      if (choice == 1) return(MENUQUIT);
531
      if (choice == 1) return(MENUQUIT);
501
      video_clear(0x0700, 0, 0);
532
      video_clear(0x0700, 0, 0);
502
      video_movecursor(0, 0);
533
      video_movecursor(0, 0);
503
      snprintf(buff, sizeof(buff), "FORMAT %c: /Q /U /Z:seriously /V:SVARDOS", cselecteddrive);
534
      snprintf(buff, sizeof(buff), "FORMAT %c: /Q /U /Z:seriously /V:SVARDOS", cselecteddrive);
504
      system(buff);
535
      system(buff);
505
      continue;
536
      continue;
506
    } else {
537
    } else {
507
      /* final confirmation */
538
      /* final confirmation */
508
      char *list[] = { "Install SvarDOS", "Quit to DOS", NULL};
539
      char *list[] = { "Install SvarDOS", "Quit to DOS", NULL};
509
      list[0] = kittengets(0, 1, list[0]);
540
      list[0] = kittengets(0, 1, list[0]);
510
      list[1] = kittengets(0, 2, list[1]);
541
      list[1] = kittengets(0, 2, list[1]);
511
      snprintf(buff, sizeof(buff), kittengets(3, 6, "The installation of SvarDOS to %c: is about to begin."), cselecteddrive);
542
      snprintf(buff, sizeof(buff), kittengets(3, 6, "The installation of SvarDOS to %c: is about to begin."), cselecteddrive);
512
      video_putstring(7, -1, COLOR_BODY[mono], buff, -1);
543
      video_putstring(7, -1, COLOR_BODY[mono], buff, -1);
513
      choice = menuselect(10, -1, 4, list, -1);
544
      choice = menuselect(10, -1, 4, list, -1);
514
      if (choice < 0) return(MENUPREV);
545
      if (choice < 0) return(MENUPREV);
515
      if (choice == 1) return(MENUQUIT);
546
      if (choice == 1) return(MENUQUIT);
516
      snprintf(buff, sizeof(buff), "SYS A: %c: > NUL", cselecteddrive);
547
      snprintf(buff, sizeof(buff), "SYS A: %c: > NUL", cselecteddrive);
517
      system(buff);
548
      system(buff);
518
      system("FDISK /MBR");
549
      system("FDISK /MBR");
519
      snprintf(buff, sizeof(buff), "%c:\\TEMP", cselecteddrive);
550
      snprintf(buff, sizeof(buff), "%c:\\TEMP", cselecteddrive);
520
      mkdir(buff);
551
      mkdir(buff);
521
      return(cselecteddrive);
552
      return(cselecteddrive);
522
    }
553
    }
523
  }
554
  }
524
}
555
}
525
 
556
 
526
 
557
 
-
 
558
/* generates locales-related configurations and writes them to file (this
-
 
559
 * is used to compute autoexec.bat content) */
-
 
560
static void genlocalesconf(FILE *fd, const struct slocales *locales) {
-
 
561
  if (locales == NULL) return;
-
 
562
 
-
 
563
  fprintf(fd, "SET LANG=%s\r\n", locales->lang);
-
 
564
 
-
 
565
  if (locales->egafile > 0) {
-
 
566
    fprintf(fd, "DISPLAY CON=(EGA,,1)\r\n");
-
 
567
    if (locales->egafile == 1) {
-
 
568
      fprintf(fd, "MODE CON CP PREPARE=((%u) %%DOSDIR%%\\CPI\\EGA.CPX)\r\n", locales->codepage);
-
 
569
    } else {
-
 
570
      fprintf(fd, "MODE CON CP PREPARE=((%u) %%DOSDIR%%\\CPI\\EGA%d.CPX)\r\n", locales->codepage, locales->egafile);
-
 
571
    }
-
 
572
    fprintf(fd, "MODE CON CP SELECT=%u\r\n", locales->codepage);
-
 
573
  }
-
 
574
 
-
 
575
  if (locales->keybfile > 0) {
-
 
576
    fprintf(fd, "KEYB %s,%d,%%DOSDIR%%\\BIN\\", locales->keybcode, locales->codepage);
-
 
577
    if (locales->keybfile == 1) {
-
 
578
      fprintf(fd, "KEYBOARD.SYS");
-
 
579
    } else {
-
 
580
      fprintf(fd, "KEYBRD%d.SYS", locales->keybfile);
-
 
581
    }
-
 
582
    if (locales->keybid != 0) fprintf(fd, " /ID:%d", locales->keybid);
-
 
583
    fprintf(fd, "\r\n");
-
 
584
  }
-
 
585
}
-
 
586
 
-
 
587
 
527
static void bootfilesgen(char targetdrv, const struct slocales *locales, char cdromdrv) {
588
static void bootfilesgen(char targetdrv, const struct slocales *locales) {
528
  char buff[128];
589
  char buff[128];
529
  char buff2[16];
-
 
530
  char buff3[16];
-
 
531
  FILE *fd;
590
  FILE *fd;
532
  /*** CONFIG.SYS ***/
591
  /*** CONFIG.SYS ***/
533
  snprintf(buff, sizeof(buff), "%c:\\CONFIG.SYS", targetdrv);
592
  snprintf(buff, sizeof(buff), "%c:\\TEMP\\CONFIG.SYS", targetdrv);
534
  fd = fopen(buff, "wb");
593
  fd = fopen(buff, "wb");
535
  if (fd == NULL) return;
594
  if (fd == NULL) return;
536
  fprintf(fd, "DOS=UMB,HIGH\r\n"
595
  fprintf(fd, "DOS=UMB,HIGH\r\n"
537
              "LASTDRIVE=Z\r\n"
596
              "LASTDRIVE=Z\r\n"
538
              "FILES=50\r\n");
597
              "FILES=50\r\n");
539
  fprintf(fd, "DEVICE=%c:\\SVARDOS\\BIN\\HIMEMX.EXE\r\n", targetdrv);
598
  fprintf(fd, "DEVICE=%c:\\SVARDOS\\BIN\\HIMEMX.EXE\r\n", targetdrv);
540
  if (strcmp(locales->lang, "EN") == 0) {
599
  if (strcmp(locales->lang, "EN") == 0) {
541
    strcpy(buff, "COMMAND");
600
    strcpy(buff, "COMMAND");
542
  } else {
601
  } else {
543
    snprintf(buff, sizeof(buff), "CMD-%s", locales->lang);
602
    snprintf(buff, sizeof(buff), "CMD-%s", locales->lang);
544
  }
603
  }
545
  fprintf(fd, "SHELLHIGH=%c:\\SVARDOS\\BIN\\%s.COM /E:512 /P\r\n", targetdrv, buff);
604
  fprintf(fd, "SHELLHIGH=C:\\SVARDOS\\BIN\\%s.COM /E:512 /P\r\n", buff);
546
  fprintf(fd, "REM COUNTRY=001,437,%c:\\SVARDOS\\CONF\\COUNTRY.SYS\r\n", targetdrv);
605
  fprintf(fd, "REM COUNTRY=001,437,C:\\SVARDOS\\CONF\\COUNTRY.SYS\r\n");
547
  fprintf(fd, "DEVICE=%c:\\DRIVERS\\UDVD2\\UDVD2.SYS /D:SVCD0001 /H\r\n", targetdrv);
606
  fprintf(fd, "REM DEVICE=C:\\DRIVERS\\UDVD2\\UDVD2.SYS /D:SVCD0001 /H\r\n");
548
  fclose(fd);
607
  fclose(fd);
549
  /*** AUTOEXEC.BAT ***/
608
  /*** AUTOEXEC.BAT ***/
550
  snprintf(buff, sizeof(buff), "%c:\\AUTOEXEC.BAT", targetdrv);
609
  snprintf(buff, sizeof(buff), "%c:\\TEMP\\AUTOEXEC.BAT", targetdrv);
551
  fd = fopen(buff, "wb");
610
  fd = fopen(buff, "wb");
552
  if (fd == NULL) return;
611
  if (fd == NULL) return;
553
  fprintf(fd, "@ECHO OFF\r\n");
612
  fprintf(fd, "@ECHO OFF\r\n");
554
  fprintf(fd, "SET TEMP=%c:\\TEMP\r\n", targetdrv);
613
  fprintf(fd, "SET TEMP=C:\\TEMP\r\n");
555
  fprintf(fd, "SET DOSDIR=%c:\\SVARDOS\r\n", targetdrv);
614
  fprintf(fd, "SET DOSDIR=C:\\SVARDOS\r\n");
556
  fprintf(fd, "SET NLSPATH=%%DOSDIR%%\\NLS\r\n");
615
  fprintf(fd, "SET NLSPATH=%%DOSDIR%%\\NLS\r\n");
557
  fprintf(fd, "SET LANG=%s\r\n", locales->lang);
-
 
558
  fprintf(fd, "SET DIRCMD=/OGNE/P/4\r\n");
616
  fprintf(fd, "SET DIRCMD=/OGNE/P/4\r\n");
559
  fprintf(fd, "SET WATTCP.CFG=%c:\\SVARDOS\\CFG\\WATTCP.CFG\r\n", targetdrv);
617
  fprintf(fd, "SET WATTCP.CFG=%%DOSDIR%%\\CFG\\WATTCP.CFG\r\n");
560
  fprintf(fd, "PATH %%DOSDIR%%\\BIN\r\n", targetdrv);
618
  fprintf(fd, "PATH %%DOSDIR%%\\BIN\r\n");
561
  fprintf(fd, "PROMPT $P$G\r\n");
619
  fprintf(fd, "PROMPT $P$G\r\n");
562
  fprintf(fd, "ALIAS REBOOT=FDAPM COLDBOOT\r\n");
620
  fprintf(fd, "ALIAS REBOOT=FDAPM COLDBOOT\r\n");
563
  fprintf(fd, "ALIAS HALT=FDAPM POWEROFF\r\n");
621
  fprintf(fd, "ALIAS HALT=FDAPM POWEROFF\r\n");
564
  fprintf(fd, "FDAPM APMDOS\r\n");
622
  fprintf(fd, "FDAPM APMDOS\r\n");
565
  fprintf(fd, "\r\n");
623
  fprintf(fd, "\r\n");
566
  if (locales->egafile > 0) {
624
  genlocalesconf(fd, locales);
567
    fprintf(fd, "DISPLAY CON=(EGA,,1)\r\n");
625
  fprintf(fd, "\r\n");
568
    if (locales->egafile == 1) {
-
 
569
      fprintf(fd, "MODE CON CP PREPARE=((%u) %c:\\SVARDOS\\CPI\\EGA.CPX)\r\n", locales->codepage, targetdrv);
-
 
570
    } else {
-
 
571
      fprintf(fd, "MODE CON CP PREPARE=((%u) %c:\\SVARDOS\\CPI\\EGA%d.CPX)\r\n", locales->codepage, targetdrv, locales->egafile);
-
 
572
    }
-
 
573
    fprintf(fd, "MODE CON CP SELECT=%u\r\n", locales->codepage);
626
  fprintf(fd, "REM Uncomment the line below for CDROM support\r\n");
574
  }
-
 
575
  if (locales->keybfile > 0) {
-
 
576
    if (locales->keybfile == 1) {
-
 
577
      snprintf(buff2, sizeof(buff2), "KEYBOARD.SYS");
-
 
578
    } else {
-
 
579
      snprintf(buff2, sizeof(buff2), "KEYBRD%d.SYS", locales->keybfile);
-
 
580
    }
-
 
581
    if (locales->keybid == 0) {
-
 
582
      buff3[0] = 0;
-
 
583
    } else {
-
 
584
      snprintf(buff3, sizeof(buff3), " /ID:%d", locales->keybid);
-
 
585
    }
-
 
586
    fprintf(fd, "KEYB %s,%d,%c:\\SVARDOS\\BIN\\%s%s\r\n", locales->keybcode, locales->codepage, targetdrv, buff2, buff3);
-
 
587
    fprintf(fd, "\r\n");
-
 
588
  }
-
 
589
  fprintf(fd, "SHSUCDX /d:SVCD0001\r\n");
627
  fprintf(fd, "REM SHSUCDX /d:SVCD0001\r\n");
590
  fprintf(fd, "\r\n");
628
  fprintf(fd, "\r\n");
591
  fprintf(fd, "REM Uncomment the line below for automatic mouse support\r\n");
629
  fprintf(fd, "REM Uncomment the line below for automatic mouse support\r\n");
592
  fprintf(fd, "REM CTMOUSE\r\n");
630
  fprintf(fd, "REM CTMOUSE\r\n");
593
  fprintf(fd, "\r\n");
631
  fprintf(fd, "\r\n");
594
  fprintf(fd, "ECHO.\r\n");
632
  fprintf(fd, "ECHO.\r\n");
595
  fprintf(fd, "ECHO %s\r\n", kittengets(6, 0, "Welcome to SvarDOS! Type 'HELP' if you need help."));
633
  fprintf(fd, "ECHO %s\r\n", kittengets(6, 0, "Welcome to SvarDOS! Type 'HELP' if you need help."));
596
  fclose(fd);
634
  fclose(fd);
597
  /*** CREATE DIRECTORY FOR CONFIGURATION FILES ***/
635
  /*** CREATE DIRECTORY FOR CONFIGURATION FILES ***/
598
  snprintf(buff, sizeof(buff), "%c:\\SVARDOS", targetdrv);
636
  snprintf(buff, sizeof(buff), "%c:\\SVARDOS", targetdrv);
599
  mkdir(buff);
637
  mkdir(buff);
600
  snprintf(buff, sizeof(buff), "%c:\\SVARDOS\\CFG", targetdrv);
638
  snprintf(buff, sizeof(buff), "%c:\\SVARDOS\\CFG", targetdrv);
601
  mkdir(buff);
639
  mkdir(buff);
602
  /*** PKG.CFG ***/
640
  /*** PKG.CFG ***/
603
  snprintf(buff, sizeof(buff), "%c:\\SVARDOS\\CFG\\PKG.CFG", targetdrv);
641
  snprintf(buff, sizeof(buff), "%c:\\SVARDOS\\CFG\\PKG.CFG", targetdrv);
604
  fd = fopen(buff, "wb");
642
  fd = fopen(buff, "wb");
605
  if (fd == NULL) return;
643
  if (fd == NULL) return;
606
  fprintf(fd, "# pkg config file - specifies locations where packages should be installed\r\n"
644
  fprintf(fd, "# pkg config file - specifies locations where packages should be installed\r\n"
607
              "\r\n"
645
              "\r\n"
608
              "# Programs\r\n"
646
              "# Programs\r\n"
609
              "DIR PROGS C:\\\r\n"
647
              "DIR PROGS C:\\\r\n"
610
              "\r\n"
648
              "\r\n"
611
              "# Games \r\n"
649
              "# Games \r\n"
612
              "DIR GAMES C:\\\r\n"
650
              "DIR GAMES C:\\\r\n"
613
              "\r\n"
651
              "\r\n"
614
              "# Drivers\r\n"
652
              "# Drivers\r\n"
615
              "DIR DRIVERS C:\\DRIVERS\r\n"
653
              "DIR DRIVERS C:\\DRIVERS\r\n"
616
              "\r\n"
654
              "\r\n"
617
              "# Development tools\r\n"
655
              "# Development tools\r\n"
618
              "DIR DEVEL C:\\DEVEL\r\n");
656
              "DIR DEVEL C:\\DEVEL\r\n");
619
  fclose(fd);
657
  fclose(fd);
620
  /*** COUNTRY.SYS ***/
658
  /*** COUNTRY.SYS ***/
621
  /*** PICOTCP ***/
659
  /*** PICOTCP ***/
622
  /*** WATTCP ***/
660
  /*** WATTCP ***/
623
}
661
}
624
 
662
 
625
 
663
 
626
static int installpackages(char targetdrv, char cdromdrv) {
664
static int installpackages(char targetdrv, char srcdrv, const struct slocales *locales) {
627
  char pkglist[512];
665
  char pkglist[512];
628
  int i, pkglistlen;
666
  int i, pkglistlen;
629
  size_t pkglistflen;
667
  size_t pkglistflen;
630
  char buff[64];
668
  char buff[1024]; /* must be *at least* 1 sector big for efficient file copying */
631
  FILE *fd;
669
  FILE *fd = NULL;
632
  char *pkgptr;
670
  char *pkgptr;
633
  newscreen(3);
671
  newscreen(3);
634
  /* load pkg list */
672
  /* load pkg list */
635
  fd = fopen("install.lst", "rb");
673
  fd = fopen("install.lst", "rb");
636
  if (fd == NULL) {
674
  if (fd == NULL) {
637
    video_putstring(10, 30, COLOR_BODY[mono], "ERROR: INSTALL.LST NOT FOUND", -1);
675
    video_putstring(10, 30, COLOR_BODY[mono], "ERROR: INSTALL.LST NOT FOUND", -1);
638
    input_getkey();
676
    input_getkey();
639
    return(-1);
677
    return(-1);
640
  }
678
  }
641
  pkglistflen = fread(pkglist, 1, sizeof(pkglist), fd);
679
  pkglistflen = fread(pkglist, 1, sizeof(pkglist), fd);
642
  fclose(fd);
680
  fclose(fd);
643
  if (pkglistflen == sizeof(pkglist)) {
681
  if (pkglistflen == sizeof(pkglist)) {
644
    video_putstring(10, 30, COLOR_BODY[mono], "ERROR: INSTALL.LST TOO LARGE", -1);
682
    video_putstring(10, 30, COLOR_BODY[mono], "ERROR: INSTALL.LST TOO LARGE", -1);
645
    input_getkey();
683
    input_getkey();
646
    return(-1);
684
    return(-1);
647
  }
685
  }
648
  pkglist[pkglistflen] = 0xff; /* mark the end of list */
686
  pkglist[pkglistflen] = 0xff; /* mark the end of list */
649
  /* replace all \r and \n chars by 0 bytes, and count the number of packages */
687
  /* replace all \r and \n chars by 0 bytes, and count the number of packages */
650
  pkglistlen = 0;
688
  pkglistlen = 0;
651
  for (i = 0; i < pkglistflen; i++) {
689
  for (i = 0; i < pkglistflen; i++) {
652
    switch (pkglist[i]) {
690
    switch (pkglist[i]) {
653
      case '\n':
691
      case '\n':
654
        pkglistlen++;
692
        pkglistlen++;
655
        /* FALLTHRU */
693
        /* FALLTHRU */
656
      case '\r':
694
      case '\r':
657
        pkglist[i] = 0;
695
        pkglist[i] = 0;
658
        break;
696
        break;
659
    }
697
    }
660
  }
698
  }
661
  /* set DOSDIR and COMSPEC */
699
  /* copy pkg.exe to the new drive, along with all packages */
662
  snprintf(buff, sizeof(buff), "%c:\\SVARDOS", targetdrv);
700
  snprintf(buff, sizeof(buff), "%c:\\TEMP\\pkg.exe", targetdrv);
663
  setenv("DOSDIR", buff, 1);
-
 
664
  snprintf(buff, sizeof(buff), "%c:\\COMMAND.COM", targetdrv);
701
  snprintf(buff + 64, sizeof(buff) - 64, "%c:\\pkg.exe", srcdrv);
665
  setenv("COMSPEC", buff, 1);
702
  fcopy(buff, buff + 64, buff, sizeof(buff));
-
 
703
 
666
  /* copy pkginst to the new drive so it is not read from the floppy each time */
704
  /* open the post-install autoexec.bat and prepare initial instructions */
667
  snprintf(buff, sizeof(buff), "COPY A:\\PKG.EXE %c:\\ > NUL", targetdrv);
705
  snprintf(buff, sizeof(buff), "%c:\\temp\\postinst.bat", targetdrv);
668
  system(buff);
706
  fd = fopen(buff, "wb");
669
  /* change current drive to target so I use the on-hdd fdinst from now on */
-
 
670
  if (set_cur_drive(targetdrv) != 0) {
707
  if (fd == NULL) return(-1);
671
    video_putstring(10, 30, COLOR_BODY[mono], "ERROR: CHANGING DRIVE TO TARGET FAILED", -1);
-
 
672
    input_getkey();
708
  fprintf(fd, "@ECHO OFF\r\n");
673
    return(-1);
-
 
674
  }
709
 
675
  /* install packages */
710
  /* copy packages */
676
  pkgptr = pkglist;
711
  pkgptr = pkglist;
677
  for (i = 0;; i++) {
712
  for (i = 0;; i++) {
678
    char buff[64];
-
 
679
    /* move forward to nearest entry or end of list */
713
    /* move forward to nearest entry or end of list */
680
    while (*pkgptr == 0) pkgptr++;
714
    while (*pkgptr == 0) pkgptr++;
681
    if (*pkgptr == 0xff) break;
715
    if (*pkgptr == 0xff) break;
682
    /* install the package */
716
    /* install the package */
683
    snprintf(buff, sizeof(buff), kittengets(4, 0, "Installing package %d/%d: %s"), i+1, pkglistlen, pkgptr);
717
    snprintf(buff, sizeof(buff), kittengets(4, 0, "Installing package %d/%d: %s"), i+1, pkglistlen, pkgptr);
684
    strcat(buff, "       ");
718
    strcat(buff, "       ");
685
    video_putstringfix(10, 1, COLOR_BODY[mono], buff, sizeof(buff));
719
    video_putstringfix(10, 1, COLOR_BODY[mono], buff, sizeof(buff));
686
    /* wait for new diskette if package not found */
720
    /* wait for new diskette if package not found */
687
    snprintf(buff, sizeof(buff), "%c:\\%s.zip", cdromdrv, pkgptr);
721
    snprintf(buff, sizeof(buff), "%c:\\%s.zip", srcdrv, pkgptr);
688
    while (fileexists(buff) != 0) {
722
    while (fileexists(buff) != 0) {
689
      putstringnls(12, 1, COLOR_BODY[mono], 4, 1, "*** INSERT THE DISK THAT CONTAINS THE REQUIRED FILE AND PRESS ANY KEY ***");
723
      putstringnls(12, 1, COLOR_BODY[mono], 4, 1, "*** INSERT THE DISK THAT CONTAINS THE REQUIRED FILE AND PRESS ANY KEY ***");
690
      input_getkey();
724
      input_getkey();
691
      video_putstringfix(12, 1, COLOR_BODY[mono], "", 80); /* erase the 'insert disk' message */
725
      video_putstringfix(12, 1, COLOR_BODY[mono], "", 80); /* erase the 'insert disk' message */
692
    }
726
    }
693
    /* proceed with package install */
727
    /* proceed with package copy (buff contains the src filename already) */
694
    snprintf(buff, sizeof(buff), "PKG INSTALL %c:\\%s.ZIP > NUL", cdromdrv, pkgptr);
728
    snprintf(buff + 32, sizeof(buff) - 32, "%c:\\temp\\%s.zip", targetdrv, pkgptr);
695
    if (system(buff) != 0) {
729
    if (fcopy(buff + 32, buff, buff, sizeof(buff)) != 0) {
696
      video_putstring(12, 30, COLOR_BODY[mono], "ERROR: PKG INSTALL FAILED", -1);
730
      video_putstring(10, 30, COLOR_BODY[mono], "READ ERROR", -1);
697
      input_getkey();
731
      input_getkey();
-
 
732
      fclose(fd);
698
      return(-1);
733
      return(-1);
699
    }
734
    }
-
 
735
    /* write install instruction to post-install script */
-
 
736
    fprintf(fd, "pkg install %s.zip\r\ndel %s.zip\r\n", pkgptr, pkgptr);
700
    /* jump to next entry or end of list */
737
    /* jump to next entry or end of list */
701
    while ((*pkgptr != 0) && (*pkgptr != 0xff)) pkgptr++;
738
    while ((*pkgptr != 0) && (*pkgptr != 0xff)) pkgptr++;
702
    if (*pkgptr == 0xff) break;
739
    if (*pkgptr == 0xff) break;
703
  }
740
  }
-
 
741
  /* set up locales so the "installation over" message is nicely displayed */
-
 
742
  genlocalesconf(fd, locales);
-
 
743
  /* replace autoexec.bat and config.sys now and write some nice message on screen */
-
 
744
  fprintf(fd, "DEL pkg.exe\r\n"
-
 
745
              "COPY CONFIG.SYS C:\\\r\n"
-
 
746
              "DEL CONFIG.SYS\r\n"
-
 
747
              "DEL C:\\AUTOEXEC.BAT\r\n"
-
 
748
              "COPY AUTOEXEC.BAT C:\\\r\n"
-
 
749
              "DEL AUTOEXEC.BAT\r\n");
-
 
750
  /* print out the "installation over" message */
-
 
751
  fprintf(fd, "ECHO.\r\n"
-
 
752
              "ECHO %s\r\n"
-
 
753
              "ECHO.\r\n", kittengets(5, 1, "SvarDOS installation is over. Please restart your computer now."));
-
 
754
  fclose(fd);
-
 
755
 
-
 
756
  /* prepare a dummy autoexec.bat that will call temp\postinst.bat */
-
 
757
  snprintf(buff, sizeof(buff), "%c:\\autoexec.bat", targetdrv);
-
 
758
  fd = fopen(buff, "wb");
-
 
759
  if (fd == NULL) return(-1);
-
 
760
  fprintf(fd, "@ECHO OFF\r\n"
-
 
761
              "SET DOSDIR=C:\\SVARDOS\r\n"
-
 
762
              "SET NLSPATH=%%DOSDIR%%\\NLS\r\n"
-
 
763
              "PATH %%DOSDIR%%\\BIN\r\n");
-
 
764
  fprintf(fd, "CD TEMP\r\n"
-
 
765
              "postinst.bat\r\n");
-
 
766
  fclose(fd);
-
 
767
 
704
  return(0);
768
  return(0);
705
}
769
}
706
 
770
 
707
 
771
 
708
static void finalreboot(void) {
772
static void finalreboot(void) {
709
  int y = 9;
773
  int y = 9;
710
  newscreen(2);
774
  newscreen(2);
711
  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.");
775
  y += putstringnls(y, 1, COLOR_BODY[mono], 5, 0, "Your computer will reboot now.\nPlease remove the installation disk from your drive.");
712
  putstringnls(++y, 1, COLOR_BODY[mono], 0, 5, "Press any key...");
776
  putstringnls(++y, 1, COLOR_BODY[mono], 0, 5, "Press any key...");
713
  input_getkey();
777
  input_getkey();
714
  reboot();
778
  reboot();
715
}
779
}
716
 
780
 
717
 
781
 
718
static void loadcp(const struct slocales *locales) {
782
static void loadcp(const struct slocales *locales) {
719
  char buff[64];
783
  char buff[64];
720
  if (locales->codepage == 437) return;
784
  if (locales->codepage == 437) return;
721
  video_movecursor(1, 0);
785
  video_movecursor(1, 0);
722
  if (locales->egafile == 1) {
786
  if (locales->egafile == 1) {
723
    snprintf(buff, sizeof(buff), "MODE CON CP PREP=((%u) A:\\EGA.CPX) > NUL", locales->codepage);
787
    snprintf(buff, sizeof(buff), "MODE CON CP PREP=((%u) A:\\EGA.CPX) > NUL", locales->codepage);
724
  } else {
788
  } else {
725
    snprintf(buff, sizeof(buff), "MODE CON CP PREP=((%u) A:\\EGA%d.CPX) > NUL", locales->codepage, locales->egafile);
789
    snprintf(buff, sizeof(buff), "MODE CON CP PREP=((%u) A:\\EGA%d.CPX) > NUL", locales->codepage, locales->egafile);
726
  }
790
  }
727
  system(buff);
791
  system(buff);
728
  snprintf(buff, sizeof(buff), "MODE CON CP SEL=%u > NUL", locales->codepage);
792
  snprintf(buff, sizeof(buff), "MODE CON CP SEL=%u > NUL", locales->codepage);
729
  system(buff);
793
  system(buff);
730
  /* below I re-init the video controller - apparently this is required if
794
  /* below I re-init the video controller - apparently this is required if
731
   * I want the new glyph symbols to be actually applied, at least some
795
   * I want the new glyph symbols to be actually applied, at least some
732
   * (broken?) BIOSes, like VBox, apply glyphs only at next video mode change */
796
   * (broken?) BIOSes, like VBox, apply glyphs only at next video mode change */
733
  {
797
  {
734
  union REGS r;
798
  union REGS r;
735
  r.h.ah = 0x0F; /* get current video mode */
799
  r.h.ah = 0x0F; /* get current video mode */
736
  int86(0x10, &r, &r); /* r.h.al contains the current video mode now */
800
  int86(0x10, &r, &r); /* r.h.al contains the current video mode now */
737
  r.h.al |= 128; /* set the high bit of AL to instruct BIOS not to flush VRAM's content (EGA+) */
801
  r.h.al |= 128; /* set the high bit of AL to instruct BIOS not to flush VRAM's content (EGA+) */
738
  r.h.ah = 0; /* re-set video mode (to whatever is set in AL) */
802
  r.h.ah = 0; /* re-set video mode (to whatever is set in AL) */
739
  int86(0x10, &r, &r);
803
  int86(0x10, &r, &r);
740
  }
804
  }
741
}
805
}
742
 
806
 
743
 
807
 
744
/* checks that drive drv contains SvarDOS packages
808
/* checks that drive drv contains SvarDOS packages
745
 * returns 0 if found, non-zero otherwise */
809
 * returns 0 if found, non-zero otherwise */
746
static int checkinstsrc(char drv) {
810
static int checkinstsrc(char drv) {
747
  char fname[16];
811
  char fname[16];
748
  snprintf(fname, sizeof(fname), "%c:\\ATTRIB.ZIP", drv);
812
  snprintf(fname, sizeof(fname), "%c:\\ATTRIB.ZIP", drv);
749
  return(fileexists(fname));
813
  return(fileexists(fname));
750
}
814
}
751
 
815
 
752
 
816
 
753
int main(void) {
817
int main(void) {
754
  struct slocales locales;
818
  struct slocales locales;
755
  int targetdrv;
819
  int targetdrv;
756
  int sourcedrv;
820
  int sourcedrv;
757
  int action;
821
  int action;
758
 
822
 
759
  /* am I running in install-from-floppy mode? */
823
  /* am I running in install-from-floppy mode? */
760
  if (checkinstsrc('A') == 0) {
824
  if (checkinstsrc('A') == 0) {
761
    sourcedrv = 'A';
825
    sourcedrv = 'A';
762
  } else { /* otherwise find where the cdrom drive is */
826
  } else { /* otherwise find where the cdrom drive is */
763
    sourcedrv = cdrom_findfirst();
827
    sourcedrv = cdrom_findfirst();
764
    if (sourcedrv < 0) {
828
    if (sourcedrv < 0) {
765
      printf("ERROR: CD-ROM DRIVE NOT FOUND\r\n");
829
      printf("ERROR: CD-ROM DRIVE NOT FOUND\r\n");
766
      return(1);
830
      return(1);
767
    }
831
    }
768
    sourcedrv += 'A'; /* convert the source drive 'id' (A=0) to an actual drive letter */
832
    sourcedrv += 'A'; /* convert the source drive 'id' (A=0) to an actual drive letter */
769
    if (checkinstsrc(sourcedrv) != 0) {
833
    if (checkinstsrc(sourcedrv) != 0) {
770
      printf("ERROR: SVARDOS INSTALLATION CD NOT FOUND IN THE DRIVE.\r\n");
834
      printf("ERROR: SVARDOS INSTALLATION CD NOT FOUND IN THE DRIVE.\r\n");
771
      return(1);
835
      return(1);
772
    }
836
    }
773
  }
837
  }
774
 
838
 
775
  /* init screen and detect mono status */
839
  /* init screen and detect mono status */
776
  mono = video_init();
840
  mono = video_init();
777
 
841
 
778
  kittenopen("INSTALL"); /* load initial NLS support */
842
  kittenopen("INSTALL"); /* load initial NLS support */
779
 
843
 
780
 SelectLang:
844
 SelectLang:
781
  action = selectlang(&locales); /* welcome to svardos, select your language */
845
  action = selectlang(&locales); /* welcome to svardos, select your language */
782
  if (action != MENUNEXT) goto Quit;
846
  if (action != MENUNEXT) goto Quit;
783
  setenv("LANG", locales.lang, 1);
847
  setenv("LANG", locales.lang, 1);
784
  loadcp(&locales);
848
  loadcp(&locales);
785
  kittenclose(); /* reload NLS with new language */
849
  kittenclose(); /* reload NLS with new language */
786
  kittenopen("INSTALL"); /* NLS support */
850
  kittenopen("INSTALL"); /* NLS support */
787
  action = selectkeyb(&locales);  /* what keyb layout should we use? */
851
  action = selectkeyb(&locales);  /* what keyb layout should we use? */
788
  if (action == MENUQUIT) goto Quit;
852
  if (action == MENUQUIT) goto Quit;
789
  if (action == MENUPREV) goto SelectLang;
853
  if (action == MENUPREV) goto SelectLang;
790
 
854
 
791
 WelcomeScreen:
855
 WelcomeScreen:
792
  action = welcomescreen(); /* what svardos is, ask whether to run live dos or install */
856
  action = welcomescreen(); /* what svardos is, ask whether to run live dos or install */
793
  if (action == MENUQUIT) goto Quit;
857
  if (action == MENUQUIT) goto Quit;
794
  if (action == MENUPREV) goto SelectLang;
858
  if (action == MENUPREV) goto SelectLang;
795
  targetdrv = preparedrive(); /* what drive should we install to? check avail. space */
859
  targetdrv = preparedrive(); /* what drive should we install to? check avail. space */
796
  if (targetdrv == MENUQUIT) goto Quit;
860
  if (targetdrv == MENUQUIT) goto Quit;
797
  if (targetdrv == MENUPREV) goto WelcomeScreen;
861
  if (targetdrv == MENUPREV) goto WelcomeScreen;
798
  bootfilesgen(targetdrv, &locales, sourcedrv); /* generate boot files and other configurations */
862
  bootfilesgen(targetdrv, &locales); /* generate boot files and other configurations */
799
  if (installpackages(targetdrv, sourcedrv) != 0) goto Quit;    /* install packages */
863
  if (installpackages(targetdrv, sourcedrv, &locales) != 0) goto Quit;    /* install packages */
800
  /*localcfg();*/ /* show local params (currency, etc), and propose to change them (based on localcfg) */
864
  /*localcfg();*/ /* show local params (currency, etc), and propose to change them (based on localcfg) */
801
  /*netcfg();*/ /* basic networking config */
865
  /*netcfg();*/ /* basic networking config */
802
  finalreboot(); /* remove the CD and reboot */
866
  finalreboot(); /* remove the CD and reboot */
803
 
867
 
804
 Quit:
868
 Quit:
805
  kittenclose(); /* close NLS support */
869
  kittenclose(); /* close NLS support */
806
  video_clear(0x0700, 0, 0);
870
  video_clear(0x0700, 0, 0);
807
  video_movecursor(0, 0);
871
  video_movecursor(0, 0);
808
  return(0);
872
  return(0);
809
}
873
}
810
 
874