Subversion Repositories SvarDOS

Rev

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

Rev 98 Rev 101
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
    "Polish",
236
    "Polish",
237
    "Turkish",
237
    "Turkish",
238
    NULL
238
    NULL
239
  };
239
  };
240
 
240
 
241
  newscreen(1);
241
  newscreen(1);
242
  msg = kittengets(1, 0, "Welcome to Svarog386");
242
  msg = kittengets(1, 0, "Welcome to Svarog386");
243
  x = 40 - (strlen(msg) >> 1);
243
  x = 40 - (strlen(msg) >> 1);
244
  video_putstring(4, x, COLOR_BODY[mono], msg, -1);
244
  video_putstring(4, x, COLOR_BODY[mono], msg, -1);
245
  video_putcharmulti(5, x, COLOR_BODY[mono], '=', strlen(msg), 1);
245
  video_putcharmulti(5, x, COLOR_BODY[mono], '=', strlen(msg), 1);
246
  putstringnls(8, -1, COLOR_BODY[mono], 1, 1, "Please select your language from the list below:");
246
  putstringnls(8, -1, COLOR_BODY[mono], 1, 1, "Please select your language from the list below:");
247
  choice = menuselect(11, -1, 6, langlist, -1);
247
  choice = menuselect(11, -1, 6, langlist, -1);
248
  if (choice < 0) return(MENUPREV);
248
  if (choice < 0) return(MENUPREV);
249
  /* populate locales with default values */
249
  /* populate locales with default values */
250
  memset(locales, 0, sizeof(struct slocales));
250
  memset(locales, 0, sizeof(struct slocales));
251
  switch (choice) {
251
  switch (choice) {
252
    case 1:
252
    case 1:
253
      strcpy(locales->lang, "FR");
253
      strcpy(locales->lang, "FR");
254
      locales->keyboff = OFFLOC_FR;
254
      locales->keyboff = OFFLOC_FR;
255
      locales->keyblen = OFFLEN_FR;
255
      locales->keyblen = OFFLEN_FR;
256
      break;
256
      break;
257
    case 2:
257
    case 2:
258
      strcpy(locales->lang, "PL");
258
      strcpy(locales->lang, "PL");
259
      locales->keyboff = OFFLOC_PL;
259
      locales->keyboff = OFFLOC_PL;
260
      locales->keyblen = OFFLEN_PL;
260
      locales->keyblen = OFFLEN_PL;
261
      break;
261
      break;
262
    case 3:
262
    case 3:
263
      strcpy(locales->lang, "TR");
263
      strcpy(locales->lang, "TR");
264
      locales->keyboff = OFFLOC_TR;
264
      locales->keyboff = OFFLOC_TR;
265
      locales->keyblen = OFFLEN_TR;
265
      locales->keyblen = OFFLEN_TR;
266
      break;
266
      break;
267
    default:
267
    default:
268
      strcpy(locales->lang, "EN");
268
      strcpy(locales->lang, "EN");
269
      locales->keyboff = 0;
269
      locales->keyboff = 0;
270
      locales->keyblen = OFFCOUNT;
270
      locales->keyblen = OFFCOUNT;
271
      break;
271
      break;
272
  }
272
  }
273
  /* populate the slocales struct accordingly to the keyboff member */
273
  /* populate the slocales struct accordingly to the keyboff member */
274
  kblay2slocal(locales);
274
  kblay2slocal(locales);
275
  /* */
275
  /* */
276
  return(MENUNEXT);
276
  return(MENUNEXT);
277
}
277
}
278
 
278
 
279
 
279
 
280
static int selectkeyb(struct slocales *locales) {
280
static int selectkeyb(struct slocales *locales) {
281
  int menuheight, choice;
281
  int menuheight, choice;
282
  if (locales->keyblen == 1) return(MENUNEXT); /* do not ask for keyboard layout if only one is available for given language */
282
  if (locales->keyblen == 1) return(MENUNEXT); /* do not ask for keyboard layout if only one is available for given language */
283
  newscreen(0);
283
  newscreen(0);
284
  putstringnls(5, 1, COLOR_BODY[mono], 1, 5, "Svarog386 supports the keyboard layouts used in different countries. Choose the keyboard layout you want.");
284
  putstringnls(5, 1, COLOR_BODY[mono], 1, 5, "Svarog386 supports the keyboard layouts used in different countries. Choose the keyboard layout you want.");
285
  menuheight = locales->keyblen + 2;
285
  menuheight = locales->keyblen + 2;
286
  if (menuheight > 13) menuheight = 13;
286
  if (menuheight > 13) menuheight = 13;
287
  choice = menuselect(10, -1, menuheight, &(kblayouts[locales->keyboff]), locales->keyblen);
287
  choice = menuselect(10, -1, menuheight, &(kblayouts[locales->keyboff]), locales->keyblen);
288
  if (choice < 0) return(MENUPREV);
288
  if (choice < 0) return(MENUPREV);
289
  /* (re)load the keyboard layout & codepage setup */
289
  /* (re)load the keyboard layout & codepage setup */
290
  locales->keyboff += choice;
290
  locales->keyboff += choice;
291
  kblay2slocal(locales);
291
  kblay2slocal(locales);
292
  return(MENUNEXT);
292
  return(MENUNEXT);
293
}
293
}
294
 
294
 
295
 
295
 
296
/* returns 0 if installation must proceed, non-zero otherwise */
296
/* returns 0 if installation must proceed, non-zero otherwise */
297
static int welcomescreen(void) {
297
static int welcomescreen(void) {
298
  int c;
298
  int c;
299
  char *choice[] = {"Install Svarog386 to disk", "Quit to DOS", NULL};
299
  char *choice[] = {"Install Svarog386 to disk", "Quit to DOS", NULL};
300
  choice[0] = kittengets(0, 1, choice[0]);
300
  choice[0] = kittengets(0, 1, choice[0]);
301
  choice[1] = kittengets(0, 2, choice[1]);
301
  choice[1] = kittengets(0, 2, choice[1]);
302
  newscreen(0);
302
  newscreen(0);
303
  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.");
303
  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.");
304
  c = menuselect(13, -1, 4, choice, -1);
304
  c = menuselect(13, -1, 4, choice, -1);
305
  if (c < 0) return(MENUPREV);
305
  if (c < 0) return(MENUPREV);
306
  if (c == 0) return(MENUNEXT);
306
  if (c == 0) return(MENUNEXT);
307
  return(MENUQUIT);
307
  return(MENUQUIT);
308
}
308
}
309
 
