Subversion Repositories SvarDOS

Rev

Rev 35 | 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
4
 */
5
 
6
#include <dos.h>
30 mv_fox 7
#include <direct.h>  /* mkdir() */
28 mv_fox 8
#include <stdio.h>   /* printf() and friends */
9
#include <stdlib.h>  /* system() */
10
#include <string.h>  /* memcpy() */
11
#include <unistd.h>
12
#include "input.h"
13
#include "video.h"
14
 
29 mv_fox 15
/* color scheme (color, mono) */
16
static unsigned short COLOR_TITLEBAR[2] = {0x7000,0x7000};
17
static unsigned short COLOR_BODY[2] = {0x1700,0x0700};
18
static unsigned short COLOR_SELECT[2] = {0x7000,0x7000};
19
static unsigned short COLOR_SELECTCUR[2] = {0x1F00,0x0700};
28 mv_fox 20
 
29 mv_fox 21
/* mono flag */
22
static int mono = 0;
28 mv_fox 23
 
24
 
25
/* reboot the computer */
26
static void reboot(void) {
27
  void ((far *bootroutine)()) = (void (far *)()) 0xFFFF0000L;
28
  int far *rstaddr = (int far *)0x00400072L; /* BIOS boot flag is at 0040:0072 */
29
  *rstaddr = 0x1234; /* 0x1234 = warm boot, 0 = cold boot */
30
  (*bootroutine)(); /* jump to the BIOS reboot routine at FFFF:0000 */
31
}
32
 
33
static int menuselect(int ypos, int xpos, int height, char **list) {
34
  int i, offset = 0, res = 0, count, width = 0;
35
  /* count how many languages there is */
36
  for (count = 0; list[count] != NULL; count++) {
37
    int len = strlen(list[count]);
38
    if (len > width) width = len;
39
  }
40
 
41
  /* if xpos negative, means 'center out' */
42
  if (xpos < 0) xpos = 39 - (width >> 1);
43
 
29 mv_fox 44
  video_putchar(ypos, xpos+width+2, COLOR_SELECT[mono], 0xBF);         /*       \ */
45
  video_putchar(ypos, xpos-1, COLOR_SELECT[mono], 0xDA);               /*  /      */
46
  video_putchar(ypos+height-1, xpos-1, COLOR_SELECT[mono], 0xC0);      /*  \      */
47
  video_putchar(ypos+height-1, xpos+width+2, COLOR_SELECT[mono], 0xD9);/*      /  */
48
  video_putcharmulti(ypos, xpos, COLOR_SELECT[mono], 0xC4, width + 2, 1);
49
  video_putcharmulti(ypos+height-1, xpos, COLOR_SELECT[mono], 0xC4, width + 2, 1);
50
  video_putcharmulti(ypos+1, xpos-1, COLOR_SELECT[mono], 0xB3, height - 2, 80);
51
  video_putcharmulti(ypos+1, xpos+width+2, COLOR_SELECT[mono], 0xB3, height - 2, 80);
28 mv_fox 52
 
53
  for (;;) {
54
    int key;
55
    /* list of selectable items */
56
    for (i = 0; i < height - 2; i++) {
57
      if (i + offset == res) {
29 mv_fox 58
        video_putchar(ypos + 1 + i, xpos, COLOR_SELECTCUR[mono], 16);
59
        video_putchar(ypos + 1 + i, xpos+width+1, COLOR_SELECTCUR[mono], 17);
28 mv_fox 60
        video_movecursor(ypos + 1 + i, xpos);
29 mv_fox 61
        video_putstringfix(ypos + 1 + i, xpos+1, COLOR_SELECTCUR[mono], list[i + offset], width);
28 mv_fox 62
      } else if (i + offset < count) {
29 mv_fox 63
        video_putchar(ypos + 1 + i, xpos, COLOR_SELECT[mono], ' ');
64
        video_putchar(ypos + 1 + i, xpos+width+1, COLOR_SELECT[mono], ' ');
65
        video_putstringfix(ypos + 1 + i, xpos+1, COLOR_SELECT[mono], list[i + offset], width);
28 mv_fox 66
      } else {
29 mv_fox 67
        video_putcharmulti(ypos + 1 + i, xpos, COLOR_SELECT[mono], ' ', width+2, 1);
28 mv_fox 68
      }
69
    }
70
    key = input_getkey();
71
    if (key == 0x0D) { /* ENTER */
72
      return(res);
73
    } else if (key == 0x148) { /* up */
33 mv_fox 74
      if (res > 0) {
75
        res--;
76
        if (res < offset) offset = res;
77
      }
28 mv_fox 78
    } else if (key == 0x150) { /* down */
33 mv_fox 79
      if (res+1 < count) {
80
        res++;
81
        if (res > offset + height - 3) offset = res - (height - 3);
82
      }
83
    } else if (key == 0x147) { /* home */
84
      res = 0;
85
      offset = 0;
86
    } else if (key == 0x14F) { /* end */
87
      res = count - 1;
88
      if (res > offset + height - 3) offset = res - (height - 3);
28 mv_fox 89
    } else if (key == 0x1B) {  /* ESC */
90
      return(-1);
33 mv_fox 91
    } else {
92
      char buf[8];
93
      sprintf(buf, "0x%02X ", key);
94
      video_putstring(1, 0, COLOR_BODY[mono], buf);
28 mv_fox 95
    }
96
  }
97
}
98
 
