Subversion Repositories SvarDOS

Rev

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