309
 
310
 
310
 
311
/* returns 1 if drive is removable, 0 if not, -1 on error */
311
/* returns 1 if drive is removable, 0 if not, -1 on error */
312
static int isdriveremovable(int drv) {
312
static int isdriveremovable(int drv) {
313
  union REGS r;
313
  union REGS r;
314
  r.x.ax = 0x4408;
314
  r.x.ax = 0x4408;
315
  r.h.bl = drv;
315
  r.h.bl = drv;
316
  int86(0x21, &r, &r);
316
  int86(0x21, &r, &r);
317
  /* CF set on error, AX set to 0 if removable, 1 if fixed */
317
  /* CF set on error, AX set to 0 if removable, 1 if fixed */
318
  if (r.x.cflag != 0) return(-1);
318
  if (r.x.cflag != 0) return(-1);
319
  if (r.x.ax == 0) return(1);
319
  if (r.x.ax == 0) return(1);
320
  return(0);
320
  return(0);
321
}
321
}
322
 
322
 
323
 
323
 
324
/* returns total disk space of drive drv (in MiB, max 2048), or -1 if drive invalid */
324
/* returns total disk space of drive drv (in MiB, max 2048), or -1 if drive invalid */
325
static int disksize(int drv) {
325
static int disksize(int drv) {
326
  long res;
326
  long res;
327
  union REGS r;
327
  union REGS r;
328
  r.h.ah = 0x36; /* DOS 2+ get free disk space */
328
  r.h.ah = 0x36; /* DOS 2+ get free disk space */
329
  r.h.dl = drv;
329
  r.h.dl = drv;
330
  int86(0x21, &r, &r);
330
  int86(0x21, &r, &r);
331
  if (r.x.ax == 0xffffu) return(-1); /* AX set to FFFFh if drive invalid */
331
  if (r.x.ax == 0xffffu) return(-1); /* AX set to FFFFh if drive invalid */
332
  res = r.x.ax;  /* sectors per cluster */
332
  res = r.x.ax;  /* sectors per cluster */
333
  res *= r.x.dx; /* dx contains total clusters, bx contains free clusters */
333
  res *= r.x.dx; /* dx contains total clusters, bx contains free clusters */
334
  res *= r.x.cx; /* bytes per sector */
334
  res *= r.x.cx; /* bytes per sector */
335
  res >>= 20;    /* convert bytes to MiB */
335
  res >>= 20;    /* convert bytes to MiB */
336
  return(res);
336
  return(res);
337
}
337
}
338
 
338
 
339
 
339
 
340
/* returns 0 if disk is empty, non-zero otherwise */
340
/* returns 0 if disk is empty, non-zero otherwise */
341
static int diskempty(int drv) {
341
static int diskempty(int drv) {
342
  unsigned int rc;
342
  unsigned int rc;
343
  int res;
343
  int res;
344
  char buff[8];
344
  char buff[8];
345
  struct find_t fileinfo;
345
  struct find_t fileinfo;
346
  snprintf(buff, sizeof(buff), "%c:\\*.*", 'A' + drv - 1);
346
  snprintf(buff, sizeof(buff), "%c:\\*.*", 'A' + drv - 1);
347
  rc = _dos_findfirst(buff, _A_NORMAL | _A_SUBDIR | _A_HIDDEN | _A_SYSTEM, &fileinfo);
347
  rc = _dos_findfirst(buff, _A_NORMAL | _A_SUBDIR | _A_HIDDEN | _A_SYSTEM, &fileinfo);
348
  if (rc == 0) {
348
  if (rc == 0) {
349
    res = 1; /* call successfull means disk is not empty */
349
    res = 1; /* call successfull means disk is not empty */
350
  } else {
350
  } else {
351
    res = 0;
351
    res = 0;
352
  }
352
  }
353
  /* _dos_findclose(&fileinfo); */ /* apparently required only on OS/2 */
353
  /* _dos_findclose(&fileinfo); */ /* apparently required only on OS/2 */
354
  return(res);
354
  return(res);
355
}
355
}
356
 
356
 
357
 
357
 
358
static int preparedrive(void) {
358
static int preparedrive(void) {
359
  int driveremovable;
359
  int driveremovable;
360
  int selecteddrive = 3; /* hardcoded to 'C:' for now */
360
  int selecteddrive = 3; /* hardcoded to 'C:' for now */
361
  int cselecteddrive;
361
  int cselecteddrive;
362
  int ds;
362
  int ds;
363
  int choice;
363
  int choice;
364
  char buff[1024];
364
  char buff[1024];
365
  cselecteddrive = 'A' + selecteddrive - 1;
365
  cselecteddrive = 'A' + selecteddrive - 1;
366
  for (;;) {
366
  for (;;) {
367
    driveremovable = isdriveremovable(selecteddrive);
367
    driveremovable = isdriveremovable(selecteddrive);
368
    if (driveremovable < 0) {
368
    if (driveremovable < 0) {
369
      char *list[] = { "Create a partition automatically", "Run the FDISK partitioning tool", "Quit to DOS", NULL};
369
      char *list[] = { "Create a partition automatically", "Run the FDISK partitioning tool", "Quit to DOS", NULL};
370
      newscreen(0);
370
      newscreen(0);
371
      list[0] = kittengets(0, 3, list[0]);
371
      list[0] = kittengets(0, 3, list[0]);
372
      list[1] = kittengets(0, 4, list[1]);
372
      list[1] = kittengets(0, 4, list[1]);
373
      list[2] = kittengets(0, 2, list[2]);
373
      list[2] = kittengets(0, 2, list[2]);
374
      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);
374
      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);
375
      putstringwrap(4, 1, COLOR_BODY[mono], buff);
375
      putstringwrap(4, 1, COLOR_BODY[mono], buff);
376
      switch (menuselect(14, -1, 5, list, -1)) {
376
      switch (menuselect(14, -1, 5, list, -1)) {
377
        case 0:
377
        case 0:
378
          system("FDISK /AUTO");
378
          system("FDISK /AUTO");
379
          break;
379
          break;
380
        case 1:
380
        case 1:
381
          video_clear(0x0700, 0, 0);
381
          video_clear(0x0700, 0, 0);
382
          video_movecursor(0, 0);
382
          video_movecursor(0, 0);
383
          system("FDISK");
383
          system("FDISK");
384
          break;
384
          break;
385
        case 2:
385
        case 2:
386
          return(MENUQUIT);
386
          return(MENUQUIT);
387
        default:
387
        default:
388
          return(-1);
388
          return(-1);
389
      }
389
      }
390
      newscreen(2);
390
      newscreen(2);
391
      putstringnls(10, 10, COLOR_BODY[mono], 3, 1, "Your computer will reboot now.");
391
      putstringnls(10, 10, COLOR_BODY[mono], 3, 1, "Your computer will reboot now.");
392
      putstringnls(12, 10, COLOR_BODY[mono], 0, 5, "Press any key...");
392
      putstringnls(12, 10, COLOR_BODY[mono], 0, 5, "Press any key...");
393
      input_getkey();
393
      input_getkey();
394
      reboot();
394
      reboot();
395
      return(MENUQUIT);
395
      return(MENUQUIT);
396
    } else if (driveremovable > 0) {
396
    } else if (driveremovable > 0) {
397
      newscreen(2);
397
      newscreen(2);
398
      snprintf(buff, sizeof(buff), kittengets(3, 2, "ERROR: Drive %c: is a removable device. Installation aborted."), cselecteddrive);
398
      snprintf(buff, sizeof(buff), kittengets(3, 2, "ERROR: Drive %c: is a removable device. Installation aborted."), cselecteddrive);
399
      video_putstring(9, 1, COLOR_BODY[mono], buff, -1);
399
      video_putstring(9, 1, COLOR_BODY[mono], buff, -1);
400
      putstringnls(11, 2, COLOR_BODY[mono], 0, 5, "Press any key...");
400
      putstringnls(11, 2, COLOR_BODY[mono], 0, 5, "Press any key...");
401
      return(MENUQUIT);
401
      return(MENUQUIT);
402
    }
402
    }
403
    /* if not formatted, propose to format it right away (try to create a directory) */
403
    /* if not formatted, propose to format it right away (try to create a directory) */
404
    snprintf(buff, sizeof(buff), "%c:\\SVWRTEST.123", cselecteddrive);
404
    snprintf(buff, sizeof(buff), "%c:\\SVWRTEST.123", cselecteddrive);
405
    if (mkdir(buff) == 0) {
405
    if (mkdir(buff) == 0) {
406
      rmdir(buff);
406
      rmdir(buff);
407
    } else {
407
    } else {
408
      char *list[] = { "Proceed with formatting", "Quit to DOS", NULL};
408
      char *list[] = { "Proceed with formatting", "Quit to DOS", NULL};
409
      newscreen(0);
409
      newscreen(0);
410
      list[0] = kittengets(0, 6, list[0]);
410
      list[0] = kittengets(0, 6, list[0]);
411
      list[1] = kittengets(0, 2, list[1]);
411
      list[1] = kittengets(0, 2, list[1]);
412
      snprintf(buff, sizeof(buff), kittengets(3, 3, "ERROR: Drive %c: seems to be unformated. Do you wish to format it?"), cselecteddrive);
412
      snprintf(buff, sizeof(buff), kittengets(3, 3, "ERROR: Drive %c: seems to be unformated. Do you wish to format it?"), cselecteddrive);
413
      video_putstring(7, 1, COLOR_BODY[mono], buff, -1);
413
      video_putstring(7, 1, COLOR_BODY[mono], buff, -1);
414
      choice = menuselect(12, -1, 4, list, -1);
414
      choice = menuselect(12, -1, 4, list, -1);
415
      if (choice < 0) return(MENUPREV);
415
      if (choice < 0) return(MENUPREV);
416
      if (choice == 1) return(MENUQUIT);
416
      if (choice == 1) return(MENUQUIT);
417
      video_clear(0x0700, 0, 0);
417
      video_clear(0x0700, 0, 0);
418
      video_movecursor(0, 0);
418
      video_movecursor(0, 0);
419
      snprintf(buff, sizeof(buff), "FORMAT %c: /Q /U /Z:seriously /V:SVAROG386", cselecteddrive);
419
      snprintf(buff, sizeof(buff), "FORMAT %c: /Q /U /Z:seriously /V:SVAROG386", cselecteddrive);
420
      system(buff);
420
      system(buff);
421
      continue;
421
      continue;
422
    }
422
    }
423
    /* check total disk space */
423
    /* check total disk space */
424
    ds = disksize(selecteddrive);
424
    ds = disksize(selecteddrive);
425
    if (ds < SVAROG_DISK_REQ) {
425
    if (ds < SVAROG_DISK_REQ) {
426
      int y = 9;
426
      int y = 9;
427
      newscreen(2);
427
      newscreen(2);
428
      snprintf(buff, sizeof(buff), kittengets(3, 4, "ERROR: Drive %c: is not big enough! Svarog386 requires a disk of at least %d MiB."), cselecteddrive);
428
      snprintf(buff, sizeof(buff), kittengets(3, 4, "ERROR: Drive %c: is not big enough! Svarog386 requires a disk of at least %d MiB."), cselecteddrive);
429
      y += putstringwrap(y, 1, COLOR_BODY[mono], buff);
429
      y += putstringwrap(y, 1, COLOR_BODY[mono], buff);
430
      putstringnls(++y, 1, COLOR_BODY[mono], 0, 5, "Press any key...");
430
      putstringnls(++y, 1, COLOR_BODY[mono], 0, 5, "Press any key...");
431
      input_getkey();
431
      input_getkey();
432
      return(MENUQUIT);
432
      return(MENUQUIT);
433
    }
433
    }
434
    /* is the disk empty? */
434
    /* is the disk empty? */
435
    newscreen(0);
435
    newscreen(0);
436
    if (diskempty(selecteddrive) != 0) {
436
    if (diskempty(selecteddrive) != 0) {
437
      char *list[] = { "Proceed with formatting", "Quit to DOS", NULL};
437
      char *list[] = { "Proceed with formatting", "Quit to DOS", NULL};
438
      int y = 6;
438
      int y = 6;
439
      list[0] = kittengets(0, 6, list[0]);
439
      list[0] = kittengets(0, 6, list[0]);
440
      list[1] = kittengets(0, 2, list[1]);
440
      list[1] = kittengets(0, 2, list[1]);
441
      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);
441
      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);
442
      y += putstringwrap(y, 1, COLOR_BODY[mono], buff);
442
      y += putstringwrap(y, 1, COLOR_BODY[mono], buff);
443
      choice = menuselect(++y, -1, 4, list, -1);
443
      choice = menuselect(++y, -1, 4, list, -1);
444
      if (choice < 0) return(MENUPREV);
444
      if (choice < 0) return(MENUPREV);
445
      if (choice == 1) return(MENUQUIT);
445
      if (choice == 1) return(MENUQUIT);
446
      video_clear(0x0700, 0, 0);
446
      video_clear(0x0700, 0, 0);
447
      video_movecursor(0, 0);
447
      video_movecursor(0, 0);
448
      snprintf(buff, sizeof(buff), "FORMAT %c: /Q /U /Z:seriously /V:SVAROG386", cselecteddrive);
448
      snprintf(buff, sizeof(buff), "FORMAT %c: /Q /U /Z:seriously /V:SVAROG386", cselecteddrive);
449
      system(buff);
449
      system(buff);
450
      continue;
450
      continue;
451
    } else {
451
    } else {
452
      /* final confirmation */
452
      /* final confirmation */
453
      char *list[] = { "Install Svarog386", "Quit to DOS", NULL};
453
      char *list[] = { "Install Svarog386", "Quit to DOS", NULL};
454
      list[0] = kittengets(0, 1, list[0]);
454
      list[0] = kittengets(0, 1, list[0]);
455
      list[1] = kittengets(0, 2, list[1]);
455
      list[1] = kittengets(0, 2, list[1]);
456
      snprintf(buff, sizeof(buff), kittengets(3, 6, "The installation of Svarog386 to %c: is about to begin."), cselecteddrive);
456
      snprintf(buff, sizeof(buff), kittengets(3, 6, "The installation of Svarog386 to %c: is about to begin."), cselecteddrive);
457
      video_putstring(7, -1, COLOR_BODY[mono], buff, -1);
457
      video_putstring(7, -1, COLOR_BODY[mono], buff, -1);
458
      choice = menuselect(10, -1, 4, list, -1);
458
      choice = menuselect(10, -1, 4, list, -1);
459
      if (choice < 0) return(MENUPREV);
459
      if (choice < 0) return(MENUPREV);
460
      if (choice == 1) return(MENUQUIT);
460
      if (choice == 1) return(MENUQUIT);
461
      snprintf(buff, sizeof(buff), "SYS A: %c: > NUL", cselecteddrive);
461
      snprintf(buff, sizeof(buff), "SYS A: %c: > NUL", cselecteddrive);
462
      system(buff);
462
      system(buff);
463
      snprintf(buff, sizeof(buff), "%c:\\TEMP", cselecteddrive);
463
      snprintf(buff, sizeof(buff), "%c:\\TEMP", cselecteddrive);
464
      mkdir(buff);
464
      mkdir(buff);
465
      return(cselecteddrive);
465
      return(cselecteddrive);
466
    }
466
    }
467
  }
467
  }
468
}
468
}
469
 
469
 
470
 
470
 
471
/* copy file src into dst, substituting all characters c1 by c2 */
471
/* copy file src into dst, substituting all characters c1 by c2 */
472
static void fcopysub(char *dst, char *src, char c1, char c2) {
472
static void fcopysub(char *dst, char *src, char c1, char c2) {
473
  FILE *fdd, *fds;
473
  FILE *fdd, *fds;
474
  int buff;
474
  int buff;
475
  fds = fopen(src, "rb");
475
  fds = fopen(src, "rb");
476
  if (fds == NULL) return;
476
  if (fds == NULL) return;
477
  fdd = fopen(dst, "wb");
477
  fdd = fopen(dst, "wb");
478
  if (fdd == NULL) {
478
  if (fdd == NULL) {
479
    fclose(fds);
479
    fclose(fds);
480
    return;
480
    return;
481
  }
481
  }
482
  /* */
482
  /* */
483
  for (;;) {
483
  for (;;) {
484
    buff = fgetc(fds);
484
    buff = fgetc(fds);
485
    if (buff == EOF) break;
485
    if (buff == EOF) break;
486
    if (buff == c1) buff = c2;
486
    if (buff == c1) buff = c2;
487
    fprintf(fdd, "%c", buff);
487
    fprintf(fdd, "%c", buff);
488
  }
488
  }
489
  /* close files and return */
489
  /* close files and return */
490
  fclose(fdd);
490
  fclose(fdd);
491
  fclose(fds);
491
  fclose(fds);
492
}
492
}
493
 
493
 
494
 
494
 
495
static void bootfilesgen(int targetdrv, struct slocales *locales, int cdromdrv) {
495
static void bootfilesgen(int targetdrv, struct slocales *locales, int cdromdrv) {
496
  char buff[128];
496
  char buff[128];
497
  char buff2[16];
497
  char buff2[16];
498
  char buff3[16];
498
  char buff3[16];
499
  FILE *fd;
499
  FILE *fd;
500
  /*** CONFIG.SYS ***/
500
  /*** CONFIG.SYS ***/
501
  snprintf(buff, sizeof(buff), "%c:\\CONFIG.SYS", targetdrv);
501
  snprintf(buff, sizeof(buff), "%c:\\CONFIG.SYS", targetdrv);
502
  fd = fopen(buff, "wb");
502
  fd = fopen(buff, "wb");
503
  if (fd == NULL) return;
503
  if (fd == NULL) return;
504
  fprintf(fd, "DOS=UMB,HIGH\r\n");
504
  fprintf(fd, "DOS=UMB,HIGH\r\n"
-
 
505
              "LASTDRIVE=Z\r\n"
505
  fprintf(fd, "FILES=50\r\n");
506
              "FILES=50\r\n");
506
  fprintf(fd, "DEVICE=%c:\\SYSTEM\\SVAROG.386\\BIN\\HIMEMX.EXE\r\n", targetdrv);
507
  fprintf(fd, "DEVICE=%c:\\SYSTEM\\SVAROG.386\\BIN\\HIMEMX.EXE\r\n", targetdrv);
507
  if (strcmp(locales->lang, "EN") == 0) {
508
  if (strcmp(locales->lang, "EN") == 0) {
508
    strcpy(buff, "COMMAND");
509
    strcpy(buff, "COMMAND");
509
  } else {
510
  } else {
510
    snprintf(buff, sizeof(buff), "CMD-%s", locales->lang);
511
    snprintf(buff, sizeof(buff), "CMD-%s", locales->lang);
511
  }
512
  }
512
  fprintf(fd, "SHELLHIGH=%c:\\SYSTEM\\SVAROG.386\\BIN\\%s.COM /E:512 /P\r\n", targetdrv, buff);
513
  fprintf(fd, "SHELLHIGH=%c:\\SYSTEM\\SVAROG.386\\BIN\\%s.COM /E:512 /P\r\n", targetdrv, buff);
513
  fprintf(fd, "REM COUNTRY=001,437,%c:\\SYSTEM\\CONF\\COUNTRY.SYS\r\n", targetdrv);
514
  fprintf(fd, "REM COUNTRY=001,437,%c:\\SYSTEM\\CONF\\COUNTRY.SYS\r\n", targetdrv);
514
  fprintf(fd, "DEVICE=%c:\\SYSTEM\\DRIVERS\\UDVD2\\UDVD2.SYS /D:SVCD0001 /H\r\n", targetdrv);
515
  fprintf(fd, "DEVICE=%c:\\SYSTEM\\DRIVERS\\UDVD2\\UDVD2.SYS /D:SVCD0001 /H\r\n", targetdrv);
515
  fclose(fd);
516
  fclose(fd);
516
  /*** AUTOEXEC.BAT ***/
517
  /*** AUTOEXEC.BAT ***/
517
  snprintf(buff, sizeof(buff), "%c:\\AUTOEXEC.BAT", targetdrv);
518
  snprintf(buff, sizeof(buff), "%c:\\AUTOEXEC.BAT", targetdrv);
518
  fd = fopen(buff, "wb");
519
  fd = fopen(buff, "wb");
519
  if (fd == NULL) return;
520
  if (fd == NULL) return;
520
  fprintf(fd, "@ECHO OFF\r\n");
521
  fprintf(fd, "@ECHO OFF\r\n");
521
  fprintf(fd, "SET TEMP=%c:\\TEMP\r\n", targetdrv);
522
  fprintf(fd, "SET TEMP=%c:\\TEMP\r\n", targetdrv);
522
  fprintf(fd, "SET DOSDIR=%c:\\SYSTEM\\SVAROG.386\r\n", targetdrv);
523
  fprintf(fd, "SET DOSDIR=%c:\\SYSTEM\\SVAROG.386\r\n", targetdrv);
523
  fprintf(fd, "SET NLSPATH=%%DOSDIR%%\\NLS\r\n");
524
  fprintf(fd, "SET NLSPATH=%%DOSDIR%%\\NLS\r\n");
524
  fprintf(fd, "SET LANG=%s\r\n", locales->lang);
525
  fprintf(fd, "SET LANG=%s\r\n", locales->lang);
525
  fprintf(fd, "SET DIRCMD=/OGNE/P/4\r\n");
526
  fprintf(fd, "SET DIRCMD=/OGNE/P/4\r\n");
526
  fprintf(fd, "SET FDNPKG.CFG=%c:\\SYSTEM\\CFG\\FDNPKG.CFG\r\n", targetdrv);
527
  fprintf(fd, "SET FDNPKG.CFG=%c:\\SYSTEM\\CFG\\FDNPKG.CFG\r\n", targetdrv);
527
  fprintf(fd, "SET WATTCP.CFG=%c:\\SYSTEM\\CFG\\WATTCP.CFG\r\n", targetdrv);
528
  fprintf(fd, "SET WATTCP.CFG=%c:\\SYSTEM\\CFG\\WATTCP.CFG\r\n", targetdrv);
528
  fprintf(fd, "PATH %%DOSDIR%%\\BIN;%c:\\SYSTEM\\LINKS\r\n", targetdrv);
529
  fprintf(fd, "PATH %%DOSDIR%%\\BIN;%c:\\SYSTEM\\LINKS\r\n", targetdrv);
529
  fprintf(fd, "PROMPT $P$G\r\n");
530
  fprintf(fd, "PROMPT $P$G\r\n");
530
  fprintf(fd, "ALIAS REBOOT=FDAPM COLDBOOT\r\n");
531
  fprintf(fd, "ALIAS REBOOT=FDAPM COLDBOOT\r\n");
531
  fprintf(fd, "ALIAS HALT=FDAPM POWEROFF\r\n");
532
  fprintf(fd, "ALIAS HALT=FDAPM POWEROFF\r\n");
532
  fprintf(fd, "FDAPM APMDOS\r\n");
533
  fprintf(fd, "FDAPM APMDOS\r\n");
533
  fprintf(fd, "\r\n");
534
  fprintf(fd, "\r\n");
534
  if (locales->egafile > 0) {
535
  if (locales->egafile > 0) {
535
    fprintf(fd, "DISPLAY CON=(EGA,,1)\r\n");
536
    fprintf(fd, "DISPLAY CON=(EGA,,1)\r\n");
536
    if (locales->egafile == 1) {
537
    if (locales->egafile == 1) {
537
      fprintf(fd, "MODE CON CP PREPARE=((%u) %c:\\SYSTEM\\SVAROG.386\\CPI\\EGA.CPX)\r\n", locales->codepage, targetdrv);
538
      fprintf(fd, "MODE CON CP PREPARE=((%u) %c:\\SYSTEM\\SVAROG.386\\CPI\\EGA.CPX)\r\n", locales->codepage, targetdrv);
538
    } else {
539
    } else {
539
      fprintf(fd, "MODE CON CP PREPARE=((%u) %c:\\SYSTEM\\SVAROG.386\\CPI\\EGA%d.CPX)\r\n", locales->codepage, targetdrv, locales->egafile);
540
      fprintf(fd, "MODE CON CP PREPARE=((%u) %c:\\SYSTEM\\SVAROG.386\\CPI\\EGA%d.CPX)\r\n", locales->codepage, targetdrv, locales->egafile);
540
    }
541
    }
541
    fprintf(fd, "MODE CON CP SELECT=%u\r\n", locales->codepage);
542
    fprintf(fd, "MODE CON CP SELECT=%u\r\n", locales->codepage);
542
  }
543
  }
543
  if (locales->keybfile > 0) {
544
  if (locales->keybfile > 0) {
544
    if (locales->keybfile == 1) {
545
    if (locales->keybfile == 1) {
545
      snprintf(buff2, sizeof(buff2), "KEYBOARD.SYS");
546
      snprintf(buff2, sizeof(buff2), "KEYBOARD.SYS");
546
    } else {
547
    } else {
547
      snprintf(buff2, sizeof(buff2), "KEYBRD%d.SYS", locales->keybfile);
548
      snprintf(buff2, sizeof(buff2), "KEYBRD%d.SYS", locales->keybfile);
548
    }
549
    }
549
    if (locales->keybid == 0) {
550
    if (locales->keybid == 0) {
550
      buff3[0] = 0;
551
      buff3[0] = 0;
551
    } else {
552
    } else {
552
      snprintf(buff3, sizeof(buff3), " /ID:%d", locales->keybid);
553
      snprintf(buff3, sizeof(buff3), " /ID:%d", locales->keybid);
553
    }
554
    }
554
    fprintf(fd, "KEYB %s,%d,%c:\\SYSTEM\\SVAROG.386\\BIN\\%s%s\r\n", locales->keybcode, locales->codepage, targetdrv, buff2, buff3);
555
    fprintf(fd, "KEYB %s,%d,%c:\\SYSTEM\\SVAROG.386\\BIN\\%s%s\r\n", locales->keybcode, locales->codepage, targetdrv, buff2, buff3);
555
    fprintf(fd, "\r\n");
556
    fprintf(fd, "\r\n");
556
  }
557
  }
557
  fprintf(fd, "SHSUCDX /d:SVCD0001\r\n");
558
  fprintf(fd, "SHSUCDX /d:SVCD0001\r\n");
558
  fprintf(fd, "\r\n");
559
  fprintf(fd, "\r\n");
559
  fprintf(fd, "REM Uncomment the line below for automatic mouse support\r\n");
560
  fprintf(fd, "REM Uncomment the line below for automatic mouse support\r\n");
560
  fprintf(fd, "REM CTMOUSE\r\n");
561
  fprintf(fd, "REM CTMOUSE\r\n");
561
  fprintf(fd, "\r\n");
562
  fprintf(fd, "\r\n");
562
  fprintf(fd, "ECHO.\r\n");
563
  fprintf(fd, "ECHO.\r\n");
563
  fprintf(fd, "ECHO %s\r\n", kittengets(6, 0, "Welcome to Svarog386! Type 'HELP' if you need help."));
564
  fprintf(fd, "ECHO %s\r\n", kittengets(6, 0, "Welcome to Svarog386! Type 'HELP' if you need help."));
564
  fclose(fd);
565
  fclose(fd);
565
  /*** CREATE DIRECTORY FOR OTHER CONFIGURATION FILES ***/
566
  /*** CREATE DIRECTORY FOR OTHER CONFIGURATION FILES ***/
566
  snprintf(buff, sizeof(buff), "%c:\\SYSTEM\\CFG", targetdrv);
567
  snprintf(buff, sizeof(buff), "%c:\\SYSTEM\\CFG", targetdrv);
567
  mkdir(buff);
568
  mkdir(buff);
568
  /*** FDNPKG.CFG ***/
569
  /*** FDNPKG.CFG ***/
569
  snprintf(buff, sizeof(buff), "%c:\\SYSTEM\\CFG\\FDNPKG.CFG", targetdrv);
570
  snprintf(buff, sizeof(buff), "%c:\\SYSTEM\\CFG\\FDNPKG.CFG", targetdrv);
570
  fcopysub(buff, "A:\\DAT\\FDNPKG.CFG", '$', cdromdrv);
571
  fcopysub(buff, "A:\\DAT\\FDNPKG.CFG", '$', cdromdrv);
571
  /*** COUNTRY.SYS ***/
572
  /*** COUNTRY.SYS ***/
572
  /*** PICOTCP ***/
573
  /*** PICOTCP ***/
573
  /*** WATTCP ***/
574
  /*** WATTCP ***/
574
}
575
}
575
 
