Subversion Repositories SvarDOS

Rev

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

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