Subversion Repositories SvarDOS

Rev

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

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