Solved

inline asm subroutine to read primary master 0x1f0

Posted on 2004-09-26
8
355 Views
Last Modified: 2008-02-01
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
Comment
Question by:nstn2879
  • 2
  • 2
  • 2
  • +1
8 Comments
 
LVL 16

Expert Comment

by:PaulCaswell
ID: 12158204
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
 

Author Comment

by:nstn2879
ID: 12159496
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
 
LVL 16

Expert Comment

by:PaulCaswell
ID: 12159580
>>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
ScreenConnect 6.0 Free Trial

Check out the updates in one game-changing release, ScreenConnect 6.0, based on partner feedback. New features include a redesigned UI that improves session organization and overall user experience. See the enhancements for yourself!

 
LVL 22

Expert Comment

by:grg99
ID: 12162509
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
 

Author Comment

by:nstn2879
ID: 12171176
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
 
LVL 22

Expert Comment

by:grg99
ID: 12171917
re: dgpp:  sorry, that syntax is waaay too hairy for me to attempt.  Maybe someone else can chip in?

0
 

Accepted Solution

by:
modulo earned 0 total points
ID: 12931744
PAQed with no points refunded (of 500)

modulo
Community Support Moderator
0

Featured Post

Does Powershell have you tied up in knots?

Managing Active Directory does not always have to be complicated.  If you are spending more time trying instead of doing, then it's time to look at something else. For nearly 20 years, AD admins around the world have used one tool for day-to-day AD management: Hyena. Discover why

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

This tutorial is posted by Aaron Wojnowski, administrator at SDKExpert.net.  To view more iPhone tutorials, visit www.sdkexpert.net. This is a very simple tutorial on finding the user's current location easily. In this tutorial, you will learn ho…
Windows programmers of the C/C++ variety, how many of you realise that since Window 9x Microsoft has been lying to you about what constitutes Unicode (http://en.wikipedia.org/wiki/Unicode)? They will have you believe that Unicode requires you to use…
The goal of this video is to provide viewers with basic examples to understand recursion in the C programming language.
The goal of this video is to provide viewers with basic examples to understand opening and reading files in the C programming language.

910 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

21 Experts available now in Live!

Get 1:1 Help Now