Subversion Repositories SvarDOS

Rev

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

Rev 388 Rev 392
1
/*
1
/*
2
 * a variety of helper functions
2
 * a variety of helper functions
3
 * Copyright (C) 2021 Mateusz Viste
3
 * Copyright (C) 2021 Mateusz Viste
4
 */
4
 */
5
 
5
 
6
#include "helpers.h"
6
#include "helpers.h"
7
 
7
 
8
/* case-insensitive comparison of strings, returns non-zero on equality */
8
/* case-insensitive comparison of strings, returns non-zero on equality */
9
int imatch(const char *s1, const char *s2) {
9
int imatch(const char *s1, const char *s2) {
10
  for (;;) {
10
  for (;;) {
11
    char c1, c2;
11
    char c1, c2;
12
    c1 = *s1;
12
    c1 = *s1;
13
    c2 = *s2;
13
    c2 = *s2;
14
    if ((c1 >= 'a') && (c1 <= 'z')) c1 -= ('a' - 'A');
14
    if ((c1 >= 'a') && (c1 <= 'z')) c1 -= ('a' - 'A');
15
    if ((c2 >= 'a') && (c2 <= 'z')) c2 -= ('a' - 'A');
15
    if ((c2 >= 'a') && (c2 <= 'z')) c2 -= ('a' - 'A');
16
    /* */
16
    /* */
17
    if (c1 != c2) return(0);
17
    if (c1 != c2) return(0);
18
    if (c1 == 0) return(1);
18
    if (c1 == 0) return(1);
19
    s1++;
19
    s1++;
20
    s2++;
20
    s2++;
21
  }
21
  }
22
}
22
}
23
 
23
 
24
 
24
 
25
/* returns zero if s1 starts with s2 */
25
/* returns zero if s1 starts with s2 */
26
int strstartswith(const char *s1, const char *s2) {
26
int strstartswith(const char *s1, const char *s2) {
27
  while (*s2 != 0) {
27
  while (*s2 != 0) {
28
    if (*s1 != *s2) return(-1);
28
    if (*s1 != *s2) return(-1);
29
    s1++;
29
    s1++;
30
    s2++;
30
    s2++;
31
  }
31
  }
32
  return(0);
32
  return(0);
33
}
33
}
34
 
34
 
35
 
35
 
36
/* outputs a NULL-terminated string to stdout */
36
/* outputs a NULL-terminated string to stdout */
37
void output_internal(const char *s, unsigned short nl) {
37
void output_internal(const char *s, unsigned short nl) {
38
  _asm {
38
  _asm {
39
    mov ah, 0x02 /* AH=9 - write character in DL to stdout */
39
    mov ah, 0x02 /* AH=9 - write character in DL to stdout */
40
    mov si, s
40
    mov si, s
41
    cld          /* clear DF so lodsb increments SI */
41
    cld          /* clear DF so lodsb increments SI */
42
    NEXTBYTE:
42
    NEXTBYTE:
43
    lodsb /* load byte from DS:SI into AL, SI++ */
43
    lodsb /* load byte from DS:SI into AL, SI++ */
44
    mov dl, al
44
    mov dl, al
45
    or al, 0  /* is al == 0? */
45
    or al, 0  /* is al == 0? */
46
    jz DONE
46
    jz DONE
47
    int 0x21
47
    int 0x21
48
    jmp NEXTBYTE
48
    jmp NEXTBYTE
49
    DONE:
49
    DONE:
50
    or nl, 0
50
    or nl, 0
51
    jz FINITO
51
    jz FINITO
52
    /* print out a CR/LF trailer if nl set */
52
    /* print out a CR/LF trailer if nl set */
53
    mov dl, 0x0D /* CR */
53
    mov dl, 0x0D /* CR */
54
    int 0x21
54
    int 0x21
55
    mov dl, 0x0A /* LF */
55
    mov dl, 0x0A /* LF */
56
    int 0x21
56
    int 0x21
57
    FINITO:
57
    FINITO:
58
  }
58
  }
59
}
59
}
60
 
60
 
61
 
61
 
62
/* find first matching files using a FindFirst DOS call
62
/* find first matching files using a FindFirst DOS call
63
 * returns 0 on success or a DOS err code on failure */
63
 * returns 0 on success or a DOS err code on failure */
64
unsigned short findfirst(struct DTA *dta, const char *pattern, unsigned short attr) {
64
unsigned short findfirst(struct DTA *dta, const char *pattern, unsigned short attr) {
65
  unsigned short res = 0;
65
  unsigned short res = 0;
66
  _asm {
66
  _asm {
67
    /* set DTA location */
67
    /* set DTA location */
68
    mov ah, 0x1a
68
    mov ah, 0x1a
69
    mov dx, dta
69
    mov dx, dta
70
    int 0x21
70
    int 0x21
71
    /* */
71
    /* */
72
    mov ah, 0x4e    /* FindFirst */
72
    mov ah, 0x4e    /* FindFirst */
73
    mov dx, pattern
73
    mov dx, pattern
74
    mov cx, attr
74
    mov cx, attr
75
    int 0x21        /* CF set on error + err code in AX, DTA filled with FileInfoRec on success */
75
    int 0x21        /* CF set on error + err code in AX, DTA filled with FileInfoRec on success */
76
    jnc DONE
76
    jnc DONE
77
    mov [res], ax
77
    mov [res], ax
78
    DONE:
78
    DONE:
79
  }
79
  }
80
  return(res);
80
  return(res);
81
}
81
}
82
 
82
 
83
 
83
 
84
/* find next matching, ie. continues an action intiated by findfirst() */
84
/* find next matching, ie. continues an action intiated by findfirst() */
85
unsigned short findnext(struct DTA *dta) {
85
unsigned short findnext(struct DTA *dta) {
86
  unsigned short res = 0;
86
  unsigned short res = 0;
87
  _asm {
87
  _asm {
88
    mov ah, 0x4f    /* FindNext */
88
    mov ah, 0x4f    /* FindNext */
89
    mov dx, dta
89
    mov dx, dta
90
    int 0x21        /* CF set on error + err code in AX, DTA filled with FileInfoRec on success */
90
    int 0x21        /* CF set on error + err code in AX, DTA filled with FileInfoRec on success */
91
    jnc DONE
91
    jnc DONE
92
    mov [res], ax
92
    mov [res], ax
93
    DONE:
93
    DONE:
94
  }
94
  }
95
  return(res);
95
  return(res);
96
}
96
}
-
 
97
 
-
 
98
 
-
 
99
/* print s string and wait for a single key press from stdin. accepts only
-
 
100
 * key presses defined in the c ASCIIZ string. returns offset of pressed key
-
 
101
 * in string. keys in c MUST BE UPPERCASE! */
-
 
102
unsigned short askchoice(const char *s, const char *c) {
-
 
103
  unsigned short res;
-
 
104
  char key = 0;
-
 
105
 
-
 
106
  AGAIN:
-
 
107
  output(s);
-
 
108
  output(" ");
-
 
109
 
-
 
110
  _asm {
-
 
111
    push ax
-
 
112
    push dx
-
 
113
 
-
 
114
    mov ax, 0x0c01 /* clear input buffer and execute getchar (INT 21h,AH=1) */
-
 
115
    int 0x21
-
 
116
    /* if AL == 0 then this is an extended character */
-
 
117
    test al, al
-
 
118
    jnz GOTCHAR
-
 
119
    mov ah, 0x08   /* read again to flush extended char from input buffer */
-
 
120
    int 0x21
-
 
121
    xor al, al     /* all extended chars are ignored */
-
 
122
    GOTCHAR:       /* received key is in AL now */
-
 
123
    mov [key], al  /* save key */
-
 
124
 
-
 
125
    /* print a cr/lf */
-
 
126
    mov ah, 0x02
-
 
127
    mov dl, 0x0D
-
 
128
    int 0x21
-
 
129
    mov dl, 0x0A
-
 
130
    int 0x21
-
 
131
 
-
 
132
    pop dx
-
 
133
    pop ax
-
 
134
  }
-
 
135
 
-
 
136
  /* ucase() result */
-
 
137
  if ((key >= 'a') && (key <= 'z')) key -= ('a' - 'A');
-
 
138
 
-
 
139
  /* is there a match? */
-
 
140
  for (res = 0; c[res] != 0; res++) if (c[res] == key) return(res);
-
 
141
 
-
 
142
  goto AGAIN;
-
 
143
}
-
 
144
 
-
 
145
 
-
 
146
/* converts a path to its canonic representation */
-
 
147
void file_truename(const char *src, char *dst) {
-
 
148
  _asm {
-
 
149
    mov ah, 0x60  /* query truename, DS:SI=src, ES:DI=dst */
-
 
150
    push ds
-
 
151
    pop es
-
 
152
    mov si, src
-
 
153
    mov di, dst
-
 
154
    int 0x21
-
 
155
  }
-
 
156
}
-
 
157
 
-
 
158
 
-
 
159
/* returns DOS attributes of file, or -1 on error */
-
 
160
int file_getattr(const char *fname) {
-
 
161
  int res = -1;
-
 
162
  _asm {
-
 
163
    mov ax, 0x4300  /* query file attributes, fname at DS:DX */
-
 
164
    mov dx, fname
-
 
165
    int 0x21        /* CX=attributes if CF=0, otherwise AX=errno */
-
 
166
    jc DONE
-
 
167
    mov [res], cx
-
 
168
    DONE:
-
 
169
  }
-
 
170
  return(res);
-
 
171
}
97
 
172