• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 404
  • Last Modified:

inline asm subroutine to read primary master 0x1f0

My software works properly, however it's slow.
I need to use 0x1f0 because of the hot swap capabilities
      regaddr = 0x1f0;
      badsector = 1;
      command=0x1f7;
      reg[1] = 0;
      reg[2] = 1;
      for (i=3;i<=6;i++)
            {
            reg[i] = lbasector %256;
            lbasector = lbasector /256;
            }
      if (reg[6] > 15)
            reg[6] = 15;
      reg[6] = regaddr + reg[6];
      if(cmd == _DISK_READ)
            {
            reg[7] = 0x20;
            }
      if(cmd == _DISK_WRITE)
            {
            reg[7] = 0x30;
            }
      for (i=1;i<=7;i++)
            {
            regaddr++;
                 outp(regaddr, reg[i]);
            }
      
      for (i=0; i<100000; i++)
      {
                 if (inp(command) == 0x58)   /* check if controller is ready */
            {
            i=100000;
            badsector = 0;
            }
           }
      if (badsector == 0)
            {
                 for (i = 0; i<256; i++)
                      {
                  if(cmd == _DISK_READ)
                        buf[i] = inpw(readbuff);
                  if(cmd == _DISK_WRITE)
                        outpw(readbuff,buf[i]);
                  }
            }

what takes time is the inpw and outpw. I want to replace this in asm.

Any Suggestions?
0
nstn2879
Asked:
nstn2879
  • 2
  • 2
  • 2
  • +1
1 Solution
 
PaulCaswellCommented:
I think you will find that inpw/outpw are pretty optimal as they are. I'd suggest you try to improve your algorithm. This looks like you are reading/writing one byte at a time. Is there a block read/write function?

I dont see any documentation of the 1f7 command. Have you tried int 13 (BIOS Disk I/O).

Paul
0
 
nstn2879Author Commented:
I use int 13 in my other version, its very fast. Unfortunatley it will not allow to hot swap an IDE drive which is the whole point of accessing the drive directly through the controller.

This block read/write function sounds like the ticket, can you give me a working sample?
0
 
PaulCaswellCommented:
>>This block read/write function sounds like the ticket, can you give me a working sample?
Sorry if I gave you the impression I had one. I was thinking of sector reads using BIOS.

Have you tried threading your reads? I've no idea how or if this would work but there's always a chance.

Paul
0
What Kind of Coding Program is Right for You?

There are many ways to learn to code these days. From coding bootcamps like Flatiron School to online courses to totally free beginner resources. The best way to learn to code depends on many factors, but the most important one is you. See what course is best for you.

 
grg99Commented:
You might try the "rep insw" and "rep outsw" instructions.  You need a sequence something like:

  mov   cx,256
  cld
  lea     edi,[Buf]
  mov   ax,Seg Buf
  mov   es,ax
   rep insw
 
--------------------
Note that everything before the "rep" instruction has to be modified slightly depending on the memory model and mode you're using.  For 32-bit code, you need to change all the registers to their 32-bit counterparts.  Depending on the memory model you'll have to change the way the address of Buf gets loaded into es:di.

For writing, change es:di to ds:si, and change insw to outsw.

Note also that direct controller access is very difficult to do correctly in the general case.  There are lots of timing and interrupt gotchas, especially if the system disk driver is still running.  And handling the dozens of possible error conditions is quite hard to implement and check and debug.



 
0
 
nstn2879Author Commented:
An additional problem, I'm using the C compiler from DJGPP, so things have to look like:

   long int Num1=256, Num2=0x1f0, Sum;

  asm("movl %1, %%eax\n\t"
       "movl %2, %%ebx\n\t"
       "addl %%ebx, %%eax\n\t"
       "movl %%eax, %0"
       : "g="(Sum)
       : "g"(Num1), "g"(Num2)
       : "ax", "bx", "cx", "dx", "di", "memory");
   printf("%li+%li=%li\n",Num1,Num2,Sum);
   while(!kbhit());
   getch();

How would one implement the
rep   insw
function and transfer the results to a buffer?
0
 
grg99Commented:
re: dgpp:  sorry, that syntax is waaay too hairy for me to attempt.  Maybe someone else can chip in?

0
 
moduloCommented:
PAQed with no points refunded (of 500)

modulo
Community Support Moderator
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

Join & Write a Comment

Featured Post

What Kind of Coding Program is Right for You?

There are many ways to learn to code these days. From coding bootcamps like Flatiron School to online courses to totally free beginner resources. The best way to learn to code depends on many factors, but the most important one is you. See what course is best for you.

  • 2
  • 2
  • 2
  • +1
Tackle projects and never again get stuck behind a technical roadblock.
Join Now