576
 
576
 
577
 
577
static void installpackages(int targetdrv, int cdromdrv) {
578
static void installpackages(int targetdrv, int cdromdrv) {
578
  char *pkglist[] = {
579
  char *pkglist[] = {
579
    "A:\\UDVD2", /* this one's not part of CORE, hence it's stored right on the floppy */
580
    "A:\\UDVD2", /* this one's not part of CORE, hence it's stored right on the floppy */
580
    "APPEND",
581
    "APPEND",
581
    "ASSIGN",
582
    "ASSIGN",
582
    "ATTRIB",
583
    "ATTRIB",
583
    "CHKDSK",
584
    "CHKDSK",
584
    "CHOICE",
585
    "CHOICE",
585
    "COMMAND",
586
    "COMMAND",
586
    "COMP",
587
    "COMP",
587
    "CPIDOS",
588
    "CPIDOS",
588
    "CTMOUSE",
589
    "CTMOUSE",
589
    "DEBUG",
590
    "DEBUG",
590
    "DEFRAG",
591
    "DEFRAG",
591
    "DELTREE",
592
    "DELTREE",
592
    "DEVLOAD",
593
    "DEVLOAD",
593
    "DISKCOMP",
594
    "DISKCOMP",
594
    "DISKCOPY",
595
    "DISKCOPY",
595
    "DISPLAY",
596
    "DISPLAY",
596
    "DOSFSCK",
597
    "DOSFSCK",
597
    "EDIT",
598
    "EDIT",
598
    "EDLIN",
599
    "EDLIN",
599
    "EXE2BIN",
600
    "EXE2BIN",
600
    "FC",
601
    "FC",
601
    "FDAPM",
602
    "FDAPM",
602
    "FDISK",
603
    "FDISK",
603
    "FDNPKG",
604
    "FDNPKG",
604
    "FIND",
605
    "FIND",
605
    "FORMAT",
606
    "FORMAT",
606
    "HELP",
607
    "HELP",
607
    "HIMEMX",
608
    "HIMEMX",
608
    "KERNEL",
609
    "KERNEL",
609
    "KEYB",
610
    "KEYB",
610
    "KEYB_LAY",
611
    "KEYB_LAY",
611
    "LABEL",
612
    "LABEL",
612
    "LBACACHE",
613
    "LBACACHE",
613
    "MEM",
614
    "MEM",
614
    "MIRROR",
615
    "MIRROR",
615
    "MODE",
616
    "MODE",
616
    "MORE",
617
    "MORE",
617
    "MOVE",
618
    "MOVE",
618
    "NANSI",
619
    "NANSI",
619
    "NLSFUNC",
620
    "NLSFUNC",
620
    "PRINT",
621
    "PRINT",
621
    "RDISK",
622
    "RDISK",
622
    "RECOVER",
623
    "RECOVER",
623
    "REPLACE",
624
    "REPLACE",
624
    "SHARE",
625
    "SHARE",
625
    "SHSUCDX",
626
    "SHSUCDX",
626
    "SORT",
627
    "SORT",
627
    "SWSUBST",
628
    "SWSUBST",
628
    "TREE",
629
    "TREE",
629
    "UNDELETE",
630
    "UNDELETE",
630
    "XCOPY",
631
    "XCOPY",
631
    NULL
632
    NULL
632
  };
633
  };
633
  int i, pkglistlen;
634
  int i, pkglistlen;
634
  char buff[64];
635
  char buff[64];
635
  newscreen(3);
636
  newscreen(3);
636
  /* count how long the pkg list is */
637
  /* count how long the pkg list is */
637
  for (pkglistlen = 0; pkglist[pkglistlen] != NULL; pkglistlen++);
638
  for (pkglistlen = 0; pkglist[pkglistlen] != NULL; pkglistlen++);
638
  /* set DOSDIR and friends */
639
  /* set DOSDIR and friends */
639
  snprintf(buff, sizeof(buff), "%c:\\SYSTEM\\SVAROG.386", targetdrv);
640
  snprintf(buff, sizeof(buff), "%c:\\SYSTEM\\SVAROG.386", targetdrv);
640
  setenv("DOSDIR", buff, 1);
641
  setenv("DOSDIR", buff, 1);
641
  snprintf(buff, sizeof(buff), "%c:\\TEMP", targetdrv);
642
  snprintf(buff, sizeof(buff), "%c:\\TEMP", targetdrv);
642
  setenv("TEMP", buff, 1);
643
  setenv("TEMP", buff, 1);
643
  /* install packages */
644
  /* install packages */
644
  for (i = 0; pkglist[i] != NULL; i++) {
645
  for (i = 0; pkglist[i] != NULL; i++) {
645
    char buff[128];
646
    char buff[128];
646
    snprintf(buff, sizeof(buff), kittengets(4, 0, "Installing package %d/%d: %s"), i+1, pkglistlen, pkglist[i]);
647
    snprintf(buff, sizeof(buff), kittengets(4, 0, "Installing package %d/%d: %s"), i+1, pkglistlen, pkglist[i]);
647
    strcat(buff, "       ");
648
    strcat(buff, "       ");
648
    video_putstring(10, 1, COLOR_BODY[mono], buff, -1);
649
    video_putstring(10, 1, COLOR_BODY[mono], buff, -1);
649
    if (pkglist[i][1] == ':') {
650
    if (pkglist[i][1] == ':') {
650
      snprintf(buff, sizeof(buff), "FDINST INSTALL %s.ZIP > NUL", pkglist[i]);
651
      snprintf(buff, sizeof(buff), "FDINST INSTALL %s.ZIP > NUL", pkglist[i]);
651
    } else {
652
    } else {
652
      snprintf(buff, sizeof(buff), "FDINST INSTALL %c:\\CORE\\%s.ZIP > NUL", cdromdrv, pkglist[i]);
653
      snprintf(buff, sizeof(buff), "FDINST INSTALL %c:\\CORE\\%s.ZIP > NUL", cdromdrv, pkglist[i]);
653
    }
654
    }
654
    system(buff);
655
    system(buff);
655
  }
656
  }
656
}
657
}
657
 
658
 
658
 
659
 
659
static void finalreboot(void) {
660
static void finalreboot(void) {
660
  int y = 9;
661
  int y = 9;
661
  newscreen(2);
662
  newscreen(2);
662
  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.");
663
  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.");
663
  putstringnls(++y, 1, COLOR_BODY[mono], 0, 5, "Press any key...");
664
  putstringnls(++y, 1, COLOR_BODY[mono], 0, 5, "Press any key...");
664
  input_getkey();
665
  input_getkey();
665
  reboot();
666
  reboot();
666
}
667
}
667
 
668
 
668
 
669
 
669
static void loadcp(struct slocales *locales) {
670
static void loadcp(struct slocales *locales) {
670
  char buff[64];
671
  char buff[64];
671
  if (locales->codepage == 437) return;
672
  if (locales->codepage == 437) return;
672
  video_movecursor(1, 0);
673
  video_movecursor(1, 0);
673
  if (locales->egafile == 1) {
674
  if (locales->egafile == 1) {
674
    snprintf(buff, sizeof(buff), "MODE CON CP PREP=((%u) A:\\EGA.CPX) > NUL", locales->codepage);
675
    snprintf(buff, sizeof(buff), "MODE CON CP PREP=((%u) A:\\EGA.CPX) > NUL", locales->codepage);
675
  } else {
676
  } else {
676
    snprintf(buff, sizeof(buff), "MODE CON CP PREP=((%u) A:\\EGA%d.CPX) > NUL", locales->codepage, locales->egafile);
677
    snprintf(buff, sizeof(buff), "MODE CON CP PREP=((%u) A:\\EGA%d.CPX) > NUL", locales->codepage, locales->egafile);
677
  }
678
  }
678
  system(buff);
679
  system(buff);
679
  snprintf(buff, sizeof(buff), "MODE CON CP SEL=%u > NUL", locales->codepage);
680
  snprintf(buff, sizeof(buff), "MODE CON CP SEL=%u > NUL", locales->codepage);
680
  system(buff);
681
  system(buff);
681
  /* below I re-init the video controller - apparently this is required if
682
  /* below I re-init the video controller - apparently this is required if
682
   * I want the new glyph symbols to be actually applied, at least some
683
   * I want the new glyph symbols to be actually applied, at least some
683
   * (broken?) BIOSes, like VBox, apply glyphs only at next video mode change */
684
   * (broken?) BIOSes, like VBox, apply glyphs only at next video mode change */
684
  {
685
  {
685
  union REGS r;
686
  union REGS r;
686
  r.h.ah = 0x0F; /* get current video mode */
687
  r.h.ah = 0x0F; /* get current video mode */
687
  int86(0x10, &r, &r); /* r.h.al contains the current video mode now */
688
  int86(0x10, &r, &r); /* r.h.al contains the current video mode now */
688
  r.h.al |= 128; /* set the high bit of AL to instruct BIOS not to flush VRAM's content (EGA+) */
689
  r.h.al |= 128; /* set the high bit of AL to instruct BIOS not to flush VRAM's content (EGA+) */
689
  r.h.ah = 0; /* re-set video mode (to whatever is set in AL) */
690
  r.h.ah = 0; /* re-set video mode (to whatever is set in AL) */
690
  int86(0x10, &r, &r);
691
  int86(0x10, &r, &r);
691
  }
692
  }
692
}
693
}
693
 
