Subversion Repositories SvarDOS

Rev

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