Hi all
I have implemented a hook onto the Timer Tick interupt, and created code that would update a varaible in Basic with that count.
This precvents me from calling for updates and I always have the latest count.
Currently investigating converting to FreeBasic, which runs in protected mode, which is basically chinese to me.
It has in-line asm which together with other features is a great attraction.
I am using Timer Tick as an example, but have implemented other interupt hooks as well which have the same conversion need.
The code I produce runs on industrial machines in a pure dos environment using the Win95 dpmi.
The dos interface in FreeBasic is based on the DJGPP library.
Have googled extensively and spend countless hours reading and getting more confused.
My problem is that I cant seem to confirm if there is a protected mode Timer Tick available that I can hook onto,(and how)
without causing a switch to real mode when my variable is updated.
It also appears that a switch to real mode occurrs to handle some of these interupts.
Most of the info available assumes dos applications running in a dos window with whatever Win version resources available.
Similarly it assumes the complexity required for multiple task applications.
My application is one where I own the machine, and nothing else will ever run at the same time as my application.
The other int I have hooked are:
Keyboard (stop polling all day for possible key stroke)
TouchScreen , same reason
Hardwired int that updates an adc count 2000 times per second.
Can somebody steer me in the right direction.
Regards
Are you then using the DOS7 of Win95 as a boot environment to host your program in?
If so, this is a 16 bit DOS question. And standard DOS programming techniques apply. You do want to use interupt hooks still, right?
If your using a Complied Basic program in a DOS OS, then I recommend Power Basic for DOS. It has very good support for ASM subroutines.
http://www.powerbasic.com/products/pbdos/
If your looking to go to outside of DOS, please consider that you will force your users to upgrade their hardware to accomodate your re-written software.
Regards, P1 :8)
> My problem is that I cant seem to confirm if there is a protected mode Timer Tick
Of course there is one. And what's better, you don't need to care about real-mode hooking in dpmi, because the IRQ is reflected to protected mode by the dpmi host. So just hook interrupt in protected mode (using dpmi int 31h, ax=0204h/0205h).
P1
I thought very carefully about the section I was posting in.
16 bit dos, it was not.
Anyhow, yes using dos7, but FreeBasic is 32bit and will not run in real mode.
Actually bought Powerbasic a while ago, but there are too many differences that would require re-writing.
Gustav, I actually got that detail, but had doubts that all the info for that int were there.
Will try again.
Regards
Hi all
I do think I need help here.
Below the code from 16bit app.
.MODEL MEDIUM
.486
.CODE
;-------------------------
PUBLIC TSRTIME
OldHandle DD ?
VarblSeg DW ?
VarblOfs DW ?
;-------------------------
TSRTIME PROC FAR
;------------
PUSH BP
MOV BP,SP
;------------
push ds ;for return to basic
push cs
pop ds ;set to current CS
;------------
MOV BX,[BP+6] ;segment of basic variable
CMP BX,0 ;if zero then program is terminating
JZ Restore ;so restore old handler.
MOV VarblSeg,BX
MOV BX,[BP+10] ;offset of basic variable
MOV VarblOfs,BX
;-----------------------------------
cli ;no int whilst re-assigning int.
mov ax, 351Ch ;get function 35
int 21h ;get vector for timer tick
mov WORD PTR OldHandler[0], bx ;save addr of original handler
mov WORD PTR OldHandler[2], es
mov ax, 251Ch ;function 25h
mov dx, OFFSET TsrTimer ;new handler addr
int 21h ;set vector with addr of new handler
sti
;----------------------------------
jmp Dos_Exit
Restore:
cli ;no int whilst re-assigning int.
lds dx,OldHandler
mov ax,251Ch
int 21h
sti
jmp Dos_Exit
TsrTimer PROC FAR
;---------
PUSH DS
PUSH BX
;---------------
mov ds,VarblSeg ;set seg to Basic's variable
mov bx,VarblOfs ;set ofs " " "
inc dword ptr [bx] ;inc the timer tick
;---------------
POP BX
POP DS
;*********
jmp cs:OldHandler
TsrTimer ENDP
;---------------------------------------
Dos_Exit:
pop ds ;restore basic's DS
POP BP ;
ret 8 ;clean up
TSRTIME ENDP
END
Now I tried to convert it to protected mode.
This is in-line asm for FreeBasic.
SUB HookInt
asm
xor eax,eax
mov TickCount,eax
'--------------------
mov ax,&H0204
mov bx,&H1c
int &h31
mov OldHandler,edx
'--------------------
mov ax,&H0205
mov bx,&H1c
lds edx,SaveTick
int &H31
jnc HookExit
mov TickCount,eax
jmp HookExit
'--------------------
SaveTick:
mov eax,TickCount
inc eax
mov TickCount,eax
iret
HookExit:
end asm
END SUB
Of course it doesnt work. (otherwise I wouldnt ask the question)
Do I need to issue an IRET, or do I need to return to the original handler, and how ?
Regards
PS. I hate the way it cant handle tabs in code on this site.
this looks a bit better
mov dssave,ds ;you will need a value for ds in the timer interrupt. Must be accessible with CS
mov ax,&H0204
mov bx,&H1c
int &h31
mov OldHandler+0,edx
mov OldHandler+4,cx ;you will get int vector in CX:EDX!
'--------------------
mov ax,&H0205
mov bx,&H1c
; lds edx,SaveTick ;dont use ds:edx, use CX:EDX!
mov cx,cs
mov edx, offset SaveTick
int &H31
jnc HookExit
xor eax, eax
mov TickCount,eax
jmp HookExit
'--------------------
SaveTick:
push eax ;save all registers which are modified!
push ds
mov ds, cs:[dssave]
mov eax,TickCount
inc eax
mov TickCount,eax
pop ds
pop eax
iretD ;use IRETD
Gustav
Many thanks for that.
That works just great, but now I have to experiment and understand why it works.
Regards
Dinosaur,
I wonder just how Gustav's solution is not 16 bit code? And why it should go outside of this forum?
My goal was to help you get an acceptable solution. But we have not address the FreeBasic problem yet. But that was not the problem at hand.
Regards, P1 :8)
P1
Your intention was appreciated, all I wanted was a solution, and I got it. :U
I guess if FreeBasic runs in protected mode, my interpretation was that it was not a 16 bit problem.
Gustav's solution may be, but in my mind it was a 32 bit problem.(blame my mother)
But hey, problem solved, thanks to you guys.
Regards
Hi all
Have converted my int hook routine for the keyboard, but although my flag is being incremented, there are
no keys (in basic). In the 16 bit version it worked nicely.
Is this hook expecting me to read the key during the int.?
Is the key being thrown away by the original handler.?
SUB HookKbdInt
asm
mov Kbdds,ds 'get a copy of current ds
mov ax,&H0204 'get addr of current handler
mov bx,&H09 'for KeyBrd
int &h31 'call ptotected mode int.
mov OldKbdInt+0,edx 'and save addr as OldKbdInt
mov OldKbdInt+4,cx
'--------------------
mov ax,&H0205 'assign an extra handler
mov bx,&H09 'for the Kbd
mov cx,cs
mov edx, offset SetKbdFlag 'offset of label where we
int &H31 'want the int to go
jnc KbdExit 'if no error jump to exit
mov KbdFlag,eax 'otherwise use it as err store.
jmp KbdExit 'get out by jumping over int routine.
'--------------------
SetKbdFlag:
push eax 'save all registers which are modified!
push ds
xor eax,eax
mov ds, cs:[Kbdds] 'set it to segment of our variable.
mov ax,KbdFlag
inc ax 'increment keyboard flag
mov KbdFlag,ax
pop ds 'restore ds of other handler.
pop eax 'restore registers
iretD 'and return to old handler.
KbdExit:
end asm
END SUB
When I press a key, the KbdFlag increments to 1.
Then using a basic statement
K$ = Inkey$
K$ is blank.
What am I doing wrong ?
Also I have written UnHook code.
SUB UnHookTickInt
asm
'----------
push eax
push ebx
push ecx
push edx
'----------
mov ax,&H0205 'assign new handler
mov bx,&H1c 'for Timer Tick.
mov edx,OldTickInt+0 'restore addr
mov cx,OldTickInt+4
int &H31
jnc UnTickExit 'if no error jump to exit
mov TickCount,eax 'otherwise use it as err store.
UnTickExit:
pop edx
pop ecx
pop ebx
pop eax
end asm
END SUB
It works correctly, but there is a gnawing feeling that I am simply hooking the old interupt onto the old interupt. ?
Also, if I have incorrectly intrepeted gustav's code with the comments, I would love it to be corrected.
Regards
> Is this hook expecting me to read the key during the int.?
Yes. Unlike int 1Ch, which is a software interrupt, int 9 is a hardware interrupt routine.
So either you must handle the keyboard (and PIC) - or just jmp to the old handler:
push eax 'save all registers which are modified!
push ds
xor eax,eax
mov ds, cs:[Kbdds] 'set it to segment of our variable.
mov ax,KbdFlag
inc ax 'increment keyboard flag
mov KbdFlag,ax
pop ds
pop eax 'restore registers
jmp fword ptr cs:[OldKbdInt]
Hi all
Just an update
For some reason FreeBasic would only work with
ljmp cs:[OldKbdInt]
which appears like AT&T syntax.
Anyhow thanks for all your help.
Regards