Subversion Repositories SvarDOS

Rev

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

Rev 79 Rev 81
1
/*
1
/*
2
 * SVAROG386 INSTALL
2
 * SVAROG386 INSTALL
3
 * COPYRIGHT (C) 2016 MATEUSZ VISTE
3
 * COPYRIGHT (C) 2016 MATEUSZ VISTE
4
 *
4
 *
5
 * http://svarog386.sf.net
5
 * http://svarog386.sf.net
6
 */
6
 */
7
 
7
 
8
#include <dos.h>
8
#include <dos.h>
9
#include <direct.h>  /* mkdir() */
9
#include <direct.h>  /* mkdir() */
10
#include <stdio.h>   /* printf() and friends */
10
#include <stdio.h>   /* printf() and friends */
11
#include <stdlib.h>  /* system() */
11
#include <stdlib.h>  /* system() */
12
#include <string.h>  /* memcpy() */
12
#include <string.h>  /* memcpy() */
13
#include <unistd.h>
13
#include <unistd.h>
14
 
14
 
15
#include "kitten\kitten.h"
15
#include "kitten\kitten.h"
16
 
16
 
17
#include "cdrom.h"
17
#include "cdrom.h"
18
#include "input.h"
18
#include "input.h"
19
#include "video.h"
19
#include "video.h"
20
 
20
 
21
/* keyboard layouts and locales */
21
/* keyboard layouts and locales */
22
#include "keylay.h"
22
#include "keylay.h"
23
#include "keyoff.h"
23
#include "keyoff.h"
24
 
24
 
25
/* color scheme (color, mono) */
25
/* color scheme (color, mono) */
26
static unsigned short COLOR_TITLEBAR[2] = {0x7000,0x7000};
26
static unsigned short COLOR_TITLEBAR[2] = {0x7000,0x7000};
27
static unsigned short COLOR_BODY[2] = {0x1700,0x0700};
27
static unsigned short COLOR_BODY[2] = {0x1700,0x0700};
28
static unsigned short COLOR_SELECT[2] = {0x7000,0x7000};
28
static unsigned short COLOR_SELECT[2] = {0x7000,0x7000};
29
static unsigned short COLOR_SELECTCUR[2] = {0x1F00,0x0700};
29
static unsigned short COLOR_SELECTCUR[2] = {0x1F00,0x0700};
30
 
30
 
31
/* mono flag */
31
/* mono flag */
32
static int mono = 0;
32
static int mono = 0;
33
 
33
 
34
/* how much disk space does Svarog386 require (in MiB) */
34
/* how much disk space does Svarog386 require (in MiB) */
35
#define SVAROG_DISK_REQ 8
35
#define SVAROG_DISK_REQ 8
36
 
36
 
37
/* menu screens can output only one of these: */
37
/* menu screens can output only one of these: */
38
#define MENUNEXT 0
38
#define MENUNEXT 0
39
#define MENUPREV -1
39
#define MENUPREV -1
40
#define MENUQUIT -2
40
#define MENUQUIT -2
41
 
41
 
42
/* a convenience 'function' used for debugging */
42
/* a convenience 'function' used for debugging */
43
#define DBG(x) { video_putstringfix(24, 0, 0x4F00u, x, 80); }
43
#define DBG(x) { video_putstringfix(24, 0, 0x4F00u, x, 80); }
44
 
44
 
45
struct slocales {
45
struct slocales {
46
  char lang[4];
46
  char lang[4];
47
  char *keybcode;
47
  char *keybcode;
48
  unsigned int codepage;
48
  unsigned int codepage;
49
  int egafile;
49
  int egafile;
50
  int keybfile;
50
  int keybfile;
51
  int keyboff;
51
  int keyboff;
52
  int keyblen;
52
  int keyblen;
53
};
53
};
54
 
54
 
55
 
55
 
56
/* reboot the computer */
56
/* reboot the computer */
57
static void reboot(void) {
57
static void reboot(void) {
58
  void ((far *bootroutine)()) = (void (far *)()) 0xFFFF0000L;
58
  void ((far *bootroutine)()) = (void (far *)()) 0xFFFF0000L;
59
  int far *rstaddr = (int far *)0x00400072L; /* BIOS boot flag is at 0040:0072 */
59
  int far *rstaddr = (int far *)0x00400072L; /* BIOS boot flag is at 0040:0072 */
60
  *rstaddr = 0x1234; /* 0x1234 = warm boot, 0 = cold boot */
60
  *rstaddr = 0x1234; /* 0x1234 = warm boot, 0 = cold boot */
61
  (*bootroutine)(); /* jump to the BIOS reboot routine at FFFF:0000 */
61
  (*bootroutine)(); /* jump to the BIOS reboot routine at FFFF:0000 */
62
}
62
}
63
 
63
 
64
 
64
 
65
/* outputs a string to screen with taking care of word wrapping. returns amount of lines. */
65
/* outputs a string to screen with taking care of word wrapping. returns amount of lines. */
66
static int putstringwrap(int y, int x, unsigned short attr, char *s) {
66
static int putstringwrap(int y, int x, unsigned short attr, char *s) {
67
  int linew, lincount;
67
  int linew, lincount;
68
  linew = 80;
68
  linew = 80;
69
  if (x >= 0) linew -= (x << 1);
69
  if (x >= 0) linew -= (x << 1);
70
 
70
 
71
  for (lincount = 1; y+lincount < 25; lincount++) {
71
  for (lincount = 1; y+lincount < 25; lincount++) {
72
    int i, len = linew;
72
    int i, len = linew;
73
    for (i = 0; i <= linew; i++) {
73
    for (i = 0; i <= linew; i++) {
74
      if (s[i] == ' ') len = i;
74
      if (s[i] == ' ') len = i;
75
      if (s[i] == '\n') {
75
      if (s[i] == '\n') {
76
        len = i;
76
        len = i;
77
        break;
77
        break;
78
      }
78
      }
79
      if (s[i] == 0) {
79
      if (s[i] == 0) {
80
        len = i;
80
        len = i;
81
        break;
81
        break;
82
      }
82
      }
83
    }
83
    }
84
    video_putstring(y++, x, attr, s, len);
84
    video_putstring(y++, x, attr, s, len);
85
    s += len;
85
    s += len;
86
    if (*s == 0) break;
86
    if (*s == 0) break;
87
    s += 1; /* skip the whitespace char */
87
    s += 1; /* skip the whitespace char */
88
  }
88
  }
89
  return(lincount);
89
  return(lincount);
90
}
90
}
91
 
91
 
92
 
92
 
93
/* an NLS wrapper around video_putstring(), also performs line wrapping when
93
/* an NLS wrapper around video_putstring(), also performs line wrapping when
94
 * needed. returns the amount of lines that were output */
94
 * needed. returns the amount of lines that were output */
95
static int putstringnls(int y, int x, unsigned short attr, int nlsmaj, int nlsmin, char *s) {
95
static int putstringnls(int y, int x, unsigned short attr, int nlsmaj, int nlsmin, char *s) {
96
  s = kittengets(nlsmaj, nlsmin, s);
96
  s = kittengets(nlsmaj, nlsmin, s);
97
  return(putstringwrap(y, x, attr, s));
97
  return(putstringwrap(y, x, attr, s));
98
}
98
}
99
 
99
 
100
 
100
 
101
static int menuselect(int ypos, int xpos, int height, char **list, int listlen) {
101
static int menuselect(int ypos, int xpos, int height, char **list, int listlen) {
102
  int i, offset = 0, res = 0, count, width = 0;
102
  int i, offset = 0, res = 0, count, width = 0;
103
  /* count how many positions there is, and check their width */
103
  /* count how many positions there is, and check their width */
104
  for (count = 0; (list[count] != NULL) && (count != listlen); count++) {
104
  for (count = 0; (list[count] != NULL) && (count != listlen); count++) {
105
    int len = strlen(list[count]);
105
    int len = strlen(list[count]);
106
    if (len > width) width = len;
106
    if (len > width) width = len;
107
  }
107
  }
108
 
108
 
109
  /* if xpos negative, means 'center out' */
109
  /* if xpos negative, means 'center out' */
110
  if (xpos < 0) xpos = 39 - (width >> 1);
110
  if (xpos < 0) xpos = 39 - (width >> 1);
111
 
111
 
112
  video_putchar(ypos, xpos+width+2, COLOR_SELECT[mono], 0xBF);         /*       \ */
112
  video_putchar(ypos, xpos+width+2, COLOR_SELECT[mono], 0xBF);         /*       \ */
113
  video_putchar(ypos, xpos-1, COLOR_SELECT[mono], 0xDA);               /*  /      */
113
  video_putchar(ypos, xpos-1, COLOR_SELECT[mono], 0xDA);               /*  /      */
114
  video_putchar(ypos+height-1, xpos-1, COLOR_SELECT[mono], 0xC0);      /*  \      */
114
  video_putchar(ypos+height-1, xpos-1, COLOR_SELECT[mono], 0xC0);      /*  \      */
115
  video_putchar(ypos+height-1, xpos+width+2, COLOR_SELECT[mono], 0xD9);/*      /  */
115
  video_putchar(ypos+height-1, xpos+width+2, COLOR_SELECT[mono], 0xD9);/*      /  */
116
  video_putcharmulti(ypos, xpos, COLOR_SELECT[mono], 0xC4, width + 2, 1);
116
  video_putcharmulti(ypos, xpos, COLOR_SELECT[mono], 0xC4, width + 2, 1);
117
  video_putcharmulti(ypos+height-1, xpos, COLOR_SELECT[mono], 0xC4, width + 2, 1);
117
  video_putcharmulti(ypos+height-1, xpos, COLOR_SELECT[mono], 0xC4, width + 2, 1);
118
  video_putcharmulti(ypos+1, xpos-1, COLOR_SELECT[mono], 0xB3, height - 2, 80);
118
  video_putcharmulti(ypos+1, xpos-1, COLOR_SELECT[mono], 0xB3, height - 2, 80);
119
  video_putcharmulti(ypos+1, xpos+width+2, COLOR_SELECT[mono], 0xB3, height - 2, 80);
119
  video_putcharmulti(ypos+1, xpos+width+2, COLOR_SELECT[mono], 0xB3, height - 2, 80);
120
 
120
 
121
  for (;;) {
121
  for (;;) {
122
    int key;
122
    int key;
123
    /* list of selectable items */
123
    /* list of selectable items */
124
    for (i = 0; i < height - 2; i++) {
124
    for (i = 0; i < height - 2; i++) {
125
      if (i + offset == res) {
125
      if (i + offset == res) {
126
        video_putchar(ypos + 1 + i, xpos, COLOR_SELECTCUR[mono], 16);
126
        video_putchar(ypos + 1 + i, xpos, COLOR_SELECTCUR[mono], 16);
127
        video_putchar(ypos + 1 + i, xpos+width+1, COLOR_SELECTCUR[mono], 17);
127
        video_putchar(ypos + 1 + i, xpos+width+1, COLOR_SELECTCUR[mono], 17);
128
        video_movecursor(ypos + 1 + i, xpos);
128
        video_movecursor(ypos + 1 + i, xpos);
129
        video_putstringfix(ypos + 1 + i, xpos+1, COLOR_SELECTCUR[mono], list[i + offset], width);
129
        video_putstringfix(ypos + 1 + i, xpos+1, COLOR_SELECTCUR[mono], list[i + offset], width);
130
      } else if (i + offset < count) {
130
      } else if (i + offset < count) {
131
        video_putchar(ypos + 1 + i, xpos, COLOR_SELECT[mono], ' ');
131
        video_putchar(ypos + 1 + i, xpos, COLOR_SELECT[mono], ' ');
132
        video_putchar(ypos + 1 + i, xpos+width+1, COLOR_SELECT[mono], ' ');
132
        video_putchar(ypos + 1 + i, xpos+width+1, COLOR_SELECT[mono], ' ');
133
        video_putstringfix(ypos + 1 + i, xpos+1, COLOR_SELECT[mono], list[i + offset], width);
133
        video_putstringfix(ypos + 1 + i, xpos+1, COLOR_SELECT[mono], list[i + offset], width);
134
      } else {
134
      } else {
135
        video_putcharmulti(ypos + 1 + i, xpos, COLOR_SELECT[mono], ' ', width+2, 1);
135
        video_putcharmulti(ypos + 1 + i, xpos, COLOR_SELECT[mono], ' ', width+2, 1);
136
      }
136
      }
137
    }
137
    }
138
    key = input_getkey();
138
    key = input_getkey();
139
    if (key == 0x0D) { /* ENTER */
139
    if (key == 0x0D) { /* ENTER */
140
      return(res);
140
      return(res);
141
    } else if (key == 0x148) { /* up */
141
    } else if (key == 0x148) { /* up */
142
      if (res > 0) {
142
      if (res > 0) {
143
        res--;
143
        res--;
144
        if (res < offset) offset = res;
144
        if (res < offset) offset = res;
145
      }
145
      }
146
    } else if (key == 0x150) { /* down */
146
    } else if (key == 0x150) { /* down */
147
      if (res+1 < count) {
147
      if (res+1 < count) {
148
        res++;
148
        res++;
149
        if (res > offset + height - 3) offset = res - (height - 3);
149
        if (res > offset + height - 3) offset = res - (height - 3);
150
      }
150
      }
151
    } else if (key == 0x147) { /* home */
151
    } else if (key == 0x147) { /* home */
152
      res = 0;
152
      res = 0;
153
      offset = 0;
153
      offset = 0;
154
    } else if (key == 0x14F) { /* end */
154
    } else if (key == 0x14F) { /* end */
155
      res = count - 1;
155
      res = count - 1;
156
      if (res > offset + height - 3) offset = res - (height - 3);
156
      if (res > offset + height - 3) offset = res - (height - 3);
157
    } else if (key == 0x1B) {  /* ESC */
157
    } else if (key == 0x1B) {  /* ESC */
158
      return(-1);
158
      return(-1);
159
    }/* else {
159
    }/* else {
160
      char buf[8];
160
      char buf[8];
161
      snprintf(buf, sizeof(buf), "0x%02X ", key);
161
      snprintf(buf, sizeof(buf), "0x%02X ", key);
162
      video_putstring(1, 0, COLOR_BODY[mono], buf, -1);
162
      video_putstring(1, 0, COLOR_BODY[mono], buf, -1);
163
    }*/
163
    }*/
164
  }
164
  }
165
}
165
}
166
 
166
 
167
static void newscreen(int statusbartype) {
167
static void newscreen(int statusbartype) {
168
  int x;
-
 
169
  char *msg;
168
  char *msg;
170
  msg = kittengets(0, 0, "SVAROG386 INSTALLATION");
169
  msg = kittengets(0, 0, "SVAROG386 INSTALLATION");
171
  for (x = 0; x < 80; x++) video_putchar(0, x, COLOR_TITLEBAR[mono], ' ');
170
  video_putcharmulti(0, 0, COLOR_TITLEBAR[mono], ' ', 80, 1);
172
  video_putstring(0, 40 - (strlen(msg) >> 1), COLOR_TITLEBAR[mono], msg, -1);
171
  video_putstring(0, 40 - (strlen(msg) >> 1), COLOR_TITLEBAR[mono], msg, -1);
173
  video_clear(COLOR_BODY[mono], 80);
172
  video_clear(COLOR_BODY[mono], 80, -80);
174
  switch (statusbartype) {
173
  switch (statusbartype) {
175
    case 1:
174
    case 1:
176
      msg = kittengets(0, 11, "Up/Down = Select entry | Enter = Validate your choice | ESC = Quit to DOS");
175
      msg = kittengets(0, 11, "Up/Down = Select entry | Enter = Validate your choice | ESC = Quit to DOS");
177
      break;
176
      break;
178
    case 2:
177
    case 2:
179
      msg = kittengets(0, 5, "Press any key...");
178
      msg = kittengets(0, 5, "Press any key...");
180
      break;
179
      break;
181
    case 3:
180
    case 3:
182
      msg = "";
181
      msg = "";
183
      break;
182
      break;
184
    default:
183
    default:
185
      msg = kittengets(0, 10, "Up/Down = Select entry | Enter = Validate your choice | ESC = Previous screen");
184
      msg = kittengets(0, 10, "Up/Down = Select entry | Enter = Validate your choice | ESC = Previous screen");
186
      break;
185
      break;
187
  }
186
  }
188
  video_putchar(24, 0, COLOR_TITLEBAR[mono], ' ');
187
  video_putchar(24, 0, COLOR_TITLEBAR[mono], ' ');
189
  video_putstringfix(24, 1, COLOR_TITLEBAR[mono], msg, 79);
188
  video_putstringfix(24, 1, COLOR_TITLEBAR[mono], msg, 79);
190
  video_movecursor(25,0);
189
  video_movecursor(25,0);
191
}
190
}
192
 
191
 
