Subversion Repositories SvarDOS

Rev

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

Rev 1277 Rev 1281
1
/* This file is part of the svarlang project and is published under the terms
1
/* This file is part of the svarlang project and is published under the terms
2
 * of the MIT license.
2
 * of the MIT license.
3
 *
3
 *
4
 * Copyright (C) 2021-2023 Mateusz Viste
4
 * Copyright (C) 2021-2023 Mateusz Viste
5
 *
5
 *
6
 * Permission is hereby granted, free of charge, to any person obtaining a
6
 * Permission is hereby granted, free of charge, to any person obtaining a
7
 * copy of this software and associated documentation files (the "Software"),
7
 * copy of this software and associated documentation files (the "Software"),
8
 * to deal in the Software without restriction, including without limitation
8
 * to deal in the Software without restriction, including without limitation
9
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10
 * and/or sell copies of the Software, and to permit persons to whom the
10
 * and/or sell copies of the Software, and to permit persons to whom the
11
 * Software is furnished to do so, subject to the following conditions:
11
 * Software is furnished to do so, subject to the following conditions:
12
 *
12
 *
13
 * The above copyright notice and this permission notice shall be included in
13
 * The above copyright notice and this permission notice shall be included in
14
 * all copies or substantial portions of the Software.
14
 * all copies or substantial portions of the Software.
15
 *
15
 *
16
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22
 * DEALINGS IN THE SOFTWARE.
22
 * DEALINGS IN THE SOFTWARE.
23
 */
23
 */
24
 
24
 
-
 
25
/* if WITHSTDIO is enabled, then remap file operations to use the standard
-
 
26
 * stdio amenities */
-
 
27
#ifdef WITHSTDIO
-
 
28
 
-
 
29
#include <stdio.h>   /* FILE, fopen(), fseek(), etc */
-
 
30
typedef FILE* FHANDLE;
-
 
31
#define FOPEN(x) fopen(x, "rb")
-
 
32
#define FCLOSE(x) fclose(x)
-
 
33
#define FSEEK(f,b) fseek(f,b,SEEK_CUR)
-
 
34
#define FREAD(f,t,b) fread(t, 1, b, f)
-
 
35
 
-
 
36
#else
-
 
37
 
25
#include <i86.h>
38
#include <i86.h>
-
 
39
typedef unsigned short FHANDLE;
-
 
40
 
-
 
41
#endif
-
 
42
 
26
#include <stdlib.h>  /* NULL */
43
#include <stdlib.h>  /* NULL */
27
#include <string.h>  /* memcmp(), strcpy() */
44
#include <string.h>  /* memcmp(), strcpy() */
28
 
45
 
29
#include "svarlang.h"
46
#include "svarlang.h"
30
 
47
 
31
 
48
 
32
/* supplied through DEFLANG.C */
49
/* supplied through DEFLANG.C */
33
extern char svarlang_mem[];
50
extern char svarlang_mem[];
34
extern const unsigned short svarlang_memsz;
51
extern const unsigned short svarlang_memsz;
35
 
52
 
36
 
53
 
37
const char *svarlang_strid(unsigned short id) {
54
const char *svarlang_strid(unsigned short id) {
38
  const char *ptr = svarlang_mem;
55
  const char *ptr = svarlang_mem;
39
  /* find the string id in langblock memory */
56
  /* find the string id in langblock memory */
40
  for (;;) {
57
  for (;;) {
41
    if (((unsigned short *)ptr)[0] == id) return(ptr + 4);
58
    if (((unsigned short *)ptr)[0] == id) return(ptr + 4);
42
    if (((unsigned short *)ptr)[1] == 0) return(ptr + 2); /* end of strings - return an empty string */
59
    if (((unsigned short *)ptr)[1] == 0) return(ptr + 2); /* end of strings - return an empty string */
43
    ptr += ((unsigned short *)ptr)[1] + 4;
60
    ptr += ((unsigned short *)ptr)[1] + 4;
44
  }
61
  }
45
}
62
}
46
 
