Subversion Repositories SvarDOS

Rev

Rev 62 | Rev 67 | 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",
65 mv_fox 183
/*    "French\0FR",*/
28 mv_fox 184
    "Polish\0PL",
65 mv_fox 185
/*    "Turkish\0TR",*/
28 mv_fox 186
    NULL
187
  };
188
 
189
  newscreen();
42 mv_fox 190
  msg = kittengets(1, 0, "Welcome to Svarog386");
191
  x = 40 - (strlen(msg) >> 1);
56 mv_fox 192
  video_putstring(4, x, COLOR_BODY[mono], msg, -1);
42 mv_fox 193
  video_putcharmulti(5, x, COLOR_BODY[mono], '=', strlen(msg), 1);
49 mv_fox 194
  putstringnls(8, -1, COLOR_BODY[mono], 1, 1, "Please select your language from the list below:");
65 mv_fox 195
  choice = menuselect(11, -1, 3, langlist);
28 mv_fox 196
  if (choice < 0) return(-1);
197
  /* write short language code into lang */
198
  for (code = langlist[choice]; *code != 0; code++);
199
  memcpy(lang, code + 1, 2);
200
  lang[2] = 0;
201
  return(0);
202
}
203
 
204
 
205
/* returns 0 if installation must proceed, non-zero otherwise */
206
static int welcomescreen(void) {
207
  char *choice[] = {"Install Svarog386 to disk", "Quit to DOS", NULL};
42 mv_fox 208
  choice[0] = kittengets(0, 1, choice[0]);
209
  choice[1] = kittengets(0, 2, choice[1]);
28 mv_fox 210
  newscreen();
56 mv_fox 211
  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 212
  return(menuselect(13, -1, 4, choice));
28 mv_fox 213
}
214
 
215
 
33 mv_fox 216
/* returns 1 if drive is removable, 0 if not, -1 on error */
217
static int isdriveremovable(int drv) {
28 mv_fox 218
  union REGS r;
33 mv_fox 219
  r.x.ax = 0x4408;
220
  r.h.bl = drv;
28 mv_fox 221
  int86(0x21, &r, &r);
33 mv_fox 222
  /* CF set on error, AX set to 0 if removable, 1 if fixed */
223
  if (r.x.cflag != 0) return(-1);
224
  if (r.x.ax == 0) return(1);
225
  return(0);
28 mv_fox 226
}
227
 
228
 
35 mv_fox 229
/* returns total disk space of drive drv (in MiB, max 2048), or -1 if drive invalid */
230
static int disksize(int drv) {
28 mv_fox 231
  long res;
232
  union REGS r;
233
  r.h.ah = 0x36; /* DOS 2+ get free disk space */
234
  r.h.dl = drv;
235
  int86(0x21, &r, &r);
236
  if (r.x.ax == 0xffffu) return(-1); /* AX set to FFFFh if drive invalid */
49 mv_fox 237
  res = r.x.ax;  /* sectors per cluster */
238
  res *= r.x.dx; /* dx contains total clusters, bx contains free clusters */
239
  res *= r.x.cx; /* bytes per sector */
240
  res >>= 20;    /* convert bytes to MiB */
241
  return(res);
35 mv_fox 242
}
243
 
244
 
245
/* returns 0 if disk is empty, non-zero otherwise */
246
static int diskempty(int drv) {
247
  unsigned int rc;
248
  int res;
249
  char buff[8];
250
  struct find_t fileinfo;
55 mv_fox 251
  snprintf(buff, sizeof(buff), "%c:\\*.*", 'A' + drv - 1);
35 mv_fox 252
  rc = _dos_findfirst(buff, _A_NORMAL | _A_SUBDIR | _A_HIDDEN | _A_SYSTEM, &fileinfo);
253
  if (rc == 0) {
254
    res = 1; /* call successfull means disk is not empty */
28 mv_fox 255
  } else {
35 mv_fox 256
    res = 0;
28 mv_fox 257
  }
35 mv_fox 258
  /* _dos_findclose(&fileinfo); */ /* apparently required only on OS/2 */
28 mv_fox 259
  return(res);
260
}
261
 
262
 
