Subversion Repositories SvarDOS

Rev

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