193
static int selectlang(struct slocales *locales) {
192
static int selectlang(struct slocales *locales) {
194
  int choice, x;
193
  int choice, x;
195
  char *msg;
194
  char *msg;
196
  char *langlist[] = {
195
  char *langlist[] = {
197
    "English",
196
    "English",
198
    "French",
197
    "French",
199
    "Polish",
198
    "Polish",
200
    "Turkish",
199
    "Turkish",
201
    NULL
200
    NULL
202
  };
201
  };
203
 
202
 
204
  newscreen(1);
203
  newscreen(1);
205
  msg = kittengets(1, 0, "Welcome to Svarog386");
204
  msg = kittengets(1, 0, "Welcome to Svarog386");
206
  x = 40 - (strlen(msg) >> 1);
205
  x = 40 - (strlen(msg) >> 1);
207
  video_putstring(4, x, COLOR_BODY[mono], msg, -1);
206
  video_putstring(4, x, COLOR_BODY[mono], msg, -1);
208
  video_putcharmulti(5, x, COLOR_BODY[mono], '=', strlen(msg), 1);
207
  video_putcharmulti(5, x, COLOR_BODY[mono], '=', strlen(msg), 1);
209
  putstringnls(8, -1, COLOR_BODY[mono], 1, 1, "Please select your language from the list below:");
208
  putstringnls(8, -1, COLOR_BODY[mono], 1, 1, "Please select your language from the list below:");
210
  choice = menuselect(11, -1, 6, langlist, -1);
209
  choice = menuselect(11, -1, 6, langlist, -1);
211
  if (choice < 0) return(MENUPREV);
210
  if (choice < 0) return(MENUPREV);
212
  /* populate locales with default values */
211
  /* populate locales with default values */
213
  memset(locales, 0, sizeof(struct slocales));
212
  memset(locales, 0, sizeof(struct slocales));
214
  switch (choice) {
213
  switch (choice) {
215
    case 1:
214
    case 1:
216
      strcpy(locales->lang, "FR");
215
      strcpy(locales->lang, "FR");
217
      locales->keyboff = OFFLOC_FR;
216
      locales->keyboff = OFFLOC_FR;
218
      locales->keyblen = OFFLEN_FR;
217
      locales->keyblen = OFFLEN_FR;
219
      break;
218
      break;
220
    case 2:
219
    case 2:
221
      strcpy(locales->lang, "PL");
220
      strcpy(locales->lang, "PL");
222
      locales->keyboff = OFFLOC_PL;
221
      locales->keyboff = OFFLOC_PL;
223
      locales->keyblen = OFFLEN_PL;
222
      locales->keyblen = OFFLEN_PL;
224
      break;
223
      break;
225
    case 3:
224
    case 3:
226
      strcpy(locales->lang, "TR");
225
      strcpy(locales->lang, "TR");
227
      locales->keyboff = OFFLOC_TR;
226
      locales->keyboff = OFFLOC_TR;
228
      locales->keyblen = OFFLEN_TR;
227
      locales->keyblen = OFFLEN_TR;
229
      break;
228
      break;
230
    default:
229
    default:
231
      strcpy(locales->lang, "EN");
230
      strcpy(locales->lang, "EN");
232
      locales->keyboff = 0;
231
      locales->keyboff = 0;
233
      locales->keyblen = OFFCOUNT;
232
      locales->keyblen = OFFCOUNT;
234
      break;
233
      break;
235
  }
234
  }
236
  /* populate the slocales struct */
235
  /* populate the slocales struct */
237
  for (msg = kblayouts[locales->keyboff]; *msg != 0; msg++); /* skip layout name */
236
  for (msg = kblayouts[locales->keyboff]; *msg != 0; msg++); /* skip layout name */
238
  msg++;
237
  msg++;
239
  /* skip keyb code and copy it to locales.keybcode */
238
  /* skip keyb code and copy it to locales.keybcode */
240
  locales->keybcode = msg;
239
  locales->keybcode = msg;
241
  for (; *msg != 0; msg++);
240
  for (; *msg != 0; msg++);
242
  /* */
241
  /* */
243
  locales->codepage = ((unsigned short)msg[1] << 8) | msg[2];
242
  locales->codepage = ((unsigned short)msg[1] << 8) | msg[2];
244
  locales->egafile = msg[3];
243
  locales->egafile = msg[3];
245
  locales->keybfile = msg[4];
244
  locales->keybfile = msg[4];
246
  /* */
245
  /* */
247
  return(MENUNEXT);
246
  return(MENUNEXT);
248
}
247
}
249
 
248
 
250
 
249
 
251
#define LTODEC(x, y) ((unsigned short)(x << 8) | (y))
250
#define LTODEC(x, y) ((unsigned short)(x << 8) | (y))
252
static int selectkeyb(struct slocales *locales) {
251
static int selectkeyb(struct slocales *locales) {
253
  int keyboff, keyblen, menuheight;
252
  int keyboff, keyblen, menuheight;
254
  unsigned short lang;
253
  unsigned short lang;
255
  lang = LTODEC(locales->lang[0], locales->lang[1]);
254
  lang = LTODEC(locales->lang[0], locales->lang[1]);
256
 
255
 
257
  switch (lang) {
256
  switch (lang) {
258
    case LTODEC('F', 'R'):
257
    case LTODEC('F', 'R'):
259
      keyboff = OFFLOC_FR;
258
      keyboff = OFFLOC_FR;
260
      keyblen = OFFLEN_FR;
259
      keyblen = OFFLEN_FR;
261
      break;
260
      break;
262
    case LTODEC('P', 'L'):
261
    case LTODEC('P', 'L'):
263
      keyboff = OFFLOC_PL;
262
      keyboff = OFFLOC_PL;
264
      keyblen = OFFLEN_PL;
263
      keyblen = OFFLEN_PL;
265
      break;
264
      break;
266
    case LTODEC('T', 'R'):
265
    case LTODEC('T', 'R'):
267
      keyboff = OFFLOC_TR;
266
      keyboff = OFFLOC_TR;
268
      keyblen = OFFLEN_TR;
267
      keyblen = OFFLEN_TR;
269
      break;
268
      break;
270
    default: /* otherwise propose all possible keyoard layouts */
269
    default: /* otherwise propose all possible keyoard layouts */
271
      keyboff = 0;
270
      keyboff = 0;
272
      keyblen = OFFCOUNT;
271
      keyblen = OFFCOUNT;
273
      break;
272
      break;
274
  }
273
  }
275
  if (keyblen == 1) return(MENUNEXT); /* do not ask for keyboard layout if only one is available for given language */
274
  if (keyblen == 1) return(MENUNEXT); /* do not ask for keyboard layout if only one is available for given language */
276
  newscreen(0);
275
  newscreen(0);
277
  putstringnls(5, 1, COLOR_BODY[mono], 1, 5, "Svarog386 supports the keyboard layouts used in different countries. Choose the keyboard layout you want.");
276
  putstringnls(5, 1, COLOR_BODY[mono], 1, 5, "Svarog386 supports the keyboard layouts used in different countries. Choose the keyboard layout you want.");
278
  menuheight = keyblen + 2;
277
  menuheight = keyblen + 2;
279
  if (menuheight > 13) menuheight = 13;
278
  if (menuheight > 13) menuheight = 13;
280
  if (menuselect(10, -1, menuheight, &(kblayouts[keyboff]), keyblen) < 0) return(MENUPREV);
279
  if (menuselect(10, -1, menuheight, &(kblayouts[keyboff]), keyblen) < 0) return(MENUPREV);
281
  return(MENUNEXT);
280
  return(MENUNEXT);
282
}
281
}
283
 
282
 
284
 
283
 
285
/* returns 0 if installation must proceed, non-zero otherwise */
284
/* returns 0 if installation must proceed, non-zero otherwise */
286
static int welcomescreen(void) {
285
static int welcomescreen(void) {
287
  int c;
286
  int c;
288
  char *choice[] = {"Install Svarog386 to disk", "Quit to DOS", NULL};
287
  char *choice[] = {"Install Svarog386 to disk", "Quit to DOS", NULL};
289
  choice[0] = kittengets(0, 1, choice[0]);
288
  choice[0] = kittengets(0, 1, choice[0]);
290
  choice[1] = kittengets(0, 2, choice[1]);
289
  choice[1] = kittengets(0, 2, choice[1]);
291
  newscreen(0);
290
  newscreen(0);
292
  putstringnls(4, 1, COLOR_BODY[mono], 2, 0, "You are about to install Svarog386: a free, MSDOS-compatible operating system based on the FreeDOS kernel. Svarog386 targets 386+ computers and comes with a variety of third-party applications.\n\nWARNING: If your PC has another operating system installed, this other system might be unable to boot once Svarog386 is installed.");
291
  putstringnls(4, 1, COLOR_BODY[mono], 2, 0, "You are about to install Svarog386: a free, MSDOS-compatible operating system based on the FreeDOS kernel. Svarog386 targets 386+ computers and comes with a variety of third-party applications.\n\nWARNING: If your PC has another operating system installed, this other system might be unable to boot once Svarog386 is installed.");
293
  c = menuselect(13, -1, 4, choice, -1);
292
  c = menuselect(13, -1, 4, choice, -1);
294
  if (c < 0) return(MENUPREV);
293
  if (c < 0) return(MENUPREV);
295
  if (c == 0) return(MENUNEXT);
294
  if (c == 0) return(MENUNEXT);
296
  return(MENUQUIT);
295
  return(MENUQUIT);
297
}
296
}
298
 
297
 
299
 
298
 
300
/* returns 1 if drive is removable, 0 if not, -1 on error */
299
/* returns 1 if drive is removable, 0 if not, -1 on error */
301
static int isdriveremovable(int drv) {
300
static int isdriveremovable(int drv) {
302
  union REGS r;
301
  union REGS r;
303
  r.x.ax = 0x4408;
302
  r.x.ax = 0x4408;
304
  r.h.bl = drv;
303
  r.h.bl = drv;
305
  int86(0x21, &r, &r);
304
  int86(0x21, &r, &r);
306
  /* CF set on error, AX set to 0 if removable, 1 if fixed */
305
  /* CF set on error, AX set to 0 if removable, 1 if fixed */
307
  if (r.x.cflag != 0) return(-1);
306
  if (r.x.cflag != 0) return(-1);
308
  if (r.x.ax == 0) return(1);
307
  if (r.x.ax == 0) return(1);
309
  return(0);
308
  return(0);
310
}
309
}
311
 