63
 
47
 
-
 
-
 
64
/* routines below are simplified (dos-based) versions of the libc FILE-related
-
 
65
 * functions. Using them avoids a dependency on FILE, hence makes the binary
-
 
66
 * smaller if the application does not need to pull fopen() and friends */
-
 
67
#ifndef WITHSTDIO
48
static unsigned short FOPEN(const char *s) {
68
static unsigned short FOPEN(const char *s) {
49
  unsigned short fname_seg = FP_SEG(s);
69
  unsigned short fname_seg = FP_SEG(s);
50
  unsigned short fname_off = FP_OFF(s);
70
  unsigned short fname_off = FP_OFF(s);
51
  unsigned short res = 0xffff;
71
  unsigned short res = 0; /* fd 0 is already used by stdout so it's a good error value */
52
  _asm {
72
  _asm {
53
    push dx
73
    push dx
54
    push ds
74
    push ds
55
 
75
 
56
    mov ax, fname_seg
76
    mov ax, fname_seg
57
    mov dx, fname_off
77
    mov dx, fname_off
58
    mov ds, ax
78
    mov ds, ax
59
    mov ax, 0x3d00  /* open file, read-only (fname at DS:DX) */
79
    mov ax, 0x3d00  /* open file, read-only (fname at DS:DX) */
60
    int 0x21
80
    int 0x21
61
    pop ds
81
    pop ds
62
    jc ERR
82
    jc ERR
63
    mov res, ax
83
    mov res, ax
64
 
84
 
65
    ERR:
85
    ERR:
66
    pop dx
86
    pop dx
67
  }
87
  }
68
 
88
 
69
  return(res);
89
  return(res);
70
}
90
}
71
 
91
 
72
 
92
 
73
static void FCLOSE(unsigned short handle) {
93
static void FCLOSE(unsigned short handle) {
74
  _asm {
94
  _asm {
75
    push bx
95
    push bx
76
 
96
 
77
    mov ah, 0x3e
97
    mov ah, 0x3e
78
    mov bx, handle
98
    mov bx, handle
79
    int 0x21
99
    int 0x21
80
 
100
 
81
    pop bx
101
    pop bx
82
  }
102
  }
83
}
103
}
84
 
104
 
85
 
105
 
86
static unsigned short FREAD(unsigned short handle, void *buff, unsigned short bytes) {
106
static unsigned short FREAD(unsigned short handle, void *buff, unsigned short bytes) {
87
  unsigned short buff_seg = FP_SEG(buff);
107
  unsigned short buff_seg = FP_SEG(buff);
88
  unsigned short buff_off = FP_OFF(buff);
108
  unsigned short buff_off = FP_OFF(buff);
89
  unsigned short res = 0;
109
  unsigned short res = 0;
90
 
110
 
91
  _asm {
111
  _asm {
92
    push bx
112
    push bx
93
    push cx
113
    push cx
94
    push dx
114
    push dx
95
 
115
 
96
    mov bx, handle
116
    mov bx, handle
97
    mov cx, bytes
117
    mov cx, bytes
98
    mov dx, buff_off
118
    mov dx, buff_off
99
    mov ax, buff_seg
119
    mov ax, buff_seg
100
    push ds
120
    push ds
101
    mov ds, ax
121
    mov ds, ax
102
    mov ah, 0x3f    /* read cx bytes from file handle bx to DS:DX */
122
    mov ah, 0x3f    /* read cx bytes from file handle bx to DS:DX */
103
    int 0x21
123
    int 0x21
104
    pop ds
124
    pop ds
105
    jc ERR
125
    jc ERR
106
 
126
 
107
    mov res, ax
127
    mov res, ax
108
    ERR:
128
    ERR:
109
 
129
 
110
    pop dx
130
    pop dx
111
    pop cx
131
    pop cx
112
    pop bx
132
    pop bx
113
  }
133
  }
114
 
134
 
115
  return(res);
135
  return(res);
116
}
136
}
117
 
137
 
118
 
138
 
119
static void FJUMP(unsigned short handle, unsigned short bytes) {
139
static void FSEEK(unsigned short handle, unsigned short bytes) {
120
  _asm {
140
  _asm {
121
    push bx
141
    push bx
122
    push cx
142
    push cx
123
    push dx
143
    push dx
124
 
144
 
125
    mov ax, 0x4201  /* move file pointer from cur pos + CX:DX */
145
    mov ax, 0x4201  /* move file pointer from cur pos + CX:DX */
126
    mov bx, handle
146
    mov bx, handle
127
    xor cx, cx
147
    xor cx, cx
128
    mov dx, bytes
148
    mov dx, bytes
129
    int 0x21
149
    int 0x21
130
 
150
 
131
    pop dx
151
    pop dx
132
    pop cx
152
    pop cx
133
    pop bx
153
    pop bx
134
  }
154
  }
135
}
155
}
136
 
156
#endif
137
 
157
 
138
int svarlang_load(const char *fname, const char *lang) {
158
int svarlang_load(const char *fname, const char *lang) {
139
  unsigned short langid;
159
  unsigned short langid;
140
  unsigned short fd;
-
 
141
  char hdr[4];
160
  char hdr[4];
142
  unsigned short buff16[2];
161
  unsigned short buff16[2];
-
 
162
  FHANDLE fd;
143
 
163
 
144
  langid = *((unsigned short *)lang);
164
  langid = *((unsigned short *)lang);
145
  langid &= 0xDFDF; /* make sure lang is upcase */
165
  langid &= 0xDFDF; /* make sure lang is upcase */
146
 
166
 
147
  fd = FOPEN(fname);
167
  fd = FOPEN(fname);
148
  if (fd == 0xffff) return(-1);
168
  if (!fd) return(-1);
149
 
169
 
150
  /* read hdr, should be "SvL\33" */
170
  /* read hdr, should be "SvL\33" */
151
  if ((FREAD(fd, hdr, 4) != 4) || (memcmp(hdr, "SvL\33", 4) != 0)) {
171
  if ((FREAD(fd, hdr, 4) != 4) || (memcmp(hdr, "SvL\33", 4) != 0)) {
152
    FCLOSE(fd);
172
    FCLOSE(fd);
153
    return(-3);
173
    return(-3);
154
  }
174
  }
155
 
175
 
156
  /* read next lang id in file */
176
  /* read next lang id in file */
157
  while (FREAD(fd, buff16, 4) == 4) {
177
  while (FREAD(fd, buff16, 4) == 4) {
158
 
178
 
159
    /* is it the lang I am looking for? */
179
    /* is it the lang I am looking for? */
160
    if (buff16[0] != langid) { /* skip to next lang */
180
    if (buff16[0] != langid) { /* skip to next lang */
161
      FJUMP(fd, buff16[1]);
181
      FSEEK(fd, buff16[1]);
162
      continue;
182
      continue;
163
    }
183
    }
164
 
184
 
165
    /* found - but do I have enough memory space? */
185
    /* found - but do I have enough memory space? */
166
    if (buff16[1] >= svarlang_memsz) {
186
    if (buff16[1] >= svarlang_memsz) {
167
      FCLOSE(fd);
187
      FCLOSE(fd);
168
      return(-4);
188
      return(-4);
169
    }
189
    }
170
 
190
 
171
    /* load strings */
191
    /* load strings */
172
    if (FREAD(fd, svarlang_mem, buff16[1]) != buff16[1]) break;
192
    if (FREAD(fd, svarlang_mem, buff16[1]) != buff16[1]) break;
173
    FCLOSE(fd);
193
    FCLOSE(fd);
174
    return(0);
194
    return(0);
175
  }
195
  }
176
 
196
 
177
  FCLOSE(fd);
197
  FCLOSE(fd);
178
  return(-5);
198
  return(-5);
179
}
199
}
180
 
200