99
static void newscreen(void) {
100
  int x;
29 mv_fox 101
  for (x = 0; x < 80; x++) video_putchar(0, x, COLOR_TITLEBAR[mono], ' ');
102
  video_clear(COLOR_BODY[mono], 80);
103
  video_putstring(0, 29, COLOR_TITLEBAR[mono], "SVAROG386 INSTALLATION");
36 mv_fox 104
  video_movecursor(25,0);
28 mv_fox 105
}
106
 
107
 
108
static int selectlang(char *lang) {
109
  int choice;
110
  char *code;
111
  char *langlist[] = {
112
    "English\0EN",
113
    "French\0FR",
114
    "German\0DE",
115
    "Italian\0IT",
116
    "Polish\0PL",
117
    "Russian\0RU",
118
    "Slovenian\0SL",
119
    "Spanish\0ES",
120
    "Turkish\0TR",
121
    NULL
122
  };
123
 
124
  newscreen();
36 mv_fox 125
  video_putstring(4, 30, COLOR_BODY[mono], "Welcome to Svarog386");
126
  video_putstring(5, 30, COLOR_BODY[mono], "====================");
127
  video_putstring(8, 2, COLOR_BODY[mono], "Please select your language from the list below:");
128
  choice = menuselect(10, -1, 12, langlist);
28 mv_fox 129
  if (choice < 0) return(-1);
130
  /* write short language code into lang */
131
  for (code = langlist[choice]; *code != 0; code++);
132
  memcpy(lang, code + 1, 2);
133
  lang[2] = 0;
134
  return(0);
135
}
136
 
137
 
138
/* returns 0 if installation must proceed, non-zero otherwise */
139
static int welcomescreen(void) {
140
  char *choice[] = {"Install Svarog386 to disk", "Quit to DOS", NULL};
141
  newscreen();
36 mv_fox 142
  video_putstring(4, 1, COLOR_BODY[mono], "You are about to install Svarog386: a free, MSDOS-compatible operating system");
143
  video_putstring(5, 1, COLOR_BODY[mono], "based on the FreeDOS kernel. Svarog386 targets 386+ computers and comes with a");
144
  video_putstring(6, 1, COLOR_BODY[mono], "variety of third-party applications.");
145
  video_putstring(8, 1, COLOR_BODY[mono], "WARNING: If your PC has another operating system installed, this other system");
146
  video_putstring(9, 1, COLOR_BODY[mono], "         might be unable to boot once Svarog386 is installed.");
28 mv_fox 147
  return(menuselect(14, -1, 4, choice));
148
}
149
 
150
 
