In initdisk.c [1], there is a label "StandardBios:" at line 719. In the code
at this location, FreeDOS makes an INT13H function 0x08 call to get current
drive parameters. The values of the drive parameters are then parsed out of
the return registers and placed into driveParam->chs.Cylinder/Head/Sector.
730: driveParam->chs.Head = (regs.d.x >> 8) + 1;
731: driveParam->chs.Sector = (regs.c.x & 0x3f);
733: driveParam->chs.Cylinder = (regs.c.x >> 8) | ((regs.c.x & 0xc0) << 2)
+ 1;
In the above code, when chs.Cylinder is assigned a value, it seems to be
stepping on the Head value that was previously set. I updated the code
snippet to including printing out the value of Heads throughout the
StandardBIOS routine.
StandardBios: /* old way to get parameters */
printf("StandardBios call, drive %02Xh\n", drive);
regs.a.b.h = 0x08;
regs.d.b.l = drive;
init_call_intr(0x13, ®s);
if (regs.flags & 0x01)
goto ErrorReturn;
printf("int13h:08h return= dx:%04X, cx:%04X\n", regs.d.x, regs.c.x);
printf("calculated Cylinders:%u\n", ((regs.c.x >> 8) | ((regs.c.x & 0xc0)
<< 2)) + 1);
printf("calculated Heads:%u\n", (regs.d.x >> 8) + 1);
printf("calculated Sectors:%u\n", (regs.c.x & 0x3f));
/* int13h call returns max value, store as count (#) i.e. +1 for 0 based
heads & cylinders */
driveParam->chs.Head = (regs.d.x >> 8) + 1; /* DH = max head value = # of
heads - 1 (0-255) */
printf("driveParam->chs.Head:%u -should match calculated Heads
above\n", driveParam->chs.Head);
driveParam->chs.Sector = (regs.c.x & 0x3f); /* CL bits 0-5 = max sector
value = # (sectors/track) - 1 (1-63) */
printf("2) driveParam->chs.Head:%u -should match calculated Heads
above\n", driveParam->chs.Head);
/* the next call (Cylinder assignment) messes up the Heads value */
/* max cylinder value = # cylinders - 1 (0-1023) = [high two
bits]CL7:6=cyls9:8, [low byte]CH=cyls7:0 */
driveParam->chs.Cylinder = ((regs.c.x >> 8) | ((regs.c.x & 0xc0) << 2)) +
1;
printf("3) driveParam->chs.Head:%u -should match calculated Heads
above\n", driveParam->chs.Head);
.
This is the result:
int13h:08h return= dx:0f01, cx:e0ff
calculated Cylinders:993
calculated Heads:16
calculated Sectors:63
driveParam->chs.Head:16 -should match calculated Heads above
2) driveParam->chs.Head:16 -should match calculated Heads above
3) driveParam->chs.Head:225 -should match calculated Heads above
drive 80h total: C = 993, H = 225, S = 63, total size 488MB
In the above output, notice that at the third output of chs.Heads the value
is no longer 16, but rather 225.
If I modify /hdr/device.h and change the CHS struct from
struct CHS {
UWORD Cylinder;
UWORD Head;
UWORD Sector;
};
to
/hdr/device.h
struct CHS {
UWORD Cylinder;
UWORD space1;
UWORD Head;
UWORD space2;
UWORD Sector;
};
I get this for debug output:
int13h:08h return= dx:0f01, cx:e0ff
calculated Cylinders:993
calculated Heads:16
calculated Sectors:63
driveParam->chs.Head:16 -should match calculated Heads above
2) driveParam->chs.Head:16 -should match calculated Heads above
3) driveParam->chs.Head:16 -should match calculated Heads above
drive 80h total: C = 993, H = 16, S = 63, total size 488MB
Notice that the value of 16 is retained properly in chs. Heads.
The struct for driveParam is below (from initdisk.c line 227).
struct DriveParamS {
UBYTE driveno; /* = 0x8x */
UWORD descflags;
ULONG total_sectors;
struct CHS chs; /* for normal INT 13 */
};
*** QUESTIONS ***:
1. Is this an alignment issue of some sort?
2. Could this be due to a misconfiguration in my FreeDOS build setup?
3. Does anyone have suggestions for how I might correct this behavior?
I am running the code on a 286 processor with the FreeDOS kernel loaded from
an IDE CF Card.
>From my config.bat on my build system:
set XNASM=nasm
set COMPILER=WATCOM
set WATCOM=c:\watcom
set PATH=%PATH%;%WATCOM%\binw
set XUPX=
set XLINK=..\utils\wlinker /ma /nologo
set MAKE=%WATCOM%\binw\wmake /ms
set XCPU=86
set XFAT=16
set ALLCFLAGS=-DDEBUG -DSK_DEBUG -DEBUG_TRUENAME
I am using zp1 (the default for the Watcom makefile from the FreeDOS
source). From mkfiles/watcom.mak on my build system:
CFLAGST=-zq-zp1-os-s-we-e3-wx-bt=DOS
CFLAGSC=-mc-zq-zp1-os-s-we-e3-wx-bt=DOS
ALLCFLAGS=-I..$(DIRSEP)hdr $(TARGETOPT)
$(ALLCFLAGS)-zq-os-s-e5-j-zl-zp1-wx-we-zgf-zff-r
Thank you!
Rich
[1] =
https://github.com/FDOS/kernel/blob/afe7fbe068bf7f3cc99dc01bf8e402311095757b
/kernel/initdisk.c
_______________________________________________
Freedos-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/freedos-devel