home *** CD-ROM | disk | FTP | other *** search
- #include <alloc.h>
- #include <dos.h>
- #include <stdio.h>
- #include <bios.h>
- #include <fcntl.h>
-
- #define D_READ 2
- #define D_WRITE 3
-
- #define CACHE_SECTORS 18
-
- typedef struct {
- int fd; /* or drive, if cm set */
- int cm, hm, sm;
- long file_ptr;
- void *cache;
- long cache_fptr;
- long cache_fptre;
- int volume_in_drive;
- } oread;
-
- void *oread_open(char *fn)
- {
- oread *or;
- if ((strlen(fn) == 2) && (fn[1] == ':'))
- {
- struct REGPACK r;
- char buf[512];
- int status;
-
- switch (fn[0])
- {
- case 'a':
- case 'A':
- or = (oread *)malloc(sizeof(oread));
- or->fd = 0;
- break;
- case 'b':
- case 'B':
- or = (oread *)malloc(sizeof(oread));
- or->fd = 1;
- break;
- default:
- printf("Invalid drive specified: %s\n", fn);
- return 0;
- }
- while ((status = biosdisk(D_READ, or->fd, 0, 0, 1, 1, buf)) == 6)
- /* wait for valid read */ ;
- if (status)
- return 0;
-
- r.r_ax = 0x0800;
- r.r_dx = or->fd;
- intr(0x13, &r);
- or->cm = (((r.r_cx & 0x00c0) << 2) | ((r.r_cx >> 8) & 0xff))+1;
- or->hm = (r.r_dx >> 8)+1;
- or->sm = r.r_cx & 0x3f;
- or->file_ptr = 0L;
- or->cache = (void *)malloc(512*CACHE_SECTORS);
- or->cache_fptr = -512*CACHE_SECTORS;
- or->cache_fptre = -512*CACHE_SECTORS;
- or->volume_in_drive = 0;
- return or;
- }
- else
- {
- int fd;
- fd = _open(fn, O_RDONLY);
- if (fd < 0)
- return 0;
- or = (oread *)malloc(sizeof(oread));
- or->fd = fd;
- or->cm = 0;
- return or;
- }
- }
-
- void oread_read(void *rv, void *buffer)
- {
- oread *r = (oread *)rv;
- if (r->cm)
- {
- int c, h, s, v, sc;
- if ((r->file_ptr >= r->cache_fptr) && (r->file_ptr < r->cache_fptre))
- {
- memcpy(buffer, (char *)(r->cache) + r->file_ptr - r->cache_fptr, 512);
- r->file_ptr += 512;
- return;
- }
- s = (unsigned long)(r->file_ptr) / 512;
- h = s / r->sm;
- c = h / r->hm;
- v = c / r->cm;
- s = s % r->sm;
- h = h % r->hm;
- c = c % r->cm;
- if (v != r->volume_in_drive)
- {
- printf("Please insert volume %03d . . .", v);
- fflush(stdout);
- if (getch() == 3)
- {
- printf("^C\n");
- exit(3);
- }
- printf("\n");
- r->volume_in_drive = v;
- r->cache_fptr = -512*CACHE_SECTORS;
- }
- sc = r->sm - s;
- if (sc > CACHE_SECTORS)
- sc = CACHE_SECTORS;
- printf("v=%02d c=%02d h=%02d s=%02d n=%02d\r", v, c, h, s, sc);
- fflush(stdout);
- if (biosdisk(D_READ, r->fd, h, c, s+1, sc, r->cache))
- biosdisk(D_READ, r->fd, h, c, s+1, sc, r->cache);
- memcpy(buffer, r->cache, 512);
- r->cache_fptr = r->file_ptr;
- r->cache_fptre = r->cache_fptr + 512*sc;
- r->file_ptr += 512;
- }
- else
- {
- if (_read(r->fd, buffer, 512) != 512)
- {
- printf("Unexpected end-of-file\n");
- exit(1);
- }
- }
- }
-
- void oread_skip(void *rv, long skip_bytes)
- {
- oread *r = (oread *)rv;
- if (r->cm)
- {
- r->file_ptr += skip_bytes;
- }
- else
- {
- lseek(r->fd, skip_bytes, 1);
- }
- }
-
- void oread_close(void *rv)
- {
- oread *r = (oread *)rv;
- if (r->cm == 0)
- _close(r->fd);
- else
- free(r->cache);
- free(r);
- }
-