33 mv_fox 151
/* returns 1 if drive is removable, 0 if not, -1 on error */
152
static int isdriveremovable(int drv) {
28 mv_fox 153
  union REGS r;
33 mv_fox 154
  r.x.ax = 0x4408;
155
  r.h.bl = drv;
28 mv_fox 156
  int86(0x21, &r, &r);
33 mv_fox 157
  /* CF set on error, AX set to 0 if removable, 1 if fixed */
158
  if (r.x.cflag != 0) return(-1);
159
  if (r.x.ax == 0) return(1);
160
  return(0);
28 mv_fox 161
}
162
 
163
 
35 mv_fox 164
/* returns total disk space of drive drv (in MiB, max 2048), or -1 if drive invalid */
165
static int disksize(int drv) {
28 mv_fox 166
  long res;
167
  union REGS r;
168
  r.h.ah = 0x36; /* DOS 2+ get free disk space */
169
  r.h.dl = drv;
170
  int86(0x21, &r, &r);
171
  if (r.x.ax == 0xffffu) return(-1); /* AX set to FFFFh if drive invalid */
172
  res = r.x.ax;
173
  res *= r.x.bx;
174
  res *= r.x.cx;
35 mv_fox 175
  return(res >> 20); /* return result after converting bytes to MiB */
176
}
177
 
178
 
179
/* returns 0 if disk is empty, non-zero otherwise */
180
static int diskempty(int drv) {
181
  unsigned int rc;
182
  int res;
183
  char buff[8];
184
  struct find_t fileinfo;
185
  sprintf(buff, "%c:\\*.*", 'A' + drv - 1);
186
  rc = _dos_findfirst(buff, _A_NORMAL | _A_SUBDIR | _A_HIDDEN | _A_SYSTEM, &fileinfo);
187
  if (rc == 0) {
188
    res = 1; /* call successfull means disk is not empty */
28 mv_fox 189
  } else {
35 mv_fox 190
    res = 0;
28 mv_fox 191
  }
35 mv_fox 192
  /* _dos_findclose(&fileinfo); */ /* apparently required only on OS/2 */
28 mv_fox 193
  return(res);
194
}
195
 
196
 
