diff --git a/files/drive.c b/files/drive.c index d1c190609a8..2c69d0b9ee7 100644 --- a/files/drive.c +++ b/files/drive.c @@ -15,6 +15,7 @@ #include #include #include +#include #ifdef HAVE_SYS_PARAM_H # include @@ -577,6 +578,61 @@ int DRIVE_OpenDevice( int drive, int flags ) } +/*********************************************************************** + * DRIVE_RawRead + * + * Read raw sectors from a device + */ +int DRIVE_RawRead(BYTE drive, DWORD begin, DWORD nr_sect, BYTE *dataptr, BOOL32 fake_success) +{ + int fd; + + if ((fd = DRIVE_OpenDevice( drive, O_RDONLY )) != -1) + { + lseek( fd, begin * 512, SEEK_SET ); + /* FIXME: check errors */ + read( fd, dataptr, nr_sect * 512 ); + close( fd ); + } + else + { + memset(dataptr, 0, nr_sect * 512); + if (fake_success) + { + if (begin == 0 && nr_sect > 1) *(dataptr + 512) = 0xf8; + if (begin == 1) *dataptr = 0xf8; + } + else + return 0; + } + return 1; +} + + +/*********************************************************************** + * DRIVE_RawWrite + * + * Write raw sectors to a device + */ +int DRIVE_RawWrite(BYTE drive, DWORD begin, DWORD nr_sect, BYTE *dataptr, BOOL32 fake_success) +{ + int fd; + + if ((fd = DRIVE_OpenDevice( drive, O_RDONLY )) != -1) + { + lseek( fd, begin * 512, SEEK_SET ); + /* FIXME: check errors */ + write( fd, dataptr, nr_sect * 512 ); + close( fd ); + } + else + if (!(fake_success)) + return 0; + + return 1; +} + + /*********************************************************************** * DRIVE_GetFreeSpace */ diff --git a/include/drive.h b/include/drive.h index 5849e3a6716..f4aea646b90 100644 --- a/include/drive.h +++ b/include/drive.h @@ -45,5 +45,7 @@ extern int DRIVE_Disable( int drive ); extern int DRIVE_Enable( int drive ); extern int DRIVE_SetLogicalMapping ( int existing_drive, int new_drive ); extern int DRIVE_OpenDevice( int drive, int flags ); +extern int DRIVE_RawRead(BYTE drive, DWORD begin, DWORD length, BYTE *dataptr, BOOL32 fake_success ); +extern int DRIVE_RawWrite(BYTE drive, DWORD begin, DWORD length, BYTE *dataptr, BOOL32 fake_success ); #endif /* __WINE_DRIVE_H */ diff --git a/msdos/int21.c b/msdos/int21.c index 45a0c062e99..6f7ca492f56 100644 --- a/msdos/int21.c +++ b/msdos/int21.c @@ -291,6 +291,30 @@ static BOOL32 ioctlGenericBlkDevReq( CONTEXT *context ) RESET_CFLAG(context); break; + case 0x41: /* write logical device track */ + case 0x61: /* read logical device track */ + { + BYTE drive = BL_reg(context) ? + BL_reg(context) : DRIVE_GetCurrentDrive(); + WORD head = *(WORD *)dataptr+1; + WORD cyl = *(WORD *)dataptr+3; + WORD sect = *(WORD *)dataptr+5; + WORD nrsect = *(WORD *)dataptr+7; + BYTE *data = (BYTE **)dataptr+9; + int (*raw_func)(BYTE, DWORD, DWORD, BYTE *, BOOL32); + + raw_func = (CL_reg(context) == 0x41) ? + DRIVE_RawWrite : DRIVE_RawRead; + + if (raw_func(drive, head*cyl*sect, nrsect, data, FALSE)) + RESET_CFLAG(context); + else + { + AX_reg(context) = 0x1e; /* read fault */ + SET_CFLAG(context); + } + } + break; case 0x66:/* get disk serial number */ { char label[12],fsname[9],path[4]; @@ -327,16 +351,16 @@ static BOOL32 ioctlGenericBlkDevReq( CONTEXT *context ) static void INT21_ParseFileNameIntoFCB( CONTEXT *context ) { char *filename = - CTX_SEG_OFF_TO_LIN(context, DS_reg(context), SI_reg(context) ); + CTX_SEG_OFF_TO_LIN(context, DS_reg(context), ESI_reg(context) ); char *fcb = - CTX_SEG_OFF_TO_LIN(context, ES_reg(context), DI_reg(context) ); + CTX_SEG_OFF_TO_LIN(context, ES_reg(context), EDI_reg(context) ); char *buffer, *s, *d; AL_reg(context) = 0xff; /* failed */ TRACE(int21, "filename: '%s'\n", filename); - buffer = HeapAlloc( GetProcessHeap(), 0, strlen(filename) ); + buffer = HeapAlloc( GetProcessHeap(), 0, strlen(filename) + 1); s = filename; d = buffer; @@ -1082,6 +1106,9 @@ void WINAPI DOS3Call( CONTEXT *context ) break; case 0x01: /* READ CHARACTER FROM STANDARD INPUT, WITH ECHO */ + _lread16(1, (BYTE *)&context->Eax, 1); + break; + case 0x03: /* READ CHARACTER FROM STDAUX */ case 0x04: /* WRITE CHARACTER TO STDAUX */ case 0x05: /* WRITE CHARACTER TO PRINTER */ diff --git a/msdos/int25.c b/msdos/int25.c index b2635e7569a..19d4598b80a 100644 --- a/msdos/int25.c +++ b/msdos/int25.c @@ -12,6 +12,7 @@ #include "drive.h" #include "debug.h" + /********************************************************************** * INT_Int25Handler * @@ -21,7 +22,6 @@ void WINAPI INT_Int25Handler( CONTEXT *context ) { BYTE *dataptr = CTX_SEG_OFF_TO_LIN( context, DS_reg(context), EBX_reg(context) ); DWORD begin, length; - int fd; if (!DRIVE_IsValid(AL_reg(context))) { @@ -43,22 +43,10 @@ void WINAPI INT_Int25Handler( CONTEXT *context ) length = CX_reg(context); } TRACE(int, "int25: abs diskread, drive %d, sector %ld, " - "count %ld, buffer %d\n", - AL_reg(context), begin, length, (int) dataptr); + "count %ld, buffer %p\n", + AL_reg(context), begin, length, dataptr); - if ((fd = DRIVE_OpenDevice( AL_reg(context), O_RDONLY )) != -1) - { - lseek( fd, begin * 512, SEEK_SET ); - /* FIXME: check errors */ - read( fd, dataptr, length * 512 ); - close( fd ); - } - else - { - memset(dataptr, 0, length * 512); - if (begin == 0 && length > 1) *(dataptr + 512) = 0xf8; - if (begin == 1) *dataptr = 0xf8; - } + DRIVE_RawRead(AL_reg(context), begin, length, dataptr, TRUE); RESET_CFLAG(context); } diff --git a/msdos/int26.c b/msdos/int26.c index ba3e11b8418..5ed49957b27 100644 --- a/msdos/int26.c +++ b/msdos/int26.c @@ -20,7 +20,6 @@ void WINAPI INT_Int26Handler( CONTEXT *context ) { BYTE *dataptr = CTX_SEG_OFF_TO_LIN( context, DS_reg(context), EBX_reg(context) ); DWORD begin, length; - int fd; if (!DRIVE_IsValid(AL_reg(context))) { @@ -43,16 +42,9 @@ void WINAPI INT_Int26Handler( CONTEXT *context ) } TRACE(int,"int26: abs diskwrite, drive %d, sector %ld, " - "count %ld, buffer %d\n", - AL_reg(context), begin, length, (int) dataptr ); - - if ((fd = DRIVE_OpenDevice( AL_reg(context), O_WRONLY )) != -1) - { - lseek( fd, begin * 512, SEEK_SET ); - /* FIXME: check errors */ - write( fd, dataptr, length * 512 ); - close( fd ); - } + "count %ld, buffer %p\n", + AL_reg(context), begin, length, dataptr ); + DRIVE_RawWrite(AL_reg(context), begin, length, dataptr, TRUE); RESET_CFLAG(context); }