Subversion Repositories SvarDOS

Rev

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

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