263
static int preparedrive(void) {
33 mv_fox 264
  int driveremovable;
36 mv_fox 265
  int selecteddrive = 3; /* hardcoded to 'C:' for now */
266
  int cselecteddrive;
35 mv_fox 267
  int ds;
56 mv_fox 268
  char buff[1024];
36 mv_fox 269
  cselecteddrive = 'A' + selecteddrive - 1;
28 mv_fox 270
  for (;;) {
271
    newscreen();
33 mv_fox 272
    driveremovable = isdriveremovable(selecteddrive);
273
    if (driveremovable < 0) {
49 mv_fox 274
      char *list[] = { "Create a partition automatically", "Run the FDISK partitioning tool", "Quit to DOS", NULL};
42 mv_fox 275
      list[0] = kittengets(0, 3, list[0]);
276
      list[1] = kittengets(0, 4, list[1]);
277
      list[2] = kittengets(0, 2, list[2]);
56 mv_fox 278
      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 279
      putstringwrap(4, 1, COLOR_BODY[mono], buff);
33 mv_fox 280
      switch (menuselect(14, -1, 5, list)) {
281
        case 0:
282
          system("FDISK /AUTO");
283
          break;
284
        case 1:
285
          video_clear(0x0700, 0);
286
          video_movecursor(0, 0);
287
          system("FDISK");
288
          break;
56 mv_fox 289
        default:
33 mv_fox 290
          return(-1);
291
      }
28 mv_fox 292
      newscreen();
61 mv_fox 293
      putstringnls(10, 10, COLOR_BODY[mono], 3, 1, "Your computer will reboot now.");
42 mv_fox 294
      putstringnls(12, 10, COLOR_BODY[mono], 0, 5, "Press any key...");
33 mv_fox 295
      input_getkey();
28 mv_fox 296
      reboot();
297
      return(-1);
33 mv_fox 298
    } else if (driveremovable > 0) {
56 mv_fox 299
      snprintf(buff, sizeof(buff), kittengets(3, 2, "ERROR: Drive %c: is a removable device. Installation aborted."), cselecteddrive);
61 mv_fox 300
      video_putstring(9, 1, COLOR_BODY[mono], buff, -1);
42 mv_fox 301
      putstringnls(11, 2, COLOR_BODY[mono], 0, 5, "Press any key...");
33 mv_fox 302
      return(-1);
28 mv_fox 303
    }
33 mv_fox 304
    /* if not formatted, propose to format it right away (try to create a directory) */
55 mv_fox 305
    snprintf(buff, sizeof(buff), "%c:\\SVWRTEST.123", cselecteddrive);
53 mv_fox 306
    if (mkdir(buff) == 0) {
307
      rmdir(buff);
308
    } else {
28 mv_fox 309
      char *list[] = { "Proceed with formatting", "Quit to DOS", NULL};
42 mv_fox 310
      list[0] = kittengets(0, 6, list[0]);
311
      list[1] = kittengets(0, 2, list[1]);
56 mv_fox 312
      snprintf(buff, sizeof(buff), kittengets(3, 3, "ERROR: Drive %c: seems to be unformated. Do you wish to format it?"), cselecteddrive);
61 mv_fox 313
      video_putstring(7, 1, COLOR_BODY[mono], buff, -1);
28 mv_fox 314
      if (menuselect(12, -1, 4, list) != 0) return(-1);
315
      video_clear(0x0700, 0);
316
      video_movecursor(0, 0);
55 mv_fox 317
      snprintf(buff, sizeof(buff), "FORMAT %c: /Q /U /Z:seriously /V:SVAROG386", cselecteddrive);
36 mv_fox 318
      system(buff);
28 mv_fox 319
      continue;
320
    }
33 mv_fox 321
    /* check total disk space */
35 mv_fox 322
    ds = disksize(selecteddrive);
47 mv_fox 323
    if (ds < SVAROG_DISK_REQ) {
56 mv_fox 324
      int y = 9;
325
      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 326
      y += putstringwrap(y, 1, COLOR_BODY[mono], buff);
56 mv_fox 327
      putstringnls(++y, 2, COLOR_BODY[mono], 0, 5, "Press any key...");
28 mv_fox 328
      input_getkey();
329
      return(-1);
330
    }
331
    /* is the disk empty? */
35 mv_fox 332
    if (diskempty(selecteddrive) != 0) {
28 mv_fox 333
      char *list[] = { "Proceed with formatting", "Quit to DOS", NULL};
65 mv_fox 334
      int y = 6;
42 mv_fox 335
      list[0] = kittengets(0, 6, list[0]);
336
      list[1] = kittengets(0, 2, list[1]);
56 mv_fox 337
      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 338
      y += putstringwrap(y, 1, COLOR_BODY[mono], buff);
339
      if (menuselect(++y, -1, 4, list) != 0) return(-1);
28 mv_fox 340
      video_clear(0x0700, 0);
341
      video_movecursor(0, 0);
55 mv_fox 342
      snprintf(buff, sizeof(buff), "FORMAT %c: /Q /U /Z:seriously /V:SVAROG386", cselecteddrive);
42 mv_fox 343
      system(buff);
28 mv_fox 344
      continue;
345
    } else {
346
      /* final confirmation */
347
      char *list[] = { "Install Svarog386", "Quit to DOS", NULL};
42 mv_fox 348
      list[0] = kittengets(0, 1, list[0]);
349
      list[1] = kittengets(0, 2, list[1]);
56 mv_fox 350
      snprintf(buff, sizeof(buff), kittengets(3, 6, "The installation of Svarog386 to %c: is about to begin."), cselecteddrive);
351
      video_putstring(7, -1, COLOR_BODY[mono], buff, -1);
28 mv_fox 352
      if (menuselect(10, -1, 4, list) != 0) return(-1);
62 mv_fox 353
      snprintf(buff, sizeof(buff), "SYS A: %c: > NUL", cselecteddrive);
36 mv_fox 354
      system(buff);
55 mv_fox 355
      snprintf(buff, sizeof(buff), "%c:\\TEMP", cselecteddrive);
36 mv_fox 356
      mkdir(buff);
357
      return(cselecteddrive);
28 mv_fox 358
    }
359
  }
360
}
361
 
362
 
53 mv_fox 363
/* copy file src into dst, substituting all characters c1 by c2 */
364
static void fcopysub(char *dst, char *src, char c1, char c2) {
365
  FILE *fdd, *fds;
366
  int buff;
367
  fds = fopen(src, "rb");
368
  if (fds == NULL) return;
369
  fdd = fopen(dst, "wb");
370
  if (fdd == NULL) {
371
    fclose(fds);
372
    return;
373
  }
374
  /* */
375
  for (;;) {
376
    buff = fgetc(fds);
377
    if (buff == EOF) break;
378
    if (buff == c1) buff = c2;
379
    fprintf(fdd, "%c", buff);
380
  }
381
  /* close files and return */
382
  fclose(fdd);
383
  fclose(fds);
384
}
385
 
386
 
387
static void bootfilesgen(int targetdrv, char *lang, int cdromdrv) {
28 mv_fox 388
  char buff[128];
49 mv_fox 389
  int cp, egafile;
28 mv_fox 390
  FILE *fd;
49 mv_fox 391
  cp = getnlscp(lang, &egafile);
53 mv_fox 392
  /*** CONFIG.SYS ***/
55 mv_fox 393
  snprintf(buff, sizeof(buff), "%c:\\CONFIG.SYS", targetdrv);
53 mv_fox 394
  fd = fopen(buff, "wb");
395
  if (fd == NULL) return;
396
  fprintf(fd, "DOS=UMB,HIGH\r\n");
397
  fprintf(fd, "FILES=50\r\n");
398
  fprintf(fd, "DEVICE=%c:\\SYSTEM\\SVAROG.386\\BIN\\HIMEMX.EXE\r\n", targetdrv);
399
  fprintf(fd, "SHELLHIGH=%c:\\SYSTEM\\SVAROG.386\\BIN\\COMMAND.COM /E:512 /P\r\n", targetdrv);
400
  fprintf(fd, "REM COUNTRY=001,437,%c:\\SYSTEM\\CONF\\COUNTRY.SYS\r\n", targetdrv);
401
  fprintf(fd, "DEVICE=%c:\\SYSTEM\\DRIVERS\\UDVD2\\UDVD2.SYS /D:SVCD0001 /H\r\n", targetdrv);
402
  fclose(fd);
28 mv_fox 403
  /*** AUTOEXEC.BAT ***/
55 mv_fox 404
  snprintf(buff, sizeof(buff), "%c:\\AUTOEXEC.BAT", targetdrv);
28 mv_fox 405
  fd = fopen(buff, "wb");
406
  if (fd == NULL) return;
407
  fprintf(fd, "@ECHO OFF\r\n");
36 mv_fox 408
  fprintf(fd, "SET TEMP=%c:\\TEMP\r\n", targetdrv);
409
  fprintf(fd, "SET DOSDIR=%c:\\SYSTEM\\SVAROG.386\r\n", targetdrv);
49 mv_fox 410
  fprintf(fd, "SET NLSPATH=%%DOSDIR%%\\NLS\r\n");
28 mv_fox 411
  fprintf(fd, "SET LANG=%s\r\n", lang);
53 mv_fox 412
  fprintf(fd, "SET DIRCMD=/OGNE/P/4\r\n");
413
  fprintf(fd, "SET FDNPKG.CFG=%c:\\SYSTEM\\CFG\\FDNPKG.CFG\r\n", targetdrv);
414
  fprintf(fd, "SET WATTCP.CFG=%c:\\SYSTEM\\CFG\\WATTCP.CFG\r\n", targetdrv);
415
  fprintf(fd, "PATH %%DOSDIR%%\\BIN;%c:\\SYSTEM\\LINKS\r\n", targetdrv);
28 mv_fox 416
  fprintf(fd, "PROMPT $P$G\r\n");
30 mv_fox 417
  fprintf(fd, "ALIAS REBOOT=FDAPM COLDBOOT\r\n");
418
  fprintf(fd, "ALIAS HALT=FDAPM POWEROFF\r\n");
56 mv_fox 419
  fprintf(fd, "FDAPM APMDOS\r\n");
28 mv_fox 420
  fprintf(fd, "\r\n");
49 mv_fox 421
  if (egafile > 0) {
55 mv_fox 422
    fprintf(fd, "DISPLAY CON=(EGA,,1)\r\n");
49 mv_fox 423
    if (egafile == 1) {
424
      fprintf(fd, "MODE CON CP PREPARE=((%d) %c:\\SYSTEM\\SVAROG.386\\CPI\\EGA.CPX)\r\n", cp, targetdrv);
425
    } else {
426
      fprintf(fd, "MODE CON CP PREPARE=((%d) %c:\\SYSTEM\\SVAROG.386\\CPI\\EGA%d.CPX)\r\n", cp, targetdrv, egafile);
427
    }
428
    fprintf(fd, "MODE CON CP SELECT=%d\r\n", cp);
429
    fprintf(fd, "\r\n");
430
  }
431
  fprintf(fd, "SHSUCDX /d:SVCD0001\r\n");
432
  fprintf(fd, "\r\n");
433
  fprintf(fd, "REM Uncomment the line below for automatic mouse support\r\n");
434
  fprintf(fd, "REM CTMOUSE\r\n");
435
  fprintf(fd, "\r\n");
53 mv_fox 436
  fprintf(fd, "ECHO.\r\n");
55 mv_fox 437
  fprintf(fd, "ECHO Welcome to Svarog386! Type 'HELP' if you need help.\r\n");
28 mv_fox 438
  fclose(fd);
53 mv_fox 439
  /*** CREATE DIRECTORY FOR OTHER CONFIGURATION FILES ***/
440
  snprintf(buff, sizeof(buff), "%c:\\SYSTEM\\CFG", targetdrv);
441
  mkdir(buff);
442
  /*** FDNPKG.CFG ***/
443
  snprintf(buff, sizeof(buff), "%c:\\SYSTEM\\CFG\\FDNPKG.CFG", targetdrv);
444
  fcopysub(buff, "A:\\DAT\\FDNPKG.CFG", '$', cdromdrv);
445
  /*** COUNTRY.SYS ***/
446
  /*** PICOTCP ***/
447
  /*** WATTCP ***/
28 mv_fox 448
}
449
 