197
static int preparedrive(void) {
33 mv_fox 198
  int driveremovable;
36 mv_fox 199
  int selecteddrive = 3; /* hardcoded to 'C:' for now */
200
  int cselecteddrive;
35 mv_fox 201
  int ds;
36 mv_fox 202
  char buff[128];
203
  cselecteddrive = 'A' + selecteddrive - 1;
28 mv_fox 204
  for (;;) {
205
    newscreen();
33 mv_fox 206
    driveremovable = isdriveremovable(selecteddrive);
207
    if (driveremovable < 0) {
34 mv_fox 208
      char *list[] = { "Create an automatic partition", "Run the FDISK partitioning tool", "Quit to DOS", NULL};
29 mv_fox 209
      video_putstring(4, 2, COLOR_BODY[mono], "ERROR: Drive C: could not be found. Perhaps your hard disk needs to be");
34 mv_fox 210
      video_putstring(5, 2, COLOR_BODY[mono], "       partitioned first. Please create at least one partition on your");
29 mv_fox 211
      video_putstring(6, 2, COLOR_BODY[mono], "       hard disk, so Svarog386 can be installed on it. Note, that");
212
      video_putstring(7, 2, COLOR_BODY[mono], "       Svarog386 requires at least 16 MiB of available disk space.");
33 mv_fox 213
      video_putstring(9, 2, COLOR_BODY[mono], "You can use the FDISK partitioning tool for creating the required partition");
214
      video_putstring(10, 2, COLOR_BODY[mono], "manually, or you can let the installer partitioning your disk");
215
      video_putstring(11, 2, COLOR_BODY[mono], "automatically. You can also abort the installation to use any other");
216
      video_putstring(12, 2, COLOR_BODY[mono], "partition manager of your choice.");
217
      switch (menuselect(14, -1, 5, list)) {
218
        case 0:
219
          system("FDISK /AUTO");
220
          break;
221
        case 1:
222
          video_clear(0x0700, 0);
223
          video_movecursor(0, 0);
224
          system("FDISK");
225
          break;
226
        case 2:
227
          return(-1);
228
      }
28 mv_fox 229
      newscreen();
35 mv_fox 230
      video_putstring(11, 10, COLOR_BODY[mono], "Your computer will reboot now. Press any key.");
33 mv_fox 231
      input_getkey();
28 mv_fox 232
      reboot();
233
      return(-1);
33 mv_fox 234
    } else if (driveremovable > 0) {
36 mv_fox 235
      sprintf(buff, "ERROR: Drive %c: appears to be a removable device.");
236
      video_putstring(9, 2, COLOR_BODY[mono], buff);
35 mv_fox 237
      video_putstring(11, 2, COLOR_BODY[mono], "Installation aborted. Press any key.");
33 mv_fox 238
      return(-1);
28 mv_fox 239
    }
33 mv_fox 240
    /* if not formatted, propose to format it right away (try to create a directory) */
36 mv_fox 241
    sprintf(buff, "%c:\\SVWRTEST.123", cselecteddrive);
242
    if (mkdir(buff) != 0) {
28 mv_fox 243
      char *list[] = { "Proceed with formatting", "Quit to DOS", NULL};
36 mv_fox 244
      sprintf(buff, "ERROR: Drive %c: seems to be unformated.", cselecteddrive);
245
      video_putstring(7, 2, COLOR_BODY[mono], buff);
29 mv_fox 246
      video_putstring(8, 2, COLOR_BODY[mono], "       Do you wish to format it?");
28 mv_fox 247
      if (menuselect(12, -1, 4, list) != 0) return(-1);
248
      video_clear(0x0700, 0);
249
      video_movecursor(0, 0);
36 mv_fox 250
      sprintf(buff, "FORMAT %c: /Q /U /V:SVAROG386", cselecteddrive);
251
      system(buff);
28 mv_fox 252
      continue;
253
    }
36 mv_fox 254
    sprintf(buff, "%c:\\SVWRTEST.123", cselecteddrive);
33 mv_fox 255
    rmdir("C:\\SVWRTEST.123");
256
    /* check total disk space */
35 mv_fox 257
    ds = disksize(selecteddrive);
28 mv_fox 258
    if (ds < 16) {
33 mv_fox 259
      video_putstring(9, 2, COLOR_BODY[mono], "ERROR: Drive C: is not big enough!");
260
      video_putstring(10, 2, COLOR_BODY[mono], "      Svarog386 requires a disk of at least 16 MiB.");
261
      video_putstring(12, 2, COLOR_BODY[mono], "Press any key to return to DOS.");
28 mv_fox 262
      input_getkey();
263
      return(-1);
264
    }
265
    /* is the disk empty? */
35 mv_fox 266
    if (diskempty(selecteddrive) != 0) {
28 mv_fox 267
      char *list[] = { "Proceed with formatting", "Quit to DOS", NULL};
29 mv_fox 268
      video_putstring(7, 2, COLOR_BODY[mono], "ERROR: Drive C: is not empty. Svarog386 must be installed on an empty disk.");
269
      video_putstring(8, 2, COLOR_BODY[mono], "       You can format the disk now, to make it empty. Note however, that");
270
      video_putstring(9, 2, COLOR_BODY[mono], "       this will ERASE ALL CURRENT DATA on your disk.");
28 mv_fox 271
      if (menuselect(12, -1, 4, list) != 0) return(-1);
272
      video_clear(0x0700, 0);
273
      video_movecursor(0, 0);
36 mv_fox 274
      system("FORMAT C: /Q /U /V:SVAROG386");
28 mv_fox 275
      continue;
276
    } else {
277
      /* final confirmation */
278
      char *list[] = { "Install Svarog386", "Quit to DOS", NULL};
36 mv_fox 279
      sprintf(buff, "The installation of Svarog386 to your %c: disk is about to begin.", cselecteddrive);
280
      video_putstring(7, 2, COLOR_BODY[mono], buff);
28 mv_fox 281
      if (menuselect(10, -1, 4, list) != 0) return(-1);
36 mv_fox 282
      sprintf(buff, "SYS A: %c:", cselecteddrive);
283
      system(buff);
284
      sprintf(buff, "%c:\\TEMP", cselecteddrive);
285
      mkdir(buff);
286
      return(cselecteddrive);
28 mv_fox 287
    }
288
  }
289
}
290
 
