Subversion Repositories SvarDOS

Rev

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