Subversion Repositories shark

Rev

Rev 3 | Rev 1618 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 pj 1
/* Project:     OSLib
2
 * Description: The OS Construction Kit
3
 * Date:                1.6.2000
4
 * Idea by:             Luca Abeni & Gerardo Lamastra
5
 *
6
 * OSLib is an SO project aimed at developing a common, easy-to-use
7
 * low-level infrastructure for developing OS kernels and Embedded
8
 * Applications; it partially derives from the HARTIK project but it
9
 * currently is independently developed.
10
 *
11
 * OSLib is distributed under GPL License, and some of its code has
12
 * been derived from the Linux kernel source; also some important
13
 * ideas come from studying the DJGPP go32 extender.
14
 *
15
 * We acknowledge the Linux Community, Free Software Foundation,
16
 * D.J. Delorie and all the other developers who believe in the
17
 * freedom of software and ideas.
18
 *
19
 * For legalese, check out the included GPL license.
20
 */
21
 
22
/* DOS Interface toward disk            */
23
 
24
#include <ll/i386/mem.h>
25
#include <ll/i386/error.h>
26
#include <ll/string.h>
27
#include <ll/i386/x-dos.h>
28
#include <ll/i386/x-dosmem.h>
29
 
40 pj 30
FILE(X-Dos-File);
2 pj 31
 
32
/* Basic DOS I/O Flag */
33
 
34
/*#define __DEBUG__*/
35
 
36
#define DOS_READ        0
37
#define DOS_WRITE       1
38
#define DOS_RW          2
39
 
40 pj 40
#define DOS_BUFSIZE     1024    /* I/O auxiliary buffer         */
41
#define DOS_MAXDESCR    16      /* Maximum number of DOS file   */
2 pj 42
 
43
static DOS_FILE DOS_descr[DOS_MAXDESCR];
44
/* I Hope this array is initialized with 0... */
45
static BYTE busy[DOS_MAXDESCR];
46
 
47
/* The Last DOS Error occurred! */
48
static unsigned _DOS_error = 0;
49
 
50
 
51
int DOS_init(void)
52
{
40 pj 53
  /* Init the DOS memory allocator */
54
  DOS_mem_init();
2 pj 55
 
40 pj 56
  /* TODO: Add a check if we are run through X */
57
  return 1;
2 pj 58
}
59
 
60
unsigned DOS_error(void)
61
{
62
    unsigned v = _DOS_error;
63
    _DOS_error = 0;
40 pj 64
    return(v);
2 pj 65
}
66
 
40 pj 67
DOS_FILE *DOS_fopen(char *name,char *mode)
2 pj 68
{
40 pj 69
    X_REGS16 ir,or;
2 pj 70
    X_SREGS16 sr;
71
    DOS_FILE *f;
72
    register int i;
73
 
40 pj 74
    #ifdef __DEBUG__
75
        char xname[80];
76
    #endif
2 pj 77
 
78
    for (i = 0; busy[i] && i < DOS_MAXDESCR; i++);
79
    /* Return NULL if no descriptor is available... */
40 pj 80
    if (i == DOS_MAXDESCR) return(NULL);
2 pj 81
    /* Otherwise, lock the descriptor & remember the index */
40 pj 82
    f = &DOS_descr[i]; busy[i] = 1; f->index = i;
2 pj 83
    /* Allocate a DOS buffer for the file name */
84
    f->n1 = DOS_alloc(80);
40 pj 85
    strcpy(f->n2,name);
2 pj 86
    if (mode[0] == 'r') {
87
        /* DOS Call: Intr 0x21
40 pj 88
                AH = 0x3D  - Open existing file
89
                AL = 0,1,2 - Read,Write, R/W
90
        */
2 pj 91
        f->mode = DOS_READ;
92
        ir.h.ah = 0x3D;
93
        ir.h.al = f->mode;
40 pj 94
    }
95
    else if (mode[0] == 'w') {
2 pj 96
        /* DOS Call: Intr 0x21
40 pj 97
                AH = 0x3C  - Create a file
98
                AL = File attribute [0x20 = Standard,r/w,archive]
99
        */
2 pj 100
        f->mode = DOS_WRITE;
101
        ir.h.ah = 0x3C;
102
        ir.x.cx = 0x20;
103
    }
104
    f->offset = 0;
105
    /* Copy th \0 also! */
106
    memcpy(f->n1, name, strlen(name) + 1);
40 pj 107
    #ifdef __DEBUG__
108
        memcpy(xname, f->n1, strlen(name) + 1);
109
        message("Name is : %s -- Mode : %d\n",xname,f->mode);
110
    #endif
2 pj 111
 
112
    /* Ask DOS to open File */
113
    ir.x.dx = DOS_OFF(f->n1);
114
    sr.ds = DOS_SEG(f->n1);
40 pj 115
    X_callBIOS(0x21,&ir,&or,&sr);
2 pj 116
    f->handle = (!(or.x.cflag) ? or.x.ax : -1);
117
 
118
    if (f->handle == -1) {
119
        /* DOS request failed! Release the used resources */
40 pj 120
        DOS_free(f->n1,80);
2 pj 121
        busy[i] = 0;
122
        _DOS_error = or.x.ax;
40 pj 123
        return(NULL);
2 pj 124
    }
40 pj 125
 
2 pj 126
    /* Allocate the DOS buffer for temporary I/O */
127
    f->buf = DOS_alloc(DOS_BUFSIZE);
40 pj 128
    return(f);
2 pj 129
}
130
 
