VirtualBox

source: kStuff/hacks/xtide/writeatatest.c@ 73

Last change on this file since 73 was 73, checked in by bird, 9 years ago

xtide util hacking.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 9.2 KB
Line 
1/* $Id: writeatatest.c 73 2015-12-20 21:17:34Z bird $ */
2/** @file
3 * Does a little write test.
4 */
5
6/*
7 * Copyright (c) 2015 knut st. osmundsen <bird-kBuild-spamx@anduin.net>
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 3 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with This program. If not, see <http://www.gnu.org/licenses/>
21 *
22 */
23
24
25/*********************************************************************************************************************************
26* Header Files *
27*********************************************************************************************************************************/
28#include <stdarg.h>
29#include <stdio.h>
30#include <stdlib.h>
31#include <string.h>
32#include <stdint.h>
33#include <io.h>
34#include <conio.h>
35#include "atalib.h"
36
37
38/*********************************************************************************************************************************
39* Structures and Typedefs *
40*********************************************************************************************************************************/
41typedef struct REGS16
42{
43 uint16_t ax; /**< 0 */
44 uint16_t cx; /**< 2 */
45 uint16_t dx; /**< 4 */
46 uint16_t si; /**< 6 */
47 uint16_t di; /**< 8 */
48 uint16_t es; /**< 10 */
49 uint16_t efl; /**< 12 */
50 uint16_t ds; /**< 14 */
51 uint16_t bx; /**< 16 */
52} REGS16;
53
54#define X86_EFL_CF 1
55
56
57/*********************************************************************************************************************************
58* Global Variables *
59*********************************************************************************************************************************/
60uint8_t g_bDrv = 0x80;
61
62
63/*
64 * INT13h access methods
65 * INT13h access methods
66 * INT13h access methods
67 */
68
69void BiosCall13(REGS16 *pRegs);
70#pragma aux BiosCall13 = \
71 "push ax" \
72 "push cx" \
73 "push dx" \
74 "push bp" \
75 "push si" \
76 "push di" \
77 "push es" \
78 "push bx" \
79 "push ds" \
80 \
81 "mov ax, [bx]" \
82 "mov cx, [bx + 2]" \
83 "mov dx, [bx + 4]" \
84 "mov si, [bx + 6]" \
85 "mov di, [bx + 8]" \
86 "mov es, [bx + 10]" \
87 "push word ptr [bx + 12]" \
88 "popf" \
89 "push word ptr [bx + 14]" \
90 "push word ptr [bx + 16]" \
91 "pop bx" \
92 "pop ds" \
93 \
94 "int 13h"\
95 \
96 "push ds" \
97 "push bx" \
98 "mov bp, sp" \
99 "mov ds, [bp + 4]" \
100 "mov bx, [bp + 6]" \
101 "mov [bx], ax" \
102 "mov [bx + 2], cx" \
103 "mov [bx + 4], dx" \
104 "mov [bx + 6], si" \
105 "mov [bx + 8], di" \
106 "mov [bx + 10], es" \
107 "pushf" \
108 "pop ax" \
109 "mov [bx + 12], ax" \
110 "pop ax" \
111 "mov [bx + 14], ax" \
112 "pop ax" \
113 "mov [bx + 16], ax" \
114 \
115 "pop ds" \
116 "pop bx" \
117 "pop es" \
118 "pop di" \
119 "pop si" \
120 "pop bp" \
121 "pop dx" \
122 "pop cx" \
123 "pop ax" \
124 parm [bx];
125
126
127int Int13hInit(void)
128{
129 REGS16 Regs;
130 memset(&Regs, 0, sizeof(Regs));
131 Regs.ax = 0x0800;
132 Regs.dx = g_bDrv;
133 BiosCall13(&Regs);
134 /** @todo check for errors. */
135 g_cHeads = (Regs.dx >> 8) + 1;
136 g_cSectorsPerTrack = Regs.cx & 0x3f;
137 g_cCylinders = (Regs.cx >> 8) | ((Regs.cx & 0xc0) << 2);
138 g_cSectorsPerCylinder = g_cHeads * g_cSectorsPerTrack;
139
140 printf("Drive %#x parameters: %u cylinders, %u heads, %u sectors\n",
141 g_bDrv, g_cCylinders, g_cHeads, g_cSectorsPerTrack);
142 if (!(Regs.efl & X86_EFL_CF))
143 return 0;
144 fprintf(stderr, "Error getting disk params: %#x\n", Regs.ax);
145 return -1;
146}
147
148void SectorNoToInt13(uint32_t iSector, REGS16 *pRegs)
149{
150 uint16_t iRem = iSector % g_cSectorsPerCylinder;
151 uint16_t iCyl = iSector / g_cSectorsPerCylinder;
152 pRegs->cx = iCyl << 8;
153 pRegs->cx |= (iCyl >> 2) & 0xc0;
154 pRegs->cx |= (iRem % g_cSectorsPerTrack) & 0x3f;
155 pRegs->dx &= UINT16_C(0x00ff);
156 pRegs->dx |= (iRem / g_cSectorsPerTrack) << 8;
157}
158
159int Int13hReadSector(uint32_t iSector, void *pvBuf)
160{
161 REGS16 Regs;
162 memset(&Regs, 0, sizeof(Regs));
163 Regs.ax = 0x0201;
164 Regs.dx = g_bDrv;
165 Regs.bx = (unsigned)(void __near *)pvBuf;
166 Regs.es = (__segment)pvBuf;
167 SectorNoToInt13(iSector, &Regs);
168 printf("ax=%#x dx=%#x cx=%#x es:bx=%04x:%04x\n", Regs.ax, Regs.dx, Regs.cx, Regs.es, Regs.bx);
169 BiosCall13(&Regs);
170 if (!(Regs.efl & X86_EFL_CF))
171 return 0;
172 fprintf(stderr, "Error reading sector %lu on %#x: %#x\n", iSector, g_bDrv, Regs.ax);
173 return -1;
174}
175
176int Int13hWriteSector(uint32_t iSector, void const *pvBuf)
177{
178 REGS16 Regs;
179 memset(&Regs, 0, sizeof(Regs));
180 Regs.ax = 0x0301;
181 Regs.dx = g_bDrv;
182 Regs.bx = (unsigned)(void const __near *)pvBuf;
183 Regs.es = (__segment)pvBuf;
184 SectorNoToInt13(iSector, &Regs);
185 printf("ax=%#x dx=%#x cx=%#x es:bx=%04x:%04x\n", Regs.ax, Regs.dx, Regs.cx, Regs.es, Regs.bx);
186 BiosCall13(&Regs);
187 if (!(Regs.efl & X86_EFL_CF))
188 return 0;
189 fprintf(stderr, "Error writing sector %lu on %#x: %#x\n", iSector, g_bDrv, Regs.ax);
190 return -1;
191}
192
193
194
195int GetDriveParams(uint8_t bDevice)
196{
197#ifdef USE_INT13H
198 return Int13hInit();
199#else
200 return 0;
201#endif
202}
203
204int ReadSector(uint32_t iSector, void *pvBuf)
205{
206#ifdef USE_INT13H
207 return Int13hReadSector(iSector, pvBuf);
208#else
209 return AtaReadSector(iSector, pvBuf);
210#endif
211}
212
213int WriteSector(uint32_t iSector, void const *pvBuf)
214{
215#ifdef USE_INT13H
216 return Int13hWriteSector(iSector, pvBuf);
217#else
218 return AtaWriteSector(iSector, pvBuf);
219#endif
220}
221
222
223
224
225static int usage(void)
226{
227 printf("usage: writetst [sector] [drv]\n");
228 return 1;
229}
230
231
232int main(int argc, char **argv)
233{
234 int rc = 1;
235
236 /*
237 * Parse parameters.
238 */
239 uint32_t iSector = 3;
240 uint8_t bDevice = ATA_DEV_MASTER;
241 g_bDrv = 0x80;
242
243 if (argc > 3)
244 {
245 fprintf(stderr, "too many parameters!\n");
246 return usage();
247 }
248 if (argc > 1)
249 {
250 iSector = strtoul(argv[1], NULL, 0);
251 if ( iSector == 0
252 || (iSector >= 32 && iSector < 65535)
253 || iSector > 0x800000 /*4G*/)
254 {
255 fprintf(stderr, "error: start sector is out of bounds: %s (%lu)\n", argv[1], iSector);
256 return usage();
257 }
258 }
259 if (argc > 2)
260 {
261 if (AtaInitFromArgv(2, argc, argv) != 0)
262 return usage();
263 }
264
265 /*
266 * Detect drive parameters.
267 */
268 if (GetDriveParams(bDevice) == 0)
269 {
270 static uint8_t s_abSaved[512];
271 if (ReadSector(iSector, s_abSaved) == 0)
272 {
273 static uint8_t s_abWrite[512];
274 unsigned i;
275 unsigned cTries;
276 //unsigned cMaxTries = 20;
277 unsigned cMaxTries = 1;
278
279 for (i = 0; i < 512; i++)
280 s_abWrite[i] = (uint8_t)i;
281
282 for (cTries = 0; cTries < cMaxTries && rc != 0; cTries++)
283 {
284 if (WriteSector(iSector, s_abWrite) == 0)
285 {
286 static uint8_t s_abReadBack[512];
287
288 if (ReadSector(iSector, s_abReadBack) == 0)
289 {
290 for (i = 0; i < 512; i++)
291 s_abWrite[i] = (uint8_t)i;
292
293 if (memcmp(s_abReadBack, s_abWrite, sizeof(s_abReadBack)) == 0)
294 {
295 rc = 0;
296 printf("wrote sector and successfully read it back\n");
297 }
298 else if (cTries >= cMaxTries - 1)
299 {
300 unsigned cErrors = 0;
301 fprintf(stderr, "read back doesn't match what was written:\n");
302 for (i = 0; i < 512; i++)
303 if (s_abReadBack[i] != (uint8_t)i)
304 {
305 fprintf(stderr, " %03x: %02x->%02x", i, (uint8_t)i, s_abReadBack[i]);
306 if ((cErrors % 5) == 4)
307 fprintf(stderr, "\n");
308 cErrors++;
309 if (cErrors > 5 * 10)
310 break;
311 }
312 if ((cErrors % 5) != 0)
313 fprintf(stderr, "\n");
314 }
315 }
316
317 }
318 }
319
320 /* restore */
321 WriteSector(iSector, s_abSaved);
322 }
323 }
324
325
326 return rc;
327}
328
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette