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, &regs);

  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
Freedos-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/freedos-devel

Reply via email to