add initial tests for DOS absolute sector read/write
This commit is contained in:
parent
bdc2e068c4
commit
5406ba5a9b
208
tests/absread/absread.c
Normal file
208
tests/absread/absread.c
Normal file
@ -0,0 +1,208 @@
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
typedef unsigned long uint32_t;
|
||||
typedef unsigned short uint16_t;
|
||||
typedef unsigned char uint8_t;
|
||||
|
||||
void die(char *msg)
|
||||
{
|
||||
printf("%s\n", msg);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* Both traditional DOS and FAT32 DOS return this structure, but
|
||||
FAT32 return a lot more data, so make sure we have plenty of space */
|
||||
struct deviceparams {
|
||||
uint8_t specfunc;
|
||||
uint8_t devtype;
|
||||
uint16_t devattr;
|
||||
uint16_t cylinders;
|
||||
uint8_t mediatype;
|
||||
uint16_t bytespersec;
|
||||
uint8_t secperclust;
|
||||
uint16_t ressectors;
|
||||
uint8_t fats;
|
||||
uint16_t rootdirents;
|
||||
uint16_t sectors;
|
||||
uint8_t media;
|
||||
uint16_t fatsecs;
|
||||
uint16_t secpertrack;
|
||||
uint16_t heads;
|
||||
uint32_t hiddensecs;
|
||||
uint32_t hugesectors;
|
||||
uint8_t lotsofpadding[224];
|
||||
};
|
||||
|
||||
void get_partition_offset(int drive)
|
||||
{
|
||||
static struct deviceparams dp;
|
||||
int err=0;
|
||||
|
||||
printf("Getting drive info: int21h function 440Dh subfunction 0860h\n");
|
||||
|
||||
dp.specfunc = 1; /* Get current information */
|
||||
|
||||
__asm {
|
||||
mov ax, 0x440d
|
||||
mov bx, drive
|
||||
mov cx, 0x0860
|
||||
mov dx, offset dp
|
||||
int 0x21
|
||||
mov ax, 0
|
||||
adc ax, 0
|
||||
mov err, ax
|
||||
}
|
||||
|
||||
if (!err)
|
||||
{
|
||||
printf("Partition Offset = %02lXh [c=%02u,h=%02u,s=%2u]\n", dp.hiddensecs, dp.cylinders, dp.heads, dp.secpertrack);
|
||||
printf("FAT32 version 4860h to compare\n");
|
||||
}
|
||||
else
|
||||
printf("Original version failed, checking FAT32 version using 4860h\n");
|
||||
|
||||
__asm {
|
||||
mov ax, 0x440d
|
||||
mov bx, drive
|
||||
mov cx, 0x4860
|
||||
mov dx, offset dp
|
||||
int 0x21
|
||||
mov ax, 0
|
||||
adc ax, 0
|
||||
mov err, ax
|
||||
}
|
||||
|
||||
if (!err)
|
||||
{
|
||||
printf("Partition Offset = %02lXh\n", dp.hiddensecs);
|
||||
return;
|
||||
}
|
||||
else
|
||||
printf("FAT32 version failed.\n");
|
||||
}
|
||||
|
||||
struct rwblock {
|
||||
uint8_t special;
|
||||
uint16_t head;
|
||||
uint16_t cylinder;
|
||||
uint16_t firstsector;
|
||||
uint16_t sectors;
|
||||
uint16_t bufferoffset;
|
||||
uint16_t bufferseg;
|
||||
};
|
||||
|
||||
static struct rwblock mbr = {
|
||||
.special = 0,
|
||||
.head = 0,
|
||||
.cylinder = 0, /* 5265, 3fh */
|
||||
.firstsector = 0, /* MS-DOS, unlike the BIOS, zero-base sectors */
|
||||
.sectors = 1,
|
||||
.bufferoffset = 0,
|
||||
.bufferseg = 0
|
||||
};
|
||||
|
||||
|
||||
void read_mbr(int drive, const void *buf)
|
||||
{
|
||||
uint8_t err=0;
|
||||
uint16_t ds_seg=0;
|
||||
|
||||
//printf("read_mbr(%c:,%p)", 'a'+drive-1, buf);
|
||||
|
||||
mbr.bufferoffset = (unsigned short)buf;
|
||||
__asm {
|
||||
push ds
|
||||
pop ax
|
||||
mov ds_seg, ax
|
||||
}
|
||||
mbr.bufferseg = ds_seg;
|
||||
//printf("DS = %04Xh\n", ds_seg);
|
||||
|
||||
__asm {
|
||||
mov ax, 0x440d
|
||||
mov bx, drive
|
||||
mov cx, 0x0861
|
||||
mov dx, offset mbr
|
||||
int 0x21
|
||||
mov ax, 0
|
||||
adc ax, 0
|
||||
mov err, al
|
||||
}
|
||||
|
||||
if (!err) {
|
||||
//printf("Success reading MBR\n\n");
|
||||
return;
|
||||
}
|
||||
|
||||
__asm {
|
||||
mov ax, 0x440d
|
||||
mov bx, drive
|
||||
mov cx, 0x4861
|
||||
mov dx, offset mbr
|
||||
int 0x21
|
||||
mov ax, 0
|
||||
adc ax, 0
|
||||
mov err, al
|
||||
}
|
||||
|
||||
if (!err) {
|
||||
//printf("Success reading FAT32 MBR\n\n");
|
||||
return;
|
||||
}
|
||||
|
||||
printf("mbr read error");
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
unsigned int c,h,s;
|
||||
static uint8_t buf[1024];
|
||||
unsigned drive = (unsigned)(argv[1][0]); /* a=1,b=2,... */
|
||||
drive = drive-'a'+1;
|
||||
printf("Query drive %c:\n", 'a'+drive-1);
|
||||
|
||||
get_partition_offset(drive);
|
||||
|
||||
read_mbr(drive, buf);
|
||||
printf("MBR: %02Xh %02Xh %02Xh %02Xh %02Xh %02Xh %02Xh %02Xh\n",
|
||||
((const uint8_t *)buf)[0],
|
||||
((const uint8_t *)buf)[1],
|
||||
((const uint8_t *)buf)[2],
|
||||
((const uint8_t *)buf)[3],
|
||||
((const uint8_t *)buf)[4],
|
||||
((const uint8_t *)buf)[5],
|
||||
((const uint8_t *)buf)[6],
|
||||
((const uint8_t *)buf)[7]);
|
||||
|
||||
printf("Finding drive\n");
|
||||
for (c = 1024; c <= 5265; c++) {
|
||||
for (h = 0; h < 255; h++)
|
||||
for (s = 0; s <= 63; s++)
|
||||
{
|
||||
mbr.cylinder = c;
|
||||
mbr.head =h;
|
||||
mbr.sectors=s;
|
||||
read_mbr(drive, buf);
|
||||
if (buf[0] != 0) {
|
||||
printf("Found at %u,%u,%u\n", c,h,s);
|
||||
|
||||
printf("MBR: %02Xh %02Xh %02Xh %02Xh %02Xh %02Xh %02Xh %02Xh\n",
|
||||
((const uint8_t *)buf)[0],
|
||||
((const uint8_t *)buf)[1],
|
||||
((const uint8_t *)buf)[2],
|
||||
((const uint8_t *)buf)[3],
|
||||
((const uint8_t *)buf)[4],
|
||||
((const uint8_t *)buf)[5],
|
||||
((const uint8_t *)buf)[6],
|
||||
((const uint8_t *)buf)[7]);
|
||||
|
||||
exit(0);
|
||||
}
|
||||
}
|
||||
printf("c=%u,", c); fflush(NULL);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
2
tests/absread/build.bat
Normal file
2
tests/absread/build.bat
Normal file
@ -0,0 +1,2 @@
|
||||
@ECHO OFF
|
||||
wcl -e3-we-wx-zq-os-s-zp1-mt-bt=DOS absread.c
|
Loading…
Reference in New Issue
Block a user