310
 
312
 
311
 
313
/* returns total disk space of drive drv (in MiB, max 2048), or -1 if drive invalid */
312
/* returns total disk space of drive drv (in MiB, max 2048), or -1 if drive invalid */
314
static int disksize(int drv) {
313
static int disksize(int drv) {
315
  long res;
314
  long res;
316
  union REGS r;
315
  union REGS r;
317
  r.h.ah = 0x36; /* DOS 2+ get free disk space */
316
  r.h.ah = 0x36; /* DOS 2+ get free disk space */
318
  r.h.dl = drv;
317
  r.h.dl = drv;
319
  int86(0x21, &r, &r);
318
  int86(0x21, &r, &r);
320
  if (r.x.ax == 0xffffu) return(-1); /* AX set to FFFFh if drive invalid */
319
  if (r.x.ax == 0xffffu) return(-1); /* AX set to FFFFh if drive invalid */
321
  res = r.x.ax;  /* sectors per cluster */
320
  res = r.x.ax;  /* sectors per cluster */
322
  res *= r.x.dx; /* dx contains total clusters, bx contains free clusters */
321
  res *= r.x.dx; /* dx contains total clusters, bx contains free clusters */
323
  res *= r.x.cx; /* bytes per sector */
322
  res *= r.x.cx; /* bytes per sector */
324
  res >>= 20;    /* convert bytes to MiB */
323
  res >>= 20;    /* convert bytes to MiB */
325
  return(res);
324
  return(res);
326
}
325
}
327
 
326
 
328
 
327
 
329
/* returns 0 if disk is empty, non-zero otherwise */
328
/* returns 0 if disk is empty, non-zero otherwise */
330
static int diskempty(int drv) {
329
static int diskempty(int drv) {
331
  unsigned int rc;
330
  unsigned int rc;
332
  int res;
331
  int res;
333
  char buff[8];
332
  char buff[8];
334
  struct find_t fileinfo;
333
  struct find_t fileinfo;
335
  snprintf(buff, sizeof(buff), "%c:\\*.*", 'A' + drv - 1);
334
  snprintf(buff, sizeof(buff), "%c:\\*.*", 'A' + drv - 1);
336
  rc = _dos_findfirst(buff, _A_NORMAL | _A_SUBDIR | _A_HIDDEN | _A_SYSTEM, &fileinfo);
335
  rc = _dos_findfirst(buff, _A_NORMAL | _A_SUBDIR | _A_HIDDEN | _A_SYSTEM, &fileinfo);
337
  if (rc == 0) {
336
  if (rc == 0) {
338
    res = 1; /* call successfull means disk is not empty */
337
    res = 1; /* call successfull means disk is not empty */
339
  } else {
338
  } else {
340
    res = 0;
339
    res = 0;
341
  }
340
  }
342
  /* _dos_findclose(&fileinfo); */ /* apparently required only on OS/2 */
341
  /* _dos_findclose(&fileinfo); */ /* apparently required only on OS/2 */
343
  return(res);
342
  return(res);
344
}
343
}
345
 
344
 
346
 
345
 