291
 
292
static void finalreboot(void) {
293
  newscreen();
36 mv_fox 294
  video_putstring(10, 2, COLOR_BODY[mono], "Svarog386 installation is over. Please remove the installation");
295
  video_putstring(11, 2, COLOR_BODY[mono], "diskette and/or CD from the drive.");
29 mv_fox 296
  video_putstring(13, 2, COLOR_BODY[mono], "Press any key to reboot...");
28 mv_fox 297
  input_getkey();
298
  reboot();
299
}
300
 
301
 
302
static void bootfilesgen(int targetdrv, char *lang) {
303
  char buff[128];
304
  FILE *fd;
305
  /*** AUTOEXEC.BAT ***/
36 mv_fox 306
  sprintf(buff, "%c:\\AUTOEXEC.BAT", targetdrv);
28 mv_fox 307
  fd = fopen(buff, "wb");
308
  if (fd == NULL) return;
309
  fprintf(fd, "@ECHO OFF\r\n");
36 mv_fox 310
  fprintf(fd, "SET TEMP=%c:\\TEMP\r\n", targetdrv);
311
  fprintf(fd, "SET DOSDIR=%c:\\SYSTEM\\SVAROG.386\r\n", targetdrv);
312
  fprintf(fd, "SET NLSPATH=%%DOSDIR%%\\NLS\r\n", targetdrv);
28 mv_fox 313
  fprintf(fd, "SET LANG=%s\r\n", lang);
314
  fprintf(fd, "SET DIRCMD=/OGNE/P\r\n");
315
  fprintf(fd, "SET FDNPKG.CFG=%c:\\SYSTEM\\CFG\\FDNPKG.CFG\r\n");
316
  fprintf(fd, "SET WATTCP.CFG=%c:\\SYSTEM\\CFG\\WATTCP.CFG\r\n");
317
  fprintf(fd, "PATH %%DOSDIR%%\\BIN;%%DOSDIR%%\\LINKS\r\n");
318
  fprintf(fd, "PROMPT $P$G\r\n");
30 mv_fox 319
  fprintf(fd, "ALIAS REBOOT=FDAPM COLDBOOT\r\n");
320
  fprintf(fd, "ALIAS HALT=FDAPM POWEROFF\r\n");
28 mv_fox 321
  fprintf(fd, "\r\n\r\n");
322
  fprintf(fd, "MODE CON CP PREPARE=((991) %c:\\SYSTEM\\SVAROG.386\\CPI\\EGA10.CPX\r\n");
323
  fprintf(fd, "MODE CON CP SELECT=991\r\n");
324
  fprintf(fd, "\r\n");
325
  fprintf(fd, "SHSUCDX /d:FDCD0001\r\n");
326
  fclose(fd);
327
  /*** CONFIG.SYS ***/
36 mv_fox 328
  sprintf(buff, "%c:\\CONFIG.SYS", targetdrv);
28 mv_fox 329
  fd = fopen(buff, "wb");
330
  if (fd == NULL) return;
331
  fprintf(fd, "DOS=UMB,HIGH\r\n");
332
  fprintf(fd, "FILES=50\r\n");
36 mv_fox 333
  fprintf(fd, "DEVICE=%c:\\SYSTEM\\SVAROG.386\\BIN\\HIMEM.EXE\r\n", targetdrv);
334
  fprintf(fd, "SHELLHIGH=%c:\\SYSTEM\\SVAROG.386\\BIN\\COMMAND.COM /E:512", targetdrv);
335
  fprintf(fd, "REM COUNTRY=001,437,%c:\\SYSTEM\\SVAROG.386\r\n", targetdrv);
336
  fprintf(fd, "DEVICE=%c:\\SYSTEM\\SVAROG.386\\BIN\\CDROM.SYS /D:FDCD0001\r\n", targetdrv);
28 mv_fox 337
  fclose(fd);
338
}
339
 