450
 
53 mv_fox 451
static void installpackages(int targetdrv, int cdromdrv) {
28 mv_fox 452
  char *pkglist[] = {
55 mv_fox 453
    "A:\\UDVD2", /* this one's not part of CORE, hence it's stored right on the floppy */
28 mv_fox 454
    "APPEND",
455
    "ASSIGN",
456
    "ATTRIB",
457
    "CHKDSK",
458
    "CHOICE",
459
    "COMMAND",
460
    "COMP",
461
    "CPIDOS",
462
    "CTMOUSE",
463
    "DEBUG",
464
    "DEFRAG",
465
    "DELTREE",
466
    "DEVLOAD",
467
    "DISKCOMP",
468
    "DISKCOPY",
469
    "DISPLAY",
470
    "DOSFSCK",
471
    "EDIT",
472
    "EDLIN",
473
    "EXE2BIN",
474
    "FC",
475
    "FDAPM",
476
    "FDISK",
477
    "FDNPKG",
478
    "FIND",
479
    "FORMAT",
480
    "HELP",
481
    "HIMEMX",
482
    "KERNEL",
483
    "KEYB",
65 mv_fox 484
    "KEYB_LAY",
28 mv_fox 485
    "LABEL",
486
    "LBACACHE",
487
    "MEM",
488
    "MIRROR",
489
    "MODE",
490
    "MORE",
491
    "MOVE",
492
    "NANSI",
493
    "NLSFUNC",
494
    "PRINT",
495
    "RDISK",
496
    "RECOVER",
497
    "REPLACE",
498
    "SHARE",
499
    "SHSUCDX",
500
    "SORT",
501
    "SWSUBST",
502
    "TREE",
503
    "UNDELETE",
504
    "XCOPY",
505
    NULL
506
  };
30 mv_fox 507
  int i, pkglistlen;
46 mv_fox 508
  char buff[64];
28 mv_fox 509
  newscreen();
30 mv_fox 510
  /* count how long the pkg list is */
511
  for (pkglistlen = 0; pkglist[pkglistlen] != NULL; pkglistlen++);
46 mv_fox 512
  /* set DOSDIR and friends */
513
  snprintf(buff, sizeof(buff), "%c:\\SYSTEM\\SVAROG.386", targetdrv);
514
  setenv("DOSDIR", buff, 1);
515
  snprintf(buff, sizeof(buff), "%c:\\TEMP", targetdrv);
516
  setenv("TEMP", buff, 1);
30 mv_fox 517
  /* install packages */
28 mv_fox 518
  for (i = 0; pkglist[i] != NULL; i++) {
36 mv_fox 519
    char buff[128];
42 mv_fox 520
    snprintf(buff, sizeof(buff), kittengets(4, 0, "Installing package %d/%d: %s"), i+1, pkglistlen, pkglist[i]);
36 mv_fox 521
    strcat(buff, "       ");
61 mv_fox 522
    video_putstring(10, 1, COLOR_BODY[mono], buff, -1);
55 mv_fox 523
    if (pkglist[i][1] == ':') {
524
      snprintf(buff, sizeof(buff), "FDINST INSTALL %s.ZIP > NUL", pkglist[i]);
525
    } else {
526
      snprintf(buff, sizeof(buff), "FDINST INSTALL %c:\\CORE\\%s.ZIP > NUL", cdromdrv, pkglist[i]);
527
    }
28 mv_fox 528
    system(buff);
529
  }
530
}
531
 
