Image Map Image Map
Results 1 to 6 of 6

Thread: Calculating INT13 CHS addresses.

  1. #1

    Question Calculating INT13 CHS addresses.

    For very specific reasons, I've written a pair of utilities that sends raw disk sectors over RS232 (via INT14+FOSSIL), to a receiving program that takes the data and concatenates into an image file. For some reason, the resulting image won't boot (Missing Operating System), and I need to see if I am calculating the C/H/S correctly for the INT13 read sector command, can somebody take a look?

    The relevant repo is here:

    http://github.com/tschak909/disk-xfer

    and the relevant bit that reads disk sectors is here:

    https://github.com/tschak909/disk-xf...os/src/int13.c

    Am I doing something _REALLY_ stupid, here?

    -Thom

  2. #2
    Join Date
    Jan 2007
    Location
    Pacific Northwest, USA
    Posts
    31,526
    Blog Entries
    20

    Default

    I think so...

    Code:
     regs.h.cl|=(c&0xC0)<<2; // cyl high
    Consider, for example if your cylinder number is 768 (300h). then the high order bits of cl will be set to

    (0x300 & 0xC0) = 0; 0 << 2 = 0.

    You really want that to be |= ( (c & 0x300) >> 2); Which would put C0H in the high order 2 bits of cl.

    It's always good to run sample numbers by hand to check your code. To look at it another way, consider a sector read of 63/255/1023.

    CL = 0x3f + 0xc0 = 0xff
    CH = 0xff
    DH = 0xff, which is the maximum CHS addressing possible.

    There was a scheme used by some old WD controllers that borrowed 2 high order bits from the DH head register and used it to extend the cylinder range to 4095.
    Last edited by Chuck(G); April 23rd, 2019 at 11:05 AM.

  3. #3

    Default

    /**
    * Read sector given CHS
    */
    unsigned char int13_read_sector(short c, unsigned char h, unsigned char s, char* buf)
    {
    // Perform the read.
    regs.h.ah=AH_READ_DISK_SECTORS;
    regs.h.al=1; // 1 sector.
    regs.h.dh=h;
    regs.h.dl=0x80; // first hd
    regs.x.bx=(short)buf;
    regs.h.ch=c&0xFF; // cyl low
    /* regs.h.cl=s | ((c >> 2) & 0xC0); // sector / cyl high */
    regs.h.cl|=((c&0x300)>>2); // Sector/cyl high
    int86(0x13,&regs,&regs);

    // 0 if successful, 1 if not.
    return regs.x.cflag;
    }


    Which now gives me data that doesn't look anything like a boot sector in the first 512 bytes.



    -Thom

  4. #4

    Default

    oh crap, I saw what I did wrong. nevermind.
    -Thom

  5. #5

    Default

    Care to share where you messed up? Might help others in the future.

    Some advice though? Whitespace is your friend, use it. Likewise you wouldn't need to waste time typing so many comments if your property names weren't so cryptic. ->c and ->h might seem convenient NOW, but you're screwing over anyone who has to work with it later, AND you'll want to punch yourself a year or more from now when/if you come back to this.

    Code:
    	geometry->heads = regs.h.dh;
    	geometry->sectors = regs.h.cl & 0x3F;
    	geometry->cylinders = ((regs.h.cl & 0xC0) << 2) + regs.h.ch;
    SO much clearer and easier to understand without needing comments. Same with your read:

    Code:
      regs.h.ah = AH_READ_DISK_SECTORS;
      regs.h.al = 1; // number of sectors
      regs.h.dh = head;
      regs.h.dl = 0x80; // first hd
      regs.x.bx = (short)buf;
      regs.h.ch = cylinder & 0xFF;
      regs.h.cl = ((cylinder >> 2) & 0xC0) + sector;
      int86(0x13, &regs, &regs);
    Though on both I would REALLY consider inline assembler or linking in external ASM to handle that, if for no other reason than C's handling/optimization/efficiency at shift math is so piss poor, and you could directly set the result in AX instead of copying all those values to -- and from -- the garbage 'flags' register nonsense. "regs" in C or "registers" in Pascal are cute and convenient for testing, but not something I'd ever suggest using in deployment.
    From time to time the accessibility of a website must be refreshed with the blood of owners and designers. It is its natural manure.
    CUTCODEDOWN.COM

  6. #6
    Join Date
    Jan 2007
    Location
    Pacific Northwest, USA
    Posts
    31,526
    Blog Entries
    20

    Default

    Depends whose "C". Some optimizing C compilers can be quite clever. Regardless, the code is just a tiny part of the overhead of reading and doesn't make much difference in execution time. It may also be more desirable than inline assembly from the standpoint of someone with only a "C", but not _asm background to read. Finally, not all C compilers use the same inline assembly syntax.

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •