/* | |
* File I/O, based on DOS int 21h calls | |
* This file is part of the DOSMid project | |
* http://dosmid.sourceforge.net | |
* | |
* Copyright (C) 2018 Mateusz Viste | |
*/ | |
#include <dos.h> | |
#include <fcntl.h> | |
#include <share.h> | |
#include "fio.h" /* include self for control */ | |
/* seek to offset position of file pointed at by fhandle. returns current file position on success, a negative error otherwise */ | |
signed long fio_seek(unsigned short fhandle, unsigned short origin, signed long offset) { | |
/* DOS 2+ - LSEEK - SET CURRENT FILE POSITION | |
AH = 42h | |
AL = origin of move | |
00h start of file | |
01h current file position | |
02h end of file | |
BX = file handle | |
CX:DX = (signed) offset from origin of new file position | |
Return on success: | |
CF clear | |
DX:AX = new file position in bytes from start of file | |
Return on error: | |
CF set | |
AX = error code */ | |
union REGS regs; | |
unsigned short *off = (unsigned short *)(&offset); | |
regs.h.ah = 0x42; | |
regs.h.al = origin; | |
regs.x.bx = fhandle; | |
regs.x.cx = off[1]; | |
regs.x.dx = off[0]; | |
int86(0x21, ®s, ®s); | |
if (regs.x.cflag != 0) return(0 - regs.x.ax); | |
return(((long)regs.x.dx << 16) | regs.x.ax); | |
} | |
/* open file fname and set fhandle with the associated file handle. returns 0 on success, non-zero otherwise */ | |
int fio_open(char far *fname, int mode, int *fhandle) { | |
/* DOS 2+ - OPEN - OPEN EXISTING FILE | |
AH = 3Dh | |
AL = access and sharing modes | |
DS:DX -> ASCIZ filename | |
CL = attribute mask of files to look for (server call only) | |
Return: | |
CF clear if successful | |
AX = file handle or error code | |
CF set on error */ | |
union REGS regs; | |
struct SREGS sregs; | |
regs.h.ah = 0x3d; | |
regs.h.al = mode; | |
sregs.ds = FP_SEG(fname); | |
regs.x.dx = FP_OFF(fname); | |
int86x(0x21, ®s, ®s, &sregs); | |
*fhandle = regs.x.ax; | |
if (regs.x.cflag != 0) return(-1); | |
return(0); | |
} | |
/* reads count bytes from file pointed at by fhandle, and writes the data into buff. returns the number of bytes actually read, or a negative number on error */ | |
int fio_read(int fhandle, void far *buff, int count) { | |
/* DOS 2+ - READ - READ FROM FILE OR DEVICE | |
* AH = 3Fh | |
* BX = file handle | |
* CX = number of bytes to read | |
* DS:DX -> buffer for data | |
* Return: | |
* CF clear if successful | |
* AX = number of bytes actually read (0 if at EOF before call) | |
* CF set on error | |
* AX = error code (05h,06h) (see #01680 at AH=59h/BX=0000h) */ | |
union REGS regs; | |
struct SREGS sregs; | |
regs.h.ah = 0x3f; | |
regs.x.bx = fhandle; | |
regs.x.cx = count; | |
sregs.ds = FP_SEG(buff); | |
regs.x.dx = FP_OFF(buff); | |
int86x(0x21, ®s, ®s, &sregs); | |
if (regs.x.cflag != 0) return(0 - regs.x.ax); | |
return(regs.x.ax); | |
} | |
/* close file handle. returns 0 on success, non-zero otherwise */ | |
int fio_close(int fhandle) { | |
/* DOS 2+ - CLOSE - CLOSE FILE | |
AH = 3Eh | |
BX = file handle | |
Return on success: | |
CF clear | |
AX destroyed | |
On error: | |
CF set | |
AX = error code */ | |
union REGS regs; | |
regs.h.ah = 0x3e; | |
regs.x.bx = fhandle; | |
int86(0x21, ®s, ®s); | |
if (regs.x.cflag != 0) return(0 - regs.x.ax); | |
return(0); | |
} |