532
 
42 mv_fox 533
static void finalreboot(void) {
56 mv_fox 534
  int y = 9;
42 mv_fox 535
  newscreen();
56 mv_fox 536
  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 537
  putstringnls(++y, 1, COLOR_BODY[mono], 0, 5, "Press any key...");
42 mv_fox 538
  input_getkey();
539
  reboot();
540
}
541
 
542
 
543
static void loadcp(char *lang) {
544
  int cp, egafile;
545
  char buff[64];
546
  cp = getnlscp(lang, &egafile);
547
  if (cp == 437) return;
548
  video_movecursor(1, 0);
549
  if (egafile == 1) {
56 mv_fox 550
    snprintf(buff, sizeof(buff), "MODE CON CP PREP=((%d) A:\\EGA.CPX) > NUL", cp);
42 mv_fox 551
  } else {
56 mv_fox 552
    snprintf(buff, sizeof(buff), "MODE CON CP PREP=((%d) A:\\EGA%d.CPX) > NUL", cp, egafile);
42 mv_fox 553
  }
554
  system(buff);
56 mv_fox 555
  snprintf(buff, sizeof(buff), "MODE CON CP SEL=%d > NUL", cp);
42 mv_fox 556
  system(buff);
557
  /* below I re-init the video controller - apparently this is required if
65 mv_fox 558
   * I want the new glyph symbols to be actually applied, at least some
559
   * (broken?) BIOSes, like VBox, apply glyphs only at next video mode change */
42 mv_fox 560
  {
561
  union REGS r;
562
  r.h.ah = 0x0F; /* get current video mode */
563
  int86(0x10, &r, &r); /* r.h.al contains the current video mode now */
56 mv_fox 564
  r.h.al |= 128; /* set the high bit of AL to instruct BIOS not to flush VRAM's content (EGA+) */
565
  r.h.ah = 0; /* re-set video mode (to whatever is set in AL) */
42 mv_fox 566
  int86(0x10, &r, &r);
567
  }
568
}
569
 
