Subversion Repositories SvarDOS

Rev

Rev 77 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

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