340
 
341
static void installpackages(void) {
342
  char *pkglist[] = {
343
    "APPEND",
344
    "ASSIGN",
345
    "ATTRIB",
346
    "CHKDSK",
347
    "CHOICE",
348
    "COMMAND",
349
    "COMP",
350
    "CPIDOS",
351
    "CTMOUSE",
352
    "DEBUG",
353
    "DEFRAG",
354
    "DELTREE",
355
    "DEVLOAD",
356
    "DISKCOMP",
357
    "DISKCOPY",
358
    "DISPLAY",
359
    "DOSFSCK",
360
    "EDIT",
361
    "EDLIN",
362
    "EXE2BIN",
363
    "FC",
364
    "FDAPM",
365
    "FDISK",
366
    "FDNPKG",
367
    "FIND",
368
    "FORMAT",
369
    "HELP",
370
    "HIMEMX",
371
    "KERNEL",
372
    "KEYB",
373
    "LABEL",
374
    "LBACACHE",
375
    "MEM",
376
    "MIRROR",
377
    "MODE",
378
    "MORE",
379
    "MOVE",
380
    "NANSI",
381
    "NLSFUNC",
382
    "PRINT",
383
    "RDISK",
384
    "RECOVER",
385
    "REPLACE",
386
    "SHARE",
387
    "SHSUCDX",
388
    "SORT",
389
    "SWSUBST",
390
    "TREE",
391
    "UNDELETE",
392
    "XCOPY",
393
    NULL
394
  };
30 mv_fox 395
  int i, pkglistlen;
28 mv_fox 396
  newscreen();
30 mv_fox 397
  /* count how long the pkg list is */
398
  for (pkglistlen = 0; pkglist[pkglistlen] != NULL; pkglistlen++);
399
  /* install packages */
28 mv_fox 400
  for (i = 0; pkglist[i] != NULL; i++) {
36 mv_fox 401
    char buff[128];
35 mv_fox 402
    sprintf(buff, "Installing package %d/%d: %s", i+1, pkglistlen, pkglist[i]);
36 mv_fox 403
    strcat(buff, "       ");
30 mv_fox 404
    video_putstring(10, 2, COLOR_BODY[mono], buff);
36 mv_fox 405
    sprintf(buff, "FDNPKG INSTALL %s > NUL");
28 mv_fox 406
    system(buff);
407
  }
408
}
409
 
410
 
411
int main(void) {
412
  char lang[4];
413
  int targetdrv;
414
 
29 mv_fox 415
  /* init screen and detect mono status */
416
  mono = video_init();
417
 
28 mv_fox 418
  for (;;) { /* fake loop, it's here just to break out easily */
419
    if (selectlang(lang) < 0) break; /* welcome to svarog, select your language */
30 mv_fox 420
    /*selectkeyb();*/ /* what keyb layout should we use? */
28 mv_fox 421
    if (welcomescreen() != 0) break; /* what svarog386 is, ask whether to run live dos or install */
422
    targetdrv = preparedrive(); /* what drive should we install to? check avail. space */
423
    if (targetdrv < 0) break;
424
    /*askaboutsources();*/ /* IF sources are available, ask if installing with them */
425
    installpackages();   /* install packages */
426
    bootfilesgen(targetdrv, lang); /* generate simple boot files */
427
    /*localcfg();*/ /* show local params (currency, etc), and propose to change them (based on localcfg) */
428
    /*netcfg();*/ /* basic networking config? */
429
    finalreboot(); /* remove the CD and reboot */
430
    break;
431
  }
432
  video_clear(0x0700, 0);
433
  video_movecursor(0, 0);
434
  return(0);
435
}