Solved

inline asm subroutine to read primary master 0x1f0

Posted on 2004-09-26
8
342 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
How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

 
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

6 Surprising Benefits of Threat Intelligence

All sorts of threat intelligence is available on the web. Intelligence you can learn from, and use to anticipate and prepare for future attacks.

Join & Write a Comment

An Outlet in Cocoa is a persistent reference to a GUI control; it connects a property (a variable) to a control.  For example, it is common to create an Outlet for the text field GUI control and change the text that appears in this field via that Ou…
This is a short and sweet, but (hopefully) to the point article. There seems to be some fundamental misunderstanding about the function prototype for the "main" function in C and C++, more specifically what type this function should return. I see so…
The goal of this video is to provide viewers with basic examples to understand and use pointers in the C programming language.
Video by: Grant
The goal of this video is to provide viewers with basic examples to understand and use for-loops in the C programming language.

707 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

15 Experts available now in Live!

Get 1:1 Help Now