Link to home
Start Free TrialLog in
Avatar of san_hbs
san_hbs

asked on

Got Stuck with linking 16-bit assembly to 32-bit VC++ program

Hi all,
  I have got stuck with an assembly program, which is written for port reading from an add-on ISA card. I need to write a VC++ application, which will get the values read by assembly program and do some manipulation. But I am unable to use the program in Windows.
  Can anyone show me a way as to how shall I proceed? I am really clueless on linking this assembly code with the VC++ application. Please help me.

Thanks in advance for any help.
San
"Be Good, Do Good".
SOLUTION
Avatar of BeyondWu
BeyondWu
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of san_hbs
san_hbs

ASKER

BeyondWu,
>You can't read a port directly in a 32bit windows program. The "in/out" intel-opcodes is a privilege instruction
Can't I write 32-bit assembly code for port I/O?

Thanks a lot for your suggestions and help.
San
"Be Good, Do Good".
>>Can't I write 32-bit assembly code for port I/O?
Yes, you can't!
It has nothing to do with which tool(MASM/VC/VB..) or which language(ASM/C/C++..) you used.
Avatar of san_hbs

ASKER

Can the assembly program I am using work on Win98?
Can't I write assembly code for port I/O using Win98 OS?

Regards
San
"Be Good, Do Good".
>>Can the assembly program I am using work on Win98?
It depend on the type of the program and which port it access.
Do you know the type? Dos program(MZ)? 16bit Windows program(NE)? or 32bit windows program(PE)?

>>Can't I write assembly code for port I/O using Win98 OS?
Yes, except you write a VXD/WDM driver.
Avatar of san_hbs

ASKER

>>Do you know the type? Dos program(MZ)? 16bit Windows >>program(NE)? or 32bit windows program(PE)?
No, I don't.
The port I am willing to use is of an add-on ISA card. This port will receive data from a GPS (Global Positioning System) device. I am supposed to get this data and write it on a map image on the screen. This is a part of academic project. I have the ISA card, but not any driver. Please suggest a way to proceed.
Regards
San
"Be Good, Do Good".
>>I have the ISA card, but not any driver.
Can this card work normally on your PC without any driver?
If not, you need the spec of the card, and write a driver, it's complex:O(, you should work with the hardware engineer.

Otherwise, you only need to know which port it uses, and read the port simply with a driver(actually, any ring0 code).
Sorry san_hbs, I made a mistake.

You can read/write port directly under win98.
you can simply use inline _asm directive.
Avatar of san_hbs

ASKER

Hi BeyonwWu,
Here I am giving the complete code in Assembly, that is working in DOS.
==
     TITLE   IOC_OA
     DOSSEG
     .MODEL small

PUBLIC  _vectloc
PUBLIC  _oldvect
PUBLIC  _mask1
PUBLIC  _mask2

.data
_vectloc     DD     000001ccH
_oldvect     DD      0f000ff23H
EXTRN     _value:word
EXTRN     _index:word
_mask1 db 0
_mask2 db 0

.code

PUBLIC     _install
_install     PROC NEAR

push ax
push bx
push dx
push ds
push es
cli
mov al,99h
mov dx,323h
out dx,al
     les     bx,DWORD PTR _vectloc          
     mov     ax,WORD PTR es:[bx]          
     mov     dx,WORD PTR es:[bx+2]          
     mov     WORD PTR _oldvect,ax          
     mov     WORD PTR _oldvect+2,dx
     mov     WORD PTR es:[bx],OFFSET _handler
     mov     WORD PTR es:[bx+2],SEG _handler

in al,21h
mov _mask1,al
and al,0fbh
out 21h,al
in al,0a1h
mov _mask2,al
and al,0f7h
out 0a1h,al                              
mov al,10100110b
mov dx,321h
out dx,al
sti
mov al,020h
out 020H,al
out 0a0H,al

pop es
pop ds
pop dx
pop bx
pop ax
ret
_install     ENDP

PUBLIC     _trmnate
_trmnate     PROC NEAR
push ax
push bx
push dx
push ds
push es
cli
     les     bx,DWORD PTR _vectloc
     mov     ax,WORD PTR _oldvect
     mov     dx,WORD PTR _oldvect+2
     mov     WORD PTR es:[bx],ax
     mov     WORD PTR es:[bx+2],dx