694
 
694
/* checks CD drive drv for the presence of the Svarog386 install CD
695
/* checks CD drive drv for the presence of the Svarog386 install CD
695
 * returns 0 if found, non-zero otherwise */
696
 * returns 0 if found, non-zero otherwise */
696
static int checkcd(char drv) {
697
static int checkcd(char drv) {
697
  FILE *fd;
698
  FILE *fd;
698
  char fname[32];
699
  char fname[32];
699
  snprintf(fname, sizeof(fname), "%c:\\CORE\\MEM.ZIP", drv);
700
  snprintf(fname, sizeof(fname), "%c:\\CORE\\MEM.ZIP", drv);
700
  fd = fopen(fname, "rb");
701
  fd = fopen(fname, "rb");
701
  if (fd == NULL) return(-1);
702
  if (fd == NULL) return(-1);
702
  fclose(fd);
703
  fclose(fd);
703
  return(0);
704
  return(0);
704
}
705
}
705
 
706
 
706
 
707
 
707
int main(void) {
708
int main(void) {
708
  struct slocales locales;
709
  struct slocales locales;
709
  int targetdrv;
710
  int targetdrv;
710
  int cdromdrv;
711
  int cdromdrv;
711
  int action;
712
  int action;
712
 
713
 
713
  /* find where the cdrom drive is */
714
  /* find where the cdrom drive is */
714
  cdromdrv = cdrom_findfirst();
715
  cdromdrv = cdrom_findfirst();
715
  if (cdromdrv < 0) {
716
  if (cdromdrv < 0) {
716
    printf("ERROR: CD-ROM DRIVE NOT FOUND\r\n");
717
    printf("ERROR: CD-ROM DRIVE NOT FOUND\r\n");
717
    return(1);
718
    return(1);
718
  }
719
  }
719
  cdromdrv += 'A'; /* convert the cdrom 'id' (A=0) to an actual drive letter */
720
  cdromdrv += 'A'; /* convert the cdrom 'id' (A=0) to an actual drive letter */
720
  if (checkcd(cdromdrv) != 0) {
721
  if (checkcd(cdromdrv) != 0) {
721
    printf("ERROR: SVAROG386 INSTALLATION CD NOT FOUND IN THE DRIVE.\r\n");
722
    printf("ERROR: SVAROG386 INSTALLATION CD NOT FOUND IN THE DRIVE.\r\n");
722
    return(1);
723
    return(1);
723
  }
724
  }
724
 
725
 
725
  /* init screen and detect mono status */
726
  /* init screen and detect mono status */
726
  mono = video_init();
727
  mono = video_init();
727
 
728
 
728
  kittenopen("INSTALL"); /* load initial NLS support */
729
  kittenopen("INSTALL"); /* load initial NLS support */
729
 
730
 
730
 SelectLang:
731
 SelectLang:
731
  action = selectlang(&locales); /* welcome to svarog, select your language */
732
  action = selectlang(&locales); /* welcome to svarog, select your language */
732
  if (action != MENUNEXT) goto Quit;
733
  if (action != MENUNEXT) goto Quit;
733
  setenv("LANG", locales.lang, 1);
734
  setenv("LANG", locales.lang, 1);
734
  loadcp(&locales);
735
  loadcp(&locales);
735
  kittenclose(); /* reload NLS with new language */
736
  kittenclose(); /* reload NLS with new language */
736
  kittenopen("INSTALL"); /* NLS support */
737
  kittenopen("INSTALL"); /* NLS support */
737
  action = selectkeyb(&locales);  /* what keyb layout should we use? */
738
  action = selectkeyb(&locales);  /* what keyb layout should we use? */
738
  if (action == MENUQUIT) goto Quit;
739
  if (action == MENUQUIT) goto Quit;
739
  if (action == MENUPREV) goto SelectLang;
740
  if (action == MENUPREV) goto SelectLang;
740
 
741
 
741
 WelcomeScreen:
742
 WelcomeScreen:
742
  action = welcomescreen(); /* what svarog386 is, ask whether to run live dos or install */
743
  action = welcomescreen(); /* what svarog386 is, ask whether to run live dos or install */
743
  if (action == MENUQUIT) goto Quit;
744
  if (action == MENUQUIT) goto Quit;
744
  if (action == MENUPREV) goto SelectLang;
745
  if (action == MENUPREV) goto SelectLang;
745
  targetdrv = preparedrive(); /* what drive should we install to? check avail. space */
746
  targetdrv = preparedrive(); /* what drive should we install to? check avail. space */
746
  if (targetdrv == MENUQUIT) goto Quit;
747
  if (targetdrv == MENUQUIT) goto Quit;
747
  if (targetdrv == MENUPREV) goto WelcomeScreen;
748
  if (targetdrv == MENUPREV) goto WelcomeScreen;
748
  /*askaboutsources();*/ /* IF sources are available, ask if installing with them */
749
  /*askaboutsources();*/ /* IF sources are available, ask if installing with them */
749
  installpackages(targetdrv, cdromdrv);    /* install packages */
750
  installpackages(targetdrv, cdromdrv);    /* install packages */
750
  bootfilesgen(targetdrv, &locales, cdromdrv); /* generate boot files and other configurations */
751
  bootfilesgen(targetdrv, &locales, cdromdrv); /* generate boot files and other configurations */
751
  /*localcfg();*/ /* show local params (currency, etc), and propose to change them (based on localcfg) */
752
  /*localcfg();*/ /* show local params (currency, etc), and propose to change them (based on localcfg) */
752
  /*netcfg();*/ /* basic networking config */
753
  /*netcfg();*/ /* basic networking config */
753
  finalreboot(); /* remove the CD and reboot */
754
  finalreboot(); /* remove the CD and reboot */
754
 
755
 
755
 Quit:
756
 Quit:
756
  kittenclose(); /* close NLS support */
757
  kittenclose(); /* close NLS support */
757
  video_clear(0x0700, 0, 0);
758
  video_clear(0x0700, 0, 0);
758
  video_movecursor(0, 0);
759
  video_movecursor(0, 0);
759
  return(0);
760
  return(0);
760
}
761
}
761
 
762