347
static int preparedrive(void) {
346
static int preparedrive(void) {
348
  int driveremovable;
347
  int driveremovable;
349
  int selecteddrive = 3; /* hardcoded to 'C:' for now */
348
  int selecteddrive = 3; /* hardcoded to 'C:' for now */
350
  int cselecteddrive;
349
  int cselecteddrive;
351
  int ds;
350
  int ds;
352
  int choice;
351
  int choice;
353
  char buff[1024];
352
  char buff[1024];
354
  cselecteddrive = 'A' + selecteddrive - 1;
353
  cselecteddrive = 'A' + selecteddrive - 1;
355
  for (;;) {
354
  for (;;) {
356
    driveremovable = isdriveremovable(selecteddrive);
355
    driveremovable = isdriveremovable(selecteddrive);
357
    if (driveremovable < 0) {
356
    if (driveremovable < 0) {
358
      char *list[] = { "Create a partition automatically", "Run the FDISK partitioning tool", "Quit to DOS", NULL};
357
      char *list[] = { "Create a partition automatically", "Run the FDISK partitioning tool", "Quit to DOS", NULL};
359
      newscreen(0);
358
      newscreen(0);
360
      list[0] = kittengets(0, 3, list[0]);
359
      list[0] = kittengets(0, 3, list[0]);
361
      list[1] = kittengets(0, 4, list[1]);
360
      list[1] = kittengets(0, 4, list[1]);
362
      list[2] = kittengets(0, 2, list[2]);
361
      list[2] = kittengets(0, 2, list[2]);
363
      snprintf(buff, sizeof(buff), kittengets(3, 0, "ERROR: Drive %c: could not be found. Perhaps your hard disk needs to be partitioned first. Please create at least one partition on your hard disk, so Svarog386 can be installed on it. Note, that Svarog386 requires at least %d MiB of available disk space.\n\nYou can use the FDISK partitioning tool for creating the required partition manually, or you can let the installer partitioning your disk automatically. You can also abort the installation to use any other partition manager of your choice."), cselecteddrive, SVAROG_DISK_REQ);
362
      snprintf(buff, sizeof(buff), kittengets(3, 0, "ERROR: Drive %c: could not be found. Perhaps your hard disk needs to be partitioned first. Please create at least one partition on your hard disk, so Svarog386 can be installed on it. Note, that Svarog386 requires at least %d MiB of available disk space.\n\nYou can use the FDISK partitioning tool for creating the required partition manually, or you can let the installer partitioning your disk automatically. You can also abort the installation to use any other partition manager of your choice."), cselecteddrive, SVAROG_DISK_REQ);
364
      putstringwrap(4, 1, COLOR_BODY[mono], buff);
363
      putstringwrap(4, 1, COLOR_BODY[mono], buff);
365
      switch (menuselect(14, -1, 5, list, -1)) {
364
      switch (menuselect(14, -1, 5, list, -1)) {
366
        case 0:
365
        case 0:
367
          system("FDISK /AUTO");
366
          system("FDISK /AUTO");
368
          break;
367
          break;
369
        case 1:
368
        case 1:
370
          video_clear(0x0700, 0);
369
          video_clear(0x0700, 0, 0);
371
          video_movecursor(0, 0);
370
          video_movecursor(0, 0);
372
          system("FDISK");
371
          system("FDISK");
373
          break;
372
          break;
374
        case 2:
373
        case 2:
375
          return(MENUQUIT);
374
          return(MENUQUIT);
376
        default:
375
        default:
377
          return(-1);
376
          return(-1);
378
      }
377
      }
379
      newscreen(2);
378
      newscreen(2);
380
      putstringnls(10, 10, COLOR_BODY[mono], 3, 1, "Your computer will reboot now.");
379
      putstringnls(10, 10, COLOR_BODY[mono], 3, 1, "Your computer will reboot now.");
381
      putstringnls(12, 10, COLOR_BODY[mono], 0, 5, "Press any key...");
380
      putstringnls(12, 10, COLOR_BODY[mono], 0, 5, "Press any key...");
382
      input_getkey();
381
      input_getkey();
383
      reboot();
382
      reboot();
384
      return(MENUQUIT);
383
      return(MENUQUIT);
385
    } else if (driveremovable > 0) {
384
    } else if (driveremovable > 0) {
386
      newscreen(2);
385
      newscreen(2);
387
      snprintf(buff, sizeof(buff), kittengets(3, 2, "ERROR: Drive %c: is a removable device. Installation aborted."), cselecteddrive);
386
      snprintf(buff, sizeof(buff), kittengets(3, 2, "ERROR: Drive %c: is a removable device. Installation aborted."), cselecteddrive);
388
      video_putstring(9, 1, COLOR_BODY[mono], buff, -1);
387
      video_putstring(9, 1, COLOR_BODY[mono], buff, -1);
389
      putstringnls(11, 2, COLOR_BODY[mono], 0, 5, "Press any key...");
388
      putstringnls(11, 2, COLOR_BODY[mono], 0, 5, "Press any key...");
390
      return(MENUQUIT);
389
      return(MENUQUIT);
391
    }
390
    }
392
    /* if not formatted, propose to format it right away (try to create a directory) */
391
    /* if not formatted, propose to format it right away (try to create a directory) */
393
    snprintf(buff, sizeof(buff), "%c:\\SVWRTEST.123", cselecteddrive);
392
    snprintf(buff, sizeof(buff), "%c:\\SVWRTEST.123", cselecteddrive);
394
    if (mkdir(buff) == 0) {
393
    if (mkdir(buff) == 0) {
395
      rmdir(buff);
394
      rmdir(buff);
396
    } else {
395
    } else {
397
      char *list[] = { "Proceed with formatting", "Quit to DOS", NULL};
396
      char *list[] = { "Proceed with formatting", "Quit to DOS", NULL};
398
      newscreen(0);
397
      newscreen(0);
399
      list[0] = kittengets(0, 6, list[0]);
398
      list[0] = kittengets(0, 6, list[0]);
400
      list[1] = kittengets(0, 2, list[1]);
399
      list[1] = kittengets(0, 2, list[1]);
401
      snprintf(buff, sizeof(buff), kittengets(3, 3, "ERROR: Drive %c: seems to be unformated. Do you wish to format it?"), cselecteddrive);
400
      snprintf(buff, sizeof(buff), kittengets(3, 3, "ERROR: Drive %c: seems to be unformated. Do you wish to format it?"), cselecteddrive);
402
      video_putstring(7, 1, COLOR_BODY[mono], buff, -1);
401
      video_putstring(7, 1, COLOR_BODY[mono], buff, -1);
403
      choice = menuselect(12, -1, 4, list, -1);
402
      choice = menuselect(12, -1, 4, list, -1);
404
      if (choice < 0) return(MENUPREV);
403
      if (choice < 0) return(MENUPREV);
405
      if (choice == 1) return(MENUQUIT);
404
      if (choice == 1) return(MENUQUIT);
406
      video_clear(0x0700, 0);
405
      video_clear(0x0700, 0, 0);
407
      video_movecursor(0, 0);
406
      video_movecursor(0, 0);
408
      snprintf(buff, sizeof(buff), "FORMAT %c: /Q /U /Z:seriously /V:SVAROG386", cselecteddrive);
407
      snprintf(buff, sizeof(buff), "FORMAT %c: /Q /U /Z:seriously /V:SVAROG386", cselecteddrive);
409
      system(buff);
408
      system(buff);
410
      continue;
409
      continue;
411
    }
410
    }
412
    /* check total disk space */
411
    /* check total disk space */
413
    ds = disksize(selecteddrive);
412
    ds = disksize(selecteddrive);
414
    if (ds < SVAROG_DISK_REQ) {
413
    if (ds < SVAROG_DISK_REQ) {
415
      int y = 9;
414
      int y = 9;
416
      newscreen(2);
415
      newscreen(2);
417
      snprintf(buff, sizeof(buff), kittengets(3, 4, "ERROR: Drive %c: is not big enough! Svarog386 requires a disk of at least %d MiB."), cselecteddrive);
416
      snprintf(buff, sizeof(buff), kittengets(3, 4, "ERROR: Drive %c: is not big enough! Svarog386 requires a disk of at least %d MiB."), cselecteddrive);
418
      y += putstringwrap(y, 1, COLOR_BODY[mono], buff);
417
      y += putstringwrap(y, 1, COLOR_BODY[mono], buff);
419
      putstringnls(++y, 1, COLOR_BODY[mono], 0, 5, "Press any key...");
418
      putstringnls(++y, 1, COLOR_BODY[mono], 0, 5, "Press any key...");
420
      input_getkey();
419
      input_getkey();
421
      return(MENUQUIT);
420
      return(MENUQUIT);
422
    }
421
    }
423
    /* is the disk empty? */
422
    /* is the disk empty? */
424
    newscreen(0);
423
    newscreen(0);
425
    if (diskempty(selecteddrive) != 0) {
424
    if (diskempty(selecteddrive) != 0) {
426
      char *list[] = { "Proceed with formatting", "Quit to DOS", NULL};
425
      char *list[] = { "Proceed with formatting", "Quit to DOS", NULL};
427
      int y = 6;
426
      int y = 6;
428
      list[0] = kittengets(0, 6, list[0]);
427
      list[0] = kittengets(0, 6, list[0]);
429
      list[1] = kittengets(0, 2, list[1]);
428
      list[1] = kittengets(0, 2, list[1]);
430
      snprintf(buff, sizeof(buff), kittengets(3, 5, "ERROR: Drive %c: is not empty. Svarog386 must be installed on an empty disk.\n\nYou can format the disk now, to make it empty. Note however, that this will ERASE ALL CURRENT DATA on your disk."), cselecteddrive);
429
      snprintf(buff, sizeof(buff), kittengets(3, 5, "ERROR: Drive %c: is not empty. Svarog386 must be installed on an empty disk.\n\nYou can format the disk now, to make it empty. Note however, that this will ERASE ALL CURRENT DATA on your disk."), cselecteddrive);
431
      y += putstringwrap(y, 1, COLOR_BODY[mono], buff);
430
      y += putstringwrap(y, 1, COLOR_BODY[mono], buff);
432
      choice = menuselect(++y, -1, 4, list, -1);
431
      choice = menuselect(++y, -1, 4, list, -1);
433
      if (choice < 0) return(MENUPREV);
432
      if (choice < 0) return(MENUPREV);
434
      if (choice == 1) return(MENUQUIT);
433
      if (choice == 1) return(MENUQUIT);
435
      video_clear(0x0700, 0);
434
      video_clear(0x0700, 0, 0);
436
      video_movecursor(0, 0);
435
      video_movecursor(0, 0);
437
      snprintf(buff, sizeof(buff), "FORMAT %c: /Q /U /Z:seriously /V:SVAROG386", cselecteddrive);
436
      snprintf(buff, sizeof(buff), "FORMAT %c: /Q /U /Z:seriously /V:SVAROG386", cselecteddrive);
438
      system(buff);
437
      system(buff);
439
      continue;
438
      continue;
440
    } else {
439
    } else {
441
      /* final confirmation */
440
      /* final confirmation */
442
      char *list[] = { "Install Svarog386", "Quit to DOS", NULL};
441
      char *list[] = { "Install Svarog386", "Quit to DOS", NULL};
443
      list[0] = kittengets(0, 1, list[0]);
442
      list[0] = kittengets(0, 1, list[0]);
444
      list[1] = kittengets(0, 2, list[1]);
443
      list[1] = kittengets(0, 2, list[1]);
445
      snprintf(buff, sizeof(buff), kittengets(3, 6, "The installation of Svarog386 to %c: is about to begin."), cselecteddrive);
444
      snprintf(buff, sizeof(buff), kittengets(3, 6, "The installation of Svarog386 to %c: is about to begin."), cselecteddrive);
446
      video_putstring(7, -1, COLOR_BODY[mono], buff, -1);
445
      video_putstring(7, -1, COLOR_BODY[mono], buff, -1);
447
      choice = menuselect(10, -1, 4, list, -1);
446
      choice = menuselect(10, -1, 4, list, -1);
448
      if (choice < 0) return(MENUPREV);
447
      if (choice < 0) return(MENUPREV);
449
      if (choice == 1) return(MENUQUIT);
448
      if (choice == 1) return(MENUQUIT);
450
      snprintf(buff, sizeof(buff), "SYS A: %c: > NUL", cselecteddrive);
449
      snprintf(buff, sizeof(buff), "SYS A: %c: > NUL", cselecteddrive);
451
      system(buff);
450
      system(buff);
452
      snprintf(buff, sizeof(buff), "%c:\\TEMP", cselecteddrive);
451
      snprintf(buff, sizeof(buff), "%c:\\TEMP", cselecteddrive);
453
      mkdir(buff);
452
      mkdir(buff);
454
      return(cselecteddrive);
453
      return(cselecteddrive);
455
    }
454
    }
456
  }
455
  }
457
}
456
}
458
 
457
 
459
 
458
 
460
/* copy file src into dst, substituting all characters c1 by c2 */
459
/* copy file src into dst, substituting all characters c1 by c2 */
461
static void fcopysub(char *dst, char *src, char c1, char c2) {
460
static void fcopysub(char *dst, char *src, char c1, char c2) {
462
  FILE *fdd, *fds;
461
  FILE *fdd, *fds;
463
  int buff;
462
  int buff;
464
  fds = fopen(src, "rb");
463
  fds = fopen(src, "rb");
465
  if (fds == NULL) return;
464
  if (fds == NULL) return;
466
  fdd = fopen(dst, "wb");
465
  fdd = fopen(dst, "wb");
467
  if (fdd == NULL) {
466
  if (fdd == NULL) {
468
    fclose(fds);
467
    fclose(fds);
469
    return;
468
    return;
470
  }
469
  }
471
  /* */
470
  /* */
472
  for (;;) {
471
  for (;;) {
473
    buff = fgetc(fds);
472
    buff = fgetc(fds);
474
    if (buff == EOF) break;
473
    if (buff == EOF) break;
475
    if (buff == c1) buff = c2;
474
    if (buff == c1) buff = c2;
476
    fprintf(fdd, "%c", buff);
475
    fprintf(fdd, "%c", buff);
477
  }
476
  }
478
  /* close files and return */
477
  /* close files and return */
479
  fclose(fdd);
478
  fclose(fdd);
480
  fclose(fds);
479
  fclose(fds);
481
}
480
}
482
 
481
 
483
 
482
 
484
static void bootfilesgen(int targetdrv, struct slocales *locales, int cdromdrv) {
483
static void bootfilesgen(int targetdrv, struct slocales *locales, int cdromdrv) {
485
  char buff[128];
484
  char buff[128];
486
  FILE *fd;
485
  FILE *fd;
487
  /*** CONFIG.SYS ***/
486
  /*** CONFIG.SYS ***/
488
  snprintf(buff, sizeof(buff), "%c:\\CONFIG.SYS", targetdrv);
487
  snprintf(buff, sizeof(buff), "%c:\\CONFIG.SYS", targetdrv);
489
  fd = fopen(buff, "wb");
488
  fd = fopen(buff, "wb");
490
  if (fd == NULL) return;
489
  if (fd == NULL) return;
491
  fprintf(fd, "DOS=UMB,HIGH\r\n");
490
  fprintf(fd, "DOS=UMB,HIGH\r\n");
492
  fprintf(fd, "FILES=50\r\n");
491
  fprintf(fd, "FILES=50\r\n");
493
  fprintf(fd, "DEVICE=%c:\\SYSTEM\\SVAROG.386\\BIN\\HIMEMX.EXE\r\n", targetdrv);
492
  fprintf(fd, "DEVICE=%c:\\SYSTEM\\SVAROG.386\\BIN\\HIMEMX.EXE\r\n", targetdrv);
494
  if (strcmp(locales->lang, "EN") == 0) {
493
  if (strcmp(locales->lang, "EN") == 0) {
495
    strcpy(buff, "command");
494
    strcpy(buff, "command");
496
  } else {
495
  } else {
497
    snprintf(buff, sizeof(buff), "CMD-%s", locales->lang);
496
    snprintf(buff, sizeof(buff), "CMD-%s", locales->lang);
498
  }
497
  }
499
  fprintf(fd, "SHELLHIGH=%c:\\SYSTEM\\SVAROG.386\\BIN\\%s.COM /E:512 /P\r\n", targetdrv, buff);
498
  fprintf(fd, "SHELLHIGH=%c:\\SYSTEM\\SVAROG.386\\BIN\\%s.COM /E:512 /P\r\n", targetdrv, buff);
500
  fprintf(fd, "REM COUNTRY=001,437,%c:\\SYSTEM\\CONF\\COUNTRY.SYS\r\n", targetdrv);
499
  fprintf(fd, "REM COUNTRY=001,437,%c:\\SYSTEM\\CONF\\COUNTRY.SYS\r\n", targetdrv);
501
  fprintf(fd, "DEVICE=%c:\\SYSTEM\\DRIVERS\\UDVD2\\UDVD2.SYS /D:SVCD0001 /H\r\n", targetdrv);
500
  fprintf(fd, "DEVICE=%c:\\SYSTEM\\DRIVERS\\UDVD2\\UDVD2.SYS /D:SVCD0001 /H\r\n", targetdrv);
502
  fclose(fd);
501
  fclose(fd);
503
  /*** AUTOEXEC.BAT ***/
502
  /*** AUTOEXEC.BAT ***/
504
  snprintf(buff, sizeof(buff), "%c:\\AUTOEXEC.BAT", targetdrv);
503
  snprintf(buff, sizeof(buff), "%c:\\AUTOEXEC.BAT", targetdrv);
505
  fd = fopen(buff, "wb");
504
  fd = fopen(buff, "wb");
506
  if (fd == NULL) return;
505
  if (fd == NULL) return;
507
  fprintf(fd, "@ECHO OFF\r\n");
506
  fprintf(fd, "@ECHO OFF\r\n");
508
  fprintf(fd, "SET TEMP=%c:\\TEMP\r\n", targetdrv);
507
  fprintf(fd, "SET TEMP=%c:\\TEMP\r\n", targetdrv);
509
  fprintf(fd, "SET DOSDIR=%c:\\SYSTEM\\SVAROG.386\r\n", targetdrv);
508
  fprintf(fd, "SET DOSDIR=%c:\\SYSTEM\\SVAROG.386\r\n", targetdrv);
510
  fprintf(fd, "SET NLSPATH=%%DOSDIR%%\\NLS\r\n");
509
  fprintf(fd, "SET NLSPATH=%%DOSDIR%%\\NLS\r\n");
511
  fprintf(fd, "SET LANG=%s\r\n", locales->lang);
510
  fprintf(fd, "SET LANG=%s\r\n", locales->lang);
512
  fprintf(fd, "SET DIRCMD=/OGNE/P/4\r\n");
511
  fprintf(fd, "SET DIRCMD=/OGNE/P/4\r\n");
513
  fprintf(fd, "SET FDNPKG.CFG=%c:\\SYSTEM\\CFG\\FDNPKG.CFG\r\n", targetdrv);
512
  fprintf(fd, "SET FDNPKG.CFG=%c:\\SYSTEM\\CFG\\FDNPKG.CFG\r\n", targetdrv);
514
  fprintf(fd, "SET WATTCP.CFG=%c:\\SYSTEM\\CFG\\WATTCP.CFG\r\n", targetdrv);
513
  fprintf(fd, "SET WATTCP.CFG=%c:\\SYSTEM\\CFG\\WATTCP.CFG\r\n", targetdrv);
515
  fprintf(fd, "PATH %%DOSDIR%%\\BIN;%c:\\SYSTEM\\LINKS\r\n", targetdrv);
514
  fprintf(fd, "PATH %%DOSDIR%%\\BIN;%c:\\SYSTEM\\LINKS\r\n", targetdrv);
516
  fprintf(fd, "PROMPT $P$G\r\n");
515
  fprintf(fd, "PROMPT $P$G\r\n");
517
  fprintf(fd, "ALIAS REBOOT=FDAPM COLDBOOT\r\n");
516
  fprintf(fd, "ALIAS REBOOT=FDAPM COLDBOOT\r\n");
518
  fprintf(fd, "ALIAS HALT=FDAPM POWEROFF\r\n");
517
  fprintf(fd, "ALIAS HALT=FDAPM POWEROFF\r\n");
519
  fprintf(fd, "FDAPM APMDOS\r\n");
518
  fprintf(fd, "FDAPM APMDOS\r\n");
520
  fprintf(fd, "\r\n");
519
  fprintf(fd, "\r\n");
521
  if (locales->egafile > 0) {
520
  if (locales->egafile > 0) {
522
    fprintf(fd, "DISPLAY CON=(EGA,,1)\r\n");
521
    fprintf(fd, "DISPLAY CON=(EGA,,1)\r\n");
523
    if (locales->egafile == 1) {
522
    if (locales->egafile == 1) {
524
      fprintf(fd, "MODE CON CP PREPARE=((%u) %c:\\SYSTEM\\SVAROG.386\\CPI\\EGA.CPX)\r\n", locales->codepage, targetdrv);
523
      fprintf(fd, "MODE CON CP PREPARE=((%u) %c:\\SYSTEM\\SVAROG.386\\CPI\\EGA.CPX)\r\n", locales->codepage, targetdrv);
525
    } else {
524
    } else {
526
      fprintf(fd, "MODE CON CP PREPARE=((%u) %c:\\SYSTEM\\SVAROG.386\\CPI\\EGA%d.CPX)\r\n", locales->codepage, targetdrv, locales->egafile);
525
      fprintf(fd, "MODE CON CP PREPARE=((%u) %c:\\SYSTEM\\SVAROG.386\\CPI\\EGA%d.CPX)\r\n", locales->codepage, targetdrv, locales->egafile);
527
    }
526
    }
528
    fprintf(fd, "MODE CON CP SELECT=%u\r\n", locales->codepage);
527
    fprintf(fd, "MODE CON CP SELECT=%u\r\n", locales->codepage);
529
  }
528
  }
530
  if (locales->keybfile > 0) {
529
  if (locales->keybfile > 0) {
531
    if (locales->keybfile == 1) {
530
    if (locales->keybfile == 1) {
532
      fprintf(fd, "KEYB %s,%d,%c:\\SYSTEM\\SVAROG.386\\BIN\\KEYBOARD.SYS\r\n", locales->keybcode, locales->codepage, targetdrv);
531
      fprintf(fd, "KEYB %s,%d,%c:\\SYSTEM\\SVAROG.386\\BIN\\KEYBOARD.SYS\r\n", locales->keybcode, locales->codepage, targetdrv);
533
    } else {
532
    } else {
534
      fprintf(fd, "KEYB %s,%d,%c:\\SYSTEM\\SVAROG.386\\BIN\\KEYBRD%d.SYS\r\n", locales->keybcode, locales->codepage, targetdrv, locales->keybfile);
533
      fprintf(fd, "KEYB %s,%d,%c:\\SYSTEM\\SVAROG.386\\BIN\\KEYBRD%d.SYS\r\n", locales->keybcode, locales->codepage, targetdrv, locales->keybfile);
535
    }
534
    }
536
    fprintf(fd, "\r\n");
535
    fprintf(fd, "\r\n");
537
  }
536
  }
538
  fprintf(fd, "SHSUCDX /d:SVCD0001\r\n");
537
  fprintf(fd, "SHSUCDX /d:SVCD0001\r\n");
539
  fprintf(fd, "\r\n");
538
  fprintf(fd, "\r\n");
540
  fprintf(fd, "REM Uncomment the line below for automatic mouse support\r\n");
539
  fprintf(fd, "REM Uncomment the line below for automatic mouse support\r\n");
541
  fprintf(fd, "REM CTMOUSE\r\n");
540
  fprintf(fd, "REM CTMOUSE\r\n");
542
  fprintf(fd, "\r\n");
541
  fprintf(fd, "\r\n");
543
  fprintf(fd, "ECHO.\r\n");
542
  fprintf(fd, "ECHO.\r\n");
544
  fprintf(fd, "ECHO %s\r\n", kittengets(6, 0, "Welcome to Svarog386! Type 'HELP' if you need help."));
543
  fprintf(fd, "ECHO %s\r\n", kittengets(6, 0, "Welcome to Svarog386! Type 'HELP' if you need help."));
545
  fclose(fd);
544
  fclose(fd);
546
  /*** CREATE DIRECTORY FOR OTHER CONFIGURATION FILES ***/
545
  /*** CREATE DIRECTORY FOR OTHER CONFIGURATION FILES ***/
547
  snprintf(buff, sizeof(buff), "%c:\\SYSTEM\\CFG", targetdrv);
546
  snprintf(buff, sizeof(buff), "%c:\\SYSTEM\\CFG", targetdrv);
548
  mkdir(buff);
547
  mkdir(buff);
549
  /*** FDNPKG.CFG ***/
548
  /*** FDNPKG.CFG ***/
550
  snprintf(buff, sizeof(buff), "%c:\\SYSTEM\\CFG\\FDNPKG.CFG", targetdrv);
549
  snprintf(buff, sizeof(buff), "%c:\\SYSTEM\\CFG\\FDNPKG.CFG", targetdrv);
551
  fcopysub(buff, "A:\\DAT\\FDNPKG.CFG", '$', cdromdrv);
550
  fcopysub(buff, "A:\\DAT\\FDNPKG.CFG", '$', cdromdrv);
552
  /*** COUNTRY.SYS ***/
551
  /*** COUNTRY.SYS ***/
553
  /*** PICOTCP ***/
552
  /*** PICOTCP ***/
554
  /*** WATTCP ***/
553
  /*** WATTCP ***/
555
}
554
}
556
 
555
 
557
 
556
 
558
static void installpackages(int targetdrv, int cdromdrv) {
557
static void installpackages(int targetdrv, int cdromdrv) {
559
  char *pkglist[] = {
558
  char *pkglist[] = {
560
    "A:\\UDVD2", /* this one's not part of CORE, hence it's stored right on the floppy */
559
    "A:\\UDVD2", /* this one's not part of CORE, hence it's stored right on the floppy */
561
    "APPEND",
560
    "APPEND",
562
    "ASSIGN",
561
    "ASSIGN",
563
    "ATTRIB",
562
    "ATTRIB",
564
    "CHKDSK",
563
    "CHKDSK",
565
    "CHOICE",
564
    "CHOICE",
566
    "COMMAND",
565
    "COMMAND",
567
    "COMP",
566
    "COMP",
568
    "CPIDOS",
567
    "CPIDOS",
569
    "CTMOUSE",
568
    "CTMOUSE",
570
    "DEBUG",
569
    "DEBUG",
571
    "DEFRAG",
570
    "DEFRAG",
572
    "DELTREE",
571
    "DELTREE",
573
    "DEVLOAD",
572
    "DEVLOAD",
574
    "DISKCOMP",
573
    "DISKCOMP",
575
    "DISKCOPY",
574
    "DISKCOPY",
576
    "DISPLAY",
575
    "DISPLAY",
577
    "DOSFSCK",
576
    "DOSFSCK",
578
    "EDIT",
577
    "EDIT",
579
    "EDLIN",
578
    "EDLIN",
580
    "EXE2BIN",
579
    "EXE2BIN",
581
    "FC",
580
    "FC",
582
    "FDAPM",
581
    "FDAPM",
583
    "FDISK",
582
    "FDISK",
584
    "FDNPKG",
583
    "FDNPKG",
585
    "FIND",
584
    "FIND",
586
    "FORMAT",
585
    "FORMAT",
587
    "HELP",
586
    "HELP",
588
    "HIMEMX",
587
    "HIMEMX",
589
    "KERNEL",
588
    "KERNEL",
590
    "KEYB",
589
    "KEYB",
591
    "KEYB_LAY",
590
    "KEYB_LAY",
592
    "LABEL",
591
    "LABEL",
593
    "LBACACHE",
592
    "LBACACHE",
594
    "MEM",
593
    "MEM",
595
    "MIRROR",
594
    "MIRROR",
596
    "MODE",
595
    "MODE",
597
    "MORE",
596
    "MORE",
598
    "MOVE",
597
    "MOVE",
599
    "NANSI",
598
    "NANSI",
600
    "NLSFUNC",
599
    "NLSFUNC",
601
    "PRINT",
600
    "PRINT",
602
    "RDISK",
601
    "RDISK",
603
    "RECOVER",
602
    "RECOVER",
604
    "REPLACE",
603
    "REPLACE",
605
    "SHARE",
604
    "SHARE",
606
    "SHSUCDX",
605
    "SHSUCDX",
607
    "SORT",
606
    "SORT",
608
    "SWSUBST",
607
    "SWSUBST",
609
    "TREE",
608
    "TREE",
610
    "UNDELETE",
609
    "UNDELETE",
611
    "XCOPY",
610
    "XCOPY",
612
    NULL
611
    NULL
613
  };
612
  };
614
  int i, pkglistlen;
613
  int i, pkglistlen;
615
  char buff[64];
614
  char buff[64];
616
  newscreen(3);
615
  newscreen(3);
617
  /* count how long the pkg list is */
616
  /* count how long the pkg list is */
618
  for (pkglistlen = 0; pkglist[pkglistlen] != NULL; pkglistlen++);
617
  for (pkglistlen = 0; pkglist[pkglistlen] != NULL; pkglistlen++);
619
  /* set DOSDIR and friends */
618
  /* set DOSDIR and friends */
620
  snprintf(buff, sizeof(buff), "%c:\\SYSTEM\\SVAROG.386", targetdrv);
619
  snprintf(buff, sizeof(buff), "%c:\\SYSTEM\\SVAROG.386", targetdrv);
621
  setenv("DOSDIR", buff, 1);
620
  setenv("DOSDIR", buff, 1);
622
  snprintf(buff, sizeof(buff), "%c:\\TEMP", targetdrv);
621
  snprintf(buff, sizeof(buff), "%c:\\TEMP", targetdrv);
623
  setenv("TEMP", buff, 1);
622
  setenv("TEMP", buff, 1);
624
  /* install packages */
623
  /* install packages */
625
  for (i = 0; pkglist[i] != NULL; i++) {
624
  for (i = 0; pkglist[i] != NULL; i++) {
626
    char buff[128];
625
    char buff[128];
627
    snprintf(buff, sizeof(buff), kittengets(4, 0, "Installing package %d/%d: %s"), i+1, pkglistlen, pkglist[i]);
626
    snprintf(buff, sizeof(buff), kittengets(4, 0, "Installing package %d/%d: %s"), i+1, pkglistlen, pkglist[i]);
628
    strcat(buff, "       ");
627
    strcat(buff, "       ");
629
    video_putstring(10, 1, COLOR_BODY[mono], buff, -1);
628
    video_putstring(10, 1, COLOR_BODY[mono], buff, -1);
630
    if (pkglist[i][1] == ':') {
629
    if (pkglist[i][1] == ':') {
631
      snprintf(buff, sizeof(buff), "FDINST INSTALL %s.ZIP > NUL", pkglist[i]);
630
      snprintf(buff, sizeof(buff), "FDINST INSTALL %s.ZIP > NUL", pkglist[i]);
632
    } else {
631
    } else {
633
      snprintf(buff, sizeof(buff), "FDINST INSTALL %c:\\CORE\\%s.ZIP > NUL", cdromdrv, pkglist[i]);
632
      snprintf(buff, sizeof(buff), "FDINST INSTALL %c:\\CORE\\%s.ZIP > NUL", cdromdrv, pkglist[i]);
634
    }
633
    }
635
    system(buff);
634
    system(buff);
636
  }
635
  }
637
}
636
}
638
 
637
 
639
 
638
 
640
static void finalreboot(void) {
639
static void finalreboot(void) {
641
  int y = 9;
640
  int y = 9;
642
  newscreen(2);
641
  newscreen(2);
643
  y += putstringnls(y, 1, COLOR_BODY[mono], 5, 0, "Svarog386 installation is over. Your computer will reboot now.\nPlease remove the installation disk from your drive.");
642
  y += putstringnls(y, 1, COLOR_BODY[mono], 5, 0, "Svarog386 installation is over. Your computer will reboot now.\nPlease remove the installation disk from your drive.");
644
  putstringnls(++y, 1, COLOR_BODY[mono], 0, 5, "Press any key...");
643
  putstringnls(++y, 1, COLOR_BODY[mono], 0, 5, "Press any key...");
645
  input_getkey();
644
  input_getkey();
646
  reboot();
645
  reboot();
647
}
646
}
648
 
647
 
649
 
648
 
650
static void loadcp(struct slocales *locales) {
649
static void loadcp(struct slocales *locales) {
651
  char buff[64];
650
  char buff[64];
652
  if (locales->codepage == 437) return;
651
  if (locales->codepage == 437) return;
653
  video_movecursor(1, 0);
652
  video_movecursor(1, 0);
654
  if (locales->egafile == 1) {
653
  if (locales->egafile == 1) {
655
    snprintf(buff, sizeof(buff), "MODE CON CP PREP=((%u) A:\\EGA.CPX) > NUL", locales->codepage);
654
    snprintf(buff, sizeof(buff), "MODE CON CP PREP=((%u) A:\\EGA.CPX) > NUL", locales->codepage);
656
  } else {
655
  } else {
657
    snprintf(buff, sizeof(buff), "MODE CON CP PREP=((%u) A:\\EGA%d.CPX) > NUL", locales->codepage, locales->egafile);
656
    snprintf(buff, sizeof(buff), "MODE CON CP PREP=((%u) A:\\EGA%d.CPX) > NUL", locales->codepage, locales->egafile);
658
  }
657
  }
659
  system(buff);
658
  system(buff);
660
  snprintf(buff, sizeof(buff), "MODE CON CP SEL=%u > NUL", locales->codepage);
659
  snprintf(buff, sizeof(buff), "MODE CON CP SEL=%u > NUL", locales->codepage);
661
  system(buff);
660
  system(buff);
662
  /* below I re-init the video controller - apparently this is required if
661
  /* below I re-init the video controller - apparently this is required if
663
   * I want the new glyph symbols to be actually applied, at least some
662
   * I want the new glyph symbols to be actually applied, at least some
664
   * (broken?) BIOSes, like VBox, apply glyphs only at next video mode change */
663
   * (broken?) BIOSes, like VBox, apply glyphs only at next video mode change */
665
  {
664
  {
666
  union REGS r;
665
  union REGS r;
667
  r.h.ah = 0x0F; /* get current video mode */
666
  r.h.ah = 0x0F; /* get current video mode */
668
  int86(0x10, &r, &r); /* r.h.al contains the current video mode now */
667
  int86(0x10, &r, &r); /* r.h.al contains the current video mode now */
669
  r.h.al |= 128; /* set the high bit of AL to instruct BIOS not to flush VRAM's content (EGA+) */
668
  r.h.al |= 128; /* set the high bit of AL to instruct BIOS not to flush VRAM's content (EGA+) */
670
  r.h.ah = 0; /* re-set video mode (to whatever is set in AL) */
669
  r.h.ah = 0; /* re-set video mode (to whatever is set in AL) */
671
  int86(0x10, &r, &r);
670
  int86(0x10, &r, &r);
672
  }
671
  }
673
}
672
}
674
 
673
 
675
/* checks CD drive drv for the presence of the Svarog386 install CD
674
/* checks CD drive drv for the presence of the Svarog386 install CD
676
 * returns 0 if found, non-zero otherwise */
675
 * returns 0 if found, non-zero otherwise */
677
static int checkcd(char drv) {
676
static int checkcd(char drv) {
678
  FILE *fd;
677
  FILE *fd;
679
  char fname[32];
678
  char fname[32];
680
  snprintf(fname, sizeof(fname), "%c:\\CORE\\MEM.ZIP", drv);
679
  snprintf(fname, sizeof(fname), "%c:\\CORE\\MEM.ZIP", drv);
681
  fd = fopen(fname, "rb");
680
  fd = fopen(fname, "rb");
682
  if (fd == NULL) return(-1);
681
  if (fd == NULL) return(-1);
683
  fclose(fd);
682
  fclose(fd);
684
  return(0);
683
  return(0);
685
}
684
}
686
 
685
 
687
 
686
 
688
int main(void) {
687
int main(void) {
689
  struct slocales locales;
688
  struct slocales locales;
690
  int targetdrv;
689
  int targetdrv;
691
  int cdromdrv;
690
  int cdromdrv;
692
  int action;
691
  int action;
693
 
692
 
694
  /* find where the cdrom drive is */
693
  /* find where the cdrom drive is */
695
  cdromdrv = cdrom_findfirst();
694
  cdromdrv = cdrom_findfirst();
696
  if (cdromdrv < 0) {
695
  if (cdromdrv < 0) {
697
    printf("ERROR: CD-ROM DRIVE NOT FOUND\r\n");
696
    printf("ERROR: CD-ROM DRIVE NOT FOUND\r\n");
698
    return(1);
697
    return(1);
699
  }
698
  }
700
  cdromdrv += 'A'; /* convert the cdrom 'id' (A=0) to an actual drive letter */
699
  cdromdrv += 'A'; /* convert the cdrom 'id' (A=0) to an actual drive letter */
701
  if (checkcd(cdromdrv) != 0) {
700
  if (checkcd(cdromdrv) != 0) {
702
    printf("ERROR: SVAROG386 INSTALLATION CD NOT FOUND IN THE DRIVE.\r\n");
701
    printf("ERROR: SVAROG386 INSTALLATION CD NOT FOUND IN THE DRIVE.\r\n");
703
    return(1);
702
    return(1);
704
  }
703
  }
705
 
704
 
706
  /* init screen and detect mono status */
705
  /* init screen and detect mono status */
707
  mono = video_init();
706
  mono = video_init();
708
 
707
 
709
  kittenopen("INSTALL"); /* load initial NLS support */
708
  kittenopen("INSTALL"); /* load initial NLS support */
710
 
709
 
711
 SelectLang:
710
 SelectLang:
712
  action = selectlang(&locales); /* welcome to svarog, select your language */
711
  action = selectlang(&locales); /* welcome to svarog, select your language */
713
  if (action != MENUNEXT) goto Quit;
712
  if (action != MENUNEXT) goto Quit;
714
  setenv("LANG", locales.lang, 1);
713
  setenv("LANG", locales.lang, 1);
715
  loadcp(&locales);
714
  loadcp(&locales);
716
  kittenclose(); /* reload NLS with new language */
715
  kittenclose(); /* reload NLS with new language */
717
  kittenopen("INSTALL"); /* NLS support */
716
  kittenopen("INSTALL"); /* NLS support */
718
  action = selectkeyb(&locales);  /* what keyb layout should we use? */
717
  action = selectkeyb(&locales);  /* what keyb layout should we use? */
719
  if (action == MENUQUIT) goto Quit;
718
  if (action == MENUQUIT) goto Quit;
720
  if (action == MENUPREV) goto SelectLang;
719
  if (action == MENUPREV) goto SelectLang;
721
 
720
 
722
 WelcomeScreen:
721
 WelcomeScreen:
723
  action = welcomescreen(); /* what svarog386 is, ask whether to run live dos or install */
722
  action = welcomescreen(); /* what svarog386 is, ask whether to run live dos or install */
724
  if (action == MENUQUIT) goto Quit;
723
  if (action == MENUQUIT) goto Quit;
725
  if (action == MENUPREV) goto SelectLang;
724
  if (action == MENUPREV) goto SelectLang;
726
  targetdrv = preparedrive(); /* what drive should we install to? check avail. space */
725
  targetdrv = preparedrive(); /* what drive should we install to? check avail. space */
727
  if (targetdrv == MENUQUIT) goto Quit;
726
  if (targetdrv == MENUQUIT) goto Quit;
728
  if (targetdrv == MENUPREV) goto WelcomeScreen;
727
  if (targetdrv == MENUPREV) goto WelcomeScreen;
729
  /*askaboutsources();*/ /* IF sources are available, ask if installing with them */
728
  /*askaboutsources();*/ /* IF sources are available, ask if installing with them */
730
  installpackages(targetdrv, cdromdrv);    /* install packages */
729
  installpackages(targetdrv, cdromdrv);    /* install packages */
731
  bootfilesgen(targetdrv, &locales, cdromdrv); /* generate boot files and other configurations */
730
  bootfilesgen(targetdrv, &locales, cdromdrv); /* generate boot files and other configurations */
732
  /*localcfg();*/ /* show local params (currency, etc), and propose to change them (based on localcfg) */
731
  /*localcfg();*/ /* show local params (currency, etc), and propose to change them (based on localcfg) */
733
  /*netcfg();*/ /* basic networking config */
732
  /*netcfg();*/ /* basic networking config */
734
  finalreboot(); /* remove the CD and reboot */
733
  finalreboot(); /* remove the CD and reboot */
735
 
734
 
736
 Quit:
735
 Quit:
737
  kittenclose(); /* close NLS support */
736
  kittenclose(); /* close NLS support */
738
  video_clear(0x0700, 0);
737
  video_clear(0x0700, 0, 0);
739
  video_movecursor(0, 0);
738
  video_movecursor(0, 0);
740
  return(0);
739
  return(0);
741
}
740
}
742
 
741