Subversion Repositories SvarDOS

Rev

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

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