Main Page | Data Structures | File List | Data Fields | Globals

int13ext.c

Go to the documentation of this file.
00001 00010 #include <dpmi.h> 00011 #include <sys/farptr.h> 00012 #include <sys/movedata.h> 00013 00014 #include "int13ext.h" 00015 00016 00017 00018 00019 // returns -1 if installed, 0 otherwise 00020 int int13ext_check() 00021 { 00022 __dpmi_regs r; 00023 r.x.ax = 0x4100; 00024 r.x.bx = 0x55AA; 00025 r.h.dl = 0x80; 00026 __dpmi_int (0x13, &r); 00027 00028 if (r.x.flags & 1) return 0; 00029 if (r.x.bx != 0xAA55) return 0; 00030 return -1; 00031 } 00032 00033 00034 00035 00036 00037 00038 00039 00040 00041 00042 // returns 0 if all goes ok, >0 int13 error, <0 DJGPP error 00043 int int13ext_getdrvparams(int drv, struct driveparams* DParam) 00044 { 00045 const int DP_size = sizeof(struct driveparams); 00046 DParam->crsize = DP_size; 00047 int selector, segress; 00048 __dpmi_regs r; 00049 00050 segress = __dpmi_allocate_dos_memory((DP_size + 15) >> 4, &selector); 00051 if (segress == -1) return NO_CTLDOS_MEMORY; 00052 r.x.ax = 0x4800; 00053 r.h.dl = (unsigned short int) drv; 00054 r.x.ds = segress; 00055 r.x.si = 0; 00056 _farpokew(selector, 0, 0x1A); // init first field with the size of driveparams struct 00057 __dpmi_int (0x13, &r); 00058 00059 dosmemget(segress << 4, DP_size, DParam); 00060 __dpmi_free_dos_memory(selector); 00061 00062 if (r.x.flags & 1) return r.h.ah; 00063 00064 return 0; 00065 } 00066 00067 00068 00069 00070 00071 00072 00073 00074 // returns 0 if all goes ok, >0 int13 error, <0 DJGPP error 00075 int int13ext_read(int drv, struct driveparams *DParam, U64B block, U64B nblocks, void *buffer) 00076 { 00077 struct diskaddrpacket DAP = {sizeof(struct diskaddrpacket), 0}; 00078 int selDAP, segDAP, selBuff, segBuff, segBound; 00079 U64B transfd; 00080 U32B rdbuffsize = // 0x8000 is default buffer size (32k) 00081 (nblocks * DParam->bytes_per_sect < 0x8000)? nblocks*DParam->bytes_per_sect :0x8000; 00082 U32B blocks_per_buff = rdbuffsize/DParam->bytes_per_sect; 00083 00084 segDAP = __dpmi_allocate_dos_memory((DAP.packetsize + 15) >> 4, &selDAP); 00085 if (segDAP == -1) return NO_CTLDOS_MEMORY; 00086 // we need to allocate memory more by 32k in order to find 64k boundary 00087 // while reading with int13 in DMA mode, that boundary can't be crossed 00088 // __dpmi_int returns 9h code in ah : 00089 // data boundary error (attempted DMA across 64K boundary or >80h sectors) 00090 segBuff = __dpmi_allocate_dos_memory(((rdbuffsize + 15) >> 4) + 0x800, &selBuff); 00091 if (segBuff == -1) { 00092 __dpmi_free_dos_memory(selDAP); 00093 return NO_BUFDOS_MEMORY; 00094 } 00095 // getting 64k boundary 00096 segBound = segBuff + 0x800 - (segBuff % 0x800); 00097 00098 __dpmi_regs r; 00099 00100 U64B tailblock = (nblocks/blocks_per_buff) * blocks_per_buff + block; 00101 for (transfd = block; transfd < block+nblocks; transfd += blocks_per_buff) { 00102 r.h.ah = 0x42; 00103 r.h.dl = (unsigned short int) drv; 00104 r.x.ds = segDAP; 00105 r.x.si = 0; 00106 00107 DAP.packetsize = sizeof(struct diskaddrpacket); 00108 if (transfd == tailblock) blocks_per_buff = nblocks + block - transfd; 00109 DAP.nblocks = blocks_per_buff; 00110 // DAP.buffer_segment = segBuff; 00111 DAP.buffer_segment = segBound; 00112 DAP.buffer_offset = 0; 00113 DAP.startblock = transfd; 00114 dosmemput(&DAP, sizeof(DAP), segDAP << 4); 00115 00116 __dpmi_int (0x13, &r); 00117 00118 if (r.x.flags & 1) { __dpmi_free_dos_memory(selBuff); 00119 __dpmi_free_dos_memory(selDAP); return r.h.ah; } 00120 00121 // dosmemget(segBuff << 4, blocks_per_buff * DParam->bytes_per_sect, 00122 dosmemget(segBound << 4, blocks_per_buff * DParam->bytes_per_sect, 00123 (char *) buffer + (transfd - block)*DParam->bytes_per_sect); 00124 } 00125 00126 __dpmi_free_dos_memory(selBuff); 00127 __dpmi_free_dos_memory(selDAP); 00128 return 0; 00129 } 00130 00131 00132 00133 00134 00135 00136 00137 00138 00139 // returns 0 if all goes ok, >0 int13 error, <0 DJGPP error 00140 int int13ext_write(int drv, struct driveparams *DParam, U64B block, U64B nblocks, void *buffer) 00141 { 00142 struct diskaddrpacket DAP = {sizeof(struct diskaddrpacket), 0}; 00143 int selDAP, segDAP, selBuff, segBuff, segBound; 00144 U64B transfd; 00145 U32B rdbuffsize = // 0x8000 is default buffer size (32k) 00146 (nblocks * DParam->bytes_per_sect < 0x8000)? nblocks*DParam->bytes_per_sect :0x8000; 00147 U32B blocks_per_buff = rdbuffsize/DParam->bytes_per_sect; 00148 00149 segDAP = __dpmi_allocate_dos_memory((DAP.packetsize + 15) >> 4, &selDAP); 00150 if (segDAP == -1) return NO_CTLDOS_MEMORY; 00151 // we need to allocate memory more by 32k in order to find 64k boundary 00152 // while writing with int13 in DMA mode, that boundary can't be crossed 00153 // __dpmi_int returns 9h code in ah : 00154 // data boundary error (attempted DMA across 64K boundary or >80h sectors) 00155 segBuff = __dpmi_allocate_dos_memory(((rdbuffsize + 15) >> 4) + 0x800, &selBuff); 00156 if (segBuff == -1) { 00157 __dpmi_free_dos_memory(selDAP); 00158 return NO_BUFDOS_MEMORY; 00159 } 00160 // getting 64k boundary 00161 segBound = segBuff + 0x800 - (segBuff % 0x800); 00162 00163 __dpmi_regs r; 00164 00165 U64B tailblock = (nblocks/blocks_per_buff) * blocks_per_buff + block; 00166 for (transfd = block; transfd < block+nblocks; transfd += blocks_per_buff) { 00167 r.x.ax = 0x4300; // write without verify 0x4302 - with 00168 r.h.dl = (unsigned short int) drv; 00169 r.x.ds = segDAP; 00170 r.x.si = 0; 00171 00172 DAP.packetsize = sizeof(struct diskaddrpacket); // 0x10 00173 if (transfd == tailblock) blocks_per_buff = nblocks + block - transfd; 00174 DAP.nblocks = blocks_per_buff; 00175 // DAP.buffer_segment = segBuff; 00176 DAP.buffer_segment = segBound; 00177 DAP.buffer_offset = 0; 00178 DAP.startblock = transfd; 00179 dosmemput(&DAP, sizeof(DAP), segDAP << 4); 00180 00181 dosmemput((char *) buffer + (transfd - block)*DParam->bytes_per_sect, 00182 blocks_per_buff * DParam->bytes_per_sect, segBound << 4); 00183 00184 __dpmi_int (0x13, &r); 00185 00186 if (r.x.flags & 1) { __dpmi_free_dos_memory(selBuff); 00187 __dpmi_free_dos_memory(selDAP); return r.h.ah; } 00188 } 00189 00190 __dpmi_free_dos_memory(selBuff); 00191 __dpmi_free_dos_memory(selDAP); 00192 return 0; 00193 }

Generated on Thu Jun 17 16:28:55 2004 for int13ext by doxygen 1.3.7