Subversion Repositories SvarDOS

Rev

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