mov al,_mask1
out 21h,al
mov al,_mask2
out 0a1h,al
sti
mov al,020h
out 020H,al
out 0a0H,al
pop es
pop ds
pop dx
pop bx
pop ax
ret
_trmnate     ENDP

PUBLIC     _handler
_handler     PROC FAR
pushf
push ax
push bx
push dx
push ds
mov ax,@data
mov ds,ax
mov dx,0320h
in al,dx
mov ah,al
add dx,2
in al,dx
mov bx,_index
mov word ptr _value[bx],ax
add _index,2
and _index,16383
mov al,020H
out 020H,al
out 0a0H,al
pop ds
pop dx
pop bx
pop ax
popf
sti
iret
_handler     ENDP

END
==

Can you please suggest me the enhancement I should make, so that it may work on win98??
Please suggest a way..
Thanks a lot for your concern to this problem
Regards
San
"Be Good, Do Good".
ASKER CERTIFIED SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of san_hbs

ASKER

BeyondWu,
  I tried with the driver code you suggested, but I need to work on that for some time because I am really unaware of that.
  Here is another problem, which I am getting during runtime of the assembly code in Win98.
The following line of code give unhanded exception - Access Violation
          mov ax,WORD PTR es:[ebx]    
  Please suggest me a way
Regards
San
"Be Good, Do Good".
Why still use mov ax,WORD PTR es:[ebx]?
It's only available under 16bit realmode.
Avatar of san_hbs

ASKER

>Why still use mov ax,WORD PTR es:[ebx]?
Because I want to do it in Win98. Apart from the driver ,which may take long time, I want to use the assembly code also.
Thank you
Regards
San
"Be Good, Do Good".
>Answer to why use mov ax,word ptr es:[ebx]
First you can use word ptr in 32 bit code,this gets
and override byte before the instruction of 0x67. Sometimes
you must read only 2 bytes at a time, as in harddisk interfaceing.
Second - under windows segment registers ds ,es ,ss are always the same segment(selector), fs has another value which I do not know what it is for and gs is always 0.
You can drop the es: in the instruction, this costs about
one clock cycle extra and does not change anything.
Your Access Violation was caused by a bad pointer [ebx].
I have used with success the library "winio" for port access in win95 - windows2000. It is easy use to in C and assembler and I think shareware.
Dancie,
Of cource, you can use the instruction mov ax,word ptr es:[ebx], and everything you said are right, but san_hbs want to hook/change the IVT under win32! Not the I/O port, do you think it's possible to change the IVT in win2k with the "winio" driver?
Comment for BeyondWu
No winio cannot change the IVT (in protected mode it is called the Interrupt Descriptor table. The only way is to write a driver that runs in ring 0. There you can get the selector of the interrupt descriptor table with the instruction sidt[address]. After you have this you can make a data descriptor which mirrors the IDT and change it.
But there is actually much more to do than simply changing the data. You must know many other factors. It is possible but difficult.
For Dancie,
Agree with you, the normal approach is use IoConnectInterrupt, but for some IRQ it's not available, we only can with SIDT/LIDT.
It seems san_hbs has forgotten the question. We don't waste time for it.:O(
Avatar of san_hbs

ASKER

BeyondWu and Dancie,
I am extremely sorry for not being involved in your discussion for so long. Actually, fast few days have not been very nice for me. Anyway I am back and hope to continure it.
I tried to build the driver as suggested by You, but I am unable to test it properly. I am not even sure that the driver I have made is correct or not (Any tools to check it?). Now the platform of development has also changed. I am being asked to develop the driver on Win2k Platform. As per my understanding of the topic, if I develop a driver, it is supposed to work on Win98/2k platform. What I want is, the driver will take the data from the ISA card and store it into a buffer. This buffer will be accessed by another part of front-end application at the same time. Your suggestions are most welcome.
I am really greatful to you both for taking serious note of my problem and trying to help me.
Regards
San
"Be Good, Do Good".
Although it is not recommmended, you *can* read and write directly to ports with Win95/98/ME, but not with NT/2000/XP.