40 pj 131
void DOS_fclose(DOS_FILE *f)
2 pj 132
{
40 pj 133
    X_REGS16 ir,or;
2 pj 134
    X_SREGS16 sr;
135
 
40 pj 136
    if (f == NULL || busy[f->index] == 0) return;
2 pj 137
    /* DOS Call: Intr 0x21
40 pj 138
            AH = 0x3E  - Close a file
139
            BX = File handle
140
    */
2 pj 141
    ir.h.ah = 0x3E;
142
    ir.x.bx = f->handle;
40 pj 143
    X_callBIOS(0x21,&ir,&or,&sr);
144
    DOS_free(f->buf,DOS_BUFSIZE);
145
    DOS_free(f->n1,80);
2 pj 146
    busy[f->index] = 0;
147
}
148
 
40 pj 149
DWORD DOS_fread(void *abuf,DWORD size,DWORD num,DOS_FILE *f)
2 pj 150
{
40 pj 151
    X_REGS16 ir,or;
2 pj 152
    X_SREGS16 sr;
40 pj 153
    DWORD count = size*num,now = 0,chunk;
2 pj 154
    BYTE done = 0;
40 pj 155
    BYTE *buf = (BYTE *)(abuf);
156
 
2 pj 157
    while (done == 0) {
158
        /* Fragment the read operation ... */
40 pj 159
        if (count > DOS_BUFSIZE) chunk = DOS_BUFSIZE;
160
        else chunk = count;
2 pj 161
        /* DOS Call: Intr 0x21
40 pj 162
                AH = 0x3F  - Read data using a file handle
163
                BX = File handle
164
                CX = Buffer size
165
                DS:DX = Segment:Offset of the Buffer
166
        */
2 pj 167
        ir.h.ah = 0x3F;
168
        ir.x.bx = f->handle;
169
        ir.x.cx = chunk;
170
        ir.x.dx = DOS_OFF(f->buf);
171
        sr.ds = DOS_SEG(f->buf);
40 pj 172
        X_callBIOS(0x21,&ir,&or,&sr);
2 pj 173
        /* If it was OK ... */
174
        if (!(or.x.cflag)) {
175
            /* Copy data into application buffer */
176
            memcpy(buf, f->buf, or.x.ax);
177
            buf += or.x.ax;
178
            now += or.x.ax;
179
            f->offset += or.x.ax;
180
            count -= or.x.ax;
181
            /*
40 pj 182
                Finish if we have read all the data or
183
                if we have read less data than how expected
184
            */ 
185
            if (now == size*num || or.x.ax != chunk) done = 1;     
2 pj 186
        } else {
187
            done = -1;
188
            _DOS_error = or.x.ax;
189
        }
190
    }
40 pj 191
    return(now);
2 pj 192
}
193
 
40 pj 194
DWORD DOS_fwrite(void *abuf,DWORD size,DWORD num,DOS_FILE *f)
2 pj 195
{
40 pj 196
    X_REGS16 ir,or;
2 pj 197
    X_SREGS16 sr;
40 pj 198
    DWORD count = size*num,now = 0,chunk;
2 pj 199
    BYTE done = 0;
40 pj 200
    BYTE *buf = (BYTE *)(abuf);
201
 
2 pj 202
    while (done == 0) {
203
        /* Fragment the write operation ... */
40 pj 204
        if (count > DOS_BUFSIZE) chunk = DOS_BUFSIZE;
205
        else chunk = count;
2 pj 206
        /* Copy data from application buffer */
207
        memcpy(f->buf, buf, chunk);
208
        /* DOS Call: Intr 0x21
40 pj 209
                AH = 0x40 - Write data using a file handle
210
                BX = File handle
211
                CX = Buffer size
212
                DS:DX = Segment:Offset of the Buffer
213
        */
2 pj 214
        ir.h.ah = 0x40;
215
        ir.x.bx = f->handle;
216
        ir.x.cx = chunk;
217
        ir.x.dx = DOS_OFF(f->buf);
218
        sr.ds = DOS_SEG(f->buf);
40 pj 219
        X_callBIOS(0x21,&ir,&or,&sr);
2 pj 220
        /* If it was OK ... */
221
        if (!(or.x.cflag)) {
222
            f->offset += or.x.ax;
223
            count -= or.x.ax;
224
            buf += or.x.ax;
225
            now += or.x.ax;
40 pj 226
            if (now == size*num || or.x.ax != chunk) done = 1;     
2 pj 227
        } else {
228
            done = -1;
229
            _DOS_error = or.x.ax;
230
        }
231
    }
40 pj 232
    return(now);
2 pj 233
}
40 pj 234