570
 
65 mv_fox 571
/* checks CD drive drv for the presence of the Svarog386 install CD
572
 * returns 0 if found, non-zero otherwise */
573
static int checkcd(char drv) {
574
  FILE *fd;
575
  char fname[32];
576
  snprintf(fname, sizeof(fname), "%c:\\CORE\\MEM.ZIP", drv);
577
  fd = fopen(fname, "rb");
578
  if (fd == NULL) return(-1);
579
  fclose(fd);
580
  return(0);
581
}
582
 
583
 
28 mv_fox 584
int main(void) {
585
  char lang[4];
586
  int targetdrv;
53 mv_fox 587
  int cdromdrv;
28 mv_fox 588
 
53 mv_fox 589
  /* find where the cdrom drive is */
590
  cdromdrv = cdrom_findfirst();
591
  if (cdromdrv < 0) {
592
    printf("ERROR: CD-ROM DRIVE NOT FOUND\r\n");
593
    return(1);
594
  }
595
  cdromdrv += 'A'; /* convert the cdrom 'id' (A=0) to an actual drive letter */
65 mv_fox 596
  if (checkcd(cdromdrv) != 0) {
597
    printf("ERROR: SVAROG386 INSTALLATION CD NOT FOUND IN THE DRIVE.\r\n");
598
    return(1);
599
  }
53 mv_fox 600
 
29 mv_fox 601
  /* init screen and detect mono status */
602
  mono = video_init();
603
 
28 mv_fox 604
  for (;;) { /* fake loop, it's here just to break out easily */
61 mv_fox 605
    kittenopen("INSTALL"); /* NLS support */
28 mv_fox 606
    if (selectlang(lang) < 0) break; /* welcome to svarog, select your language */
42 mv_fox 607
    setenv("LANG", lang, 1);
608
    loadcp(lang);
61 mv_fox 609
    kittenclose(); /* reload NLS with new language */
42 mv_fox 610
    kittenopen("INSTALL"); /* NLS support */
30 mv_fox 611
    /*selectkeyb();*/ /* what keyb layout should we use? */
28 mv_fox 612
    if (welcomescreen() != 0) break; /* what svarog386 is, ask whether to run live dos or install */
613
    targetdrv = preparedrive(); /* what drive should we install to? check avail. space */
614
    if (targetdrv < 0) break;
615
    /*askaboutsources();*/ /* IF sources are available, ask if installing with them */
53 mv_fox 616
    installpackages(targetdrv, cdromdrv);    /* install packages */
617
    bootfilesgen(targetdrv, lang, cdromdrv); /* generate boot files and other configurations */
28 mv_fox 618
    /*localcfg();*/ /* show local params (currency, etc), and propose to change them (based on localcfg) */
42 mv_fox 619
    /*netcfg();*/ /* basic networking config */
28 mv_fox 620
    finalreboot(); /* remove the CD and reboot */
621
    break;
622
  }
42 mv_fox 623
  kittenclose(); /* close NLS support */
28 mv_fox 624
  video_clear(0x0700, 0);
625
  video_movecursor(0, 0);
626
  return(0);
627
}