Page 1 of 1

Additional BrokenThorn Issue?

Posted: Fri Sep 11, 2020 8:18 pm
by pretzelpirate
I don't see it listed here, but I thought I'd have someone check that the issue is with the page and not me: https://wiki.osdev.org/Brokenthorn%27s_Known_Bugs

In OSDev6, BrokenThorn says the LBA to CHS conversion formulas are:
absolute sector = (LBA % sectors per track) + 1
absolute head = (LBA / sectors per track) % number of heads
absolute track = LBA / (sectors per track * number of heads)
link: http://www.brokenthorn.com/Resources/OSDev6.html

I believe the "absolute track" formula is incorrect and the correct set of equations should be:
absolute sector = (LBA % sectors per track) + 1
absolute head = (LBA / sectors per track) % number of heads
absolute track = (LBA / sectors per track) / number of heads
Adding this would reduce confusion with people wondering why the code never multiplies by "number of heads".

I don't have permissions to edit the Wiki yet, but if this looks correct, I can add the reference.

Re: Additional BrokenThorn Issue?

Posted: Sat Sep 12, 2020 1:46 am
by alexfru
There is no difference?

Try this code:

Code: Select all

#include <stdio.h>

int main(void)
{
  int a, b, c;
  puts("Begin...");
  for (a = 0; a < 128; a++)
    for (b = 1; b < 128; b++)
      for (c = 1; c < 128; c++)
      {
        int r0 = (a / b) / c;
        int r1 = a / (b * c);
        if (r0 != r1)
          printf("(%d / %d) / %d != %d / (%d * %d)\n", a, b, c, a, b, c);
        //printf(".");
      }
  puts("End.");
  return 0;
}
Output:
Begin...
End.

Re: Additional BrokenThorn Issue?

Posted: Sat Sep 12, 2020 1:49 am
by nullplan
The two are identical. Unless I missed something, dividing by a product is the same as dividing by each of the factors. Mathematically:

Code: Select all

a / b / c = (a / b) / c = (a / b) * (1 / c) = (a * 1) / (b * c)
That doesn't hold with integer division in C, yes, because of the round-off error introduced in step 2, but the ends still apply. I am sure, someone better versed in number theory than I could prove this proposition. But for now I have simply written a program to prove it for me within the range given and it failed to find any counter examples. And that is good enough for me.
pretzelpirate wrote:I don't have permissions to edit the Wiki yet, but if this looks correct, I can add the reference.
Enter your user control panel, click "user groups", click "Wiki", and click "Join". Done.

Re: Additional BrokenThorn Issue?

Posted: Sat Sep 12, 2020 6:49 am
by pretzelpirate
It looks like you're all correct, and I should avoid posting late at night.

I don't quite understand why BrokenThorn used a less obvious formula that didn't match the specific steps that were being done in code, but perhaps this post will help other people who wonder why the code and comments don't match.

Thanks everyone!

Re: Additional BrokenThorn Issue?

Posted: Sat Sep 12, 2020 11:17 am
by nullplan
pretzelpirate wrote:I don't quite understand why BrokenThorn used a less obvious formula
Probably a micro-optimization. This way avoids one division, and some programmers, particularly low-level OS programmers, have a pathological aversion to division, believing it to be slow. In this case, though, when you are trying to access a floppy drive, a division is going to be the least of your worries, timewise.

Re: Additional BrokenThorn Issue?

Posted: Sat Sep 12, 2020 11:58 am
by Octocontrabass
It could be left over from analyzing a hard disk bootloader that uses only 16-bit instructions. It's possible for (LBA / sectors per track) to overflow a 16-bit DIV instruction in cases where (LBA / (sectors per track * number of heads)) would not.