Subversion Repositories SvarDOS

Rev

Rev 34 | Go to most recent revision | Only display areas with differences | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

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