| /* | |
| * DOS interrupt 25h handler | |
| */ | |
| #include <stdlib.h> | |
| #include <string.h> | |
| #include <fcntl.h> | |
| #include <unistd.h> | |
| #include "msdos.h" | |
| #include "ldt.h" | |
| #include "miscemu.h" | |
| #include "drive.h" | |
| #include "debug.h" | |
| /********************************************************************** | |
| * INT_Int25Handler | |
| * | |
| * Handler for int 25h (absolute disk read). | |
| */ | |
| 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))) | |
| { | |
| SET_CFLAG(context); | |
| AX_reg(context) = 0x0101; /* unknown unit */ | |
| return; | |
| } | |
| if (CX_reg(context) == 0xffff) | |
| { | |
| begin = *(DWORD *)dataptr; | |
| length = *(WORD *)(dataptr + 4); | |
| dataptr = (BYTE *)CTX_SEG_OFF_TO_LIN( context, | |
| *(WORD *)(dataptr + 8), *(DWORD *)(dataptr + 6) ); | |
| } | |
| else | |
| { | |
| begin = DX_reg(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); | |
| 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; | |
| } | |
| RESET_CFLAG(context); | |
| } | |