Trouble hooking int 1C

I need a procedure, that will increase a double word in the data seggment, run at least 18 times per second. I tried to run this program in win98 and it just locks or reboots the computer.

I've tryed many different aproaches so I can't post any code.
It seems like the routines that work with other interrupts just won't work with the timer.

Any suggestions?

Comments

  • what does your own Int1C exactly? just inc DWORD PTR cs:[xxx]?does you return with a simple 'iret' or do you call the original Int1C?And last,you should disable interrupts with 'cli' when entering your code and allow them before leaving your code and take care that your code has been finished his task before a new timer-tick is generated.
  • : what does your own Int1C exactly? just inc DWORD PTR cs:[xxx]?does you return with a simple 'iret' or do you call the original Int1C?And last,you should disable interrupts with 'cli' when entering your code and allow them before leaving your code and take care that your code has been finished his task before a new timer-tick is generated.
    :

    I feel stupid right now. Just found out what the bug was. I saved the segment and offset of the original interrupt before I even put the right value in DS. Then when resetting the interrupt vector I put the segment of the old interrupt in DS before retriveing the offset from the data segment... But you still helped me by reminding me about iret and cli, so thnx.
  • I'm using it in a pure DOS program running in a win95 DOS-prompt, but win95 doesn't like it when I play around with the PIT. What would be the safest way to call an interrupt like 1C every 1ms?
  • You might try this Nasm INT 1Ch hook include file?
    It's probably fraut with errors, but it ran ok for me?
    Bitdog
    [code]
    ; ========================= INT1C.INC =========================
    ; Procedures INT1Con & INT1Coff installs & uninstalls the INT1C routine below.
    ; It hooks INTerrupt 1Ch which is called 18.2065 times per second.
    ; Copy this to your working directory with your .ASM file, use a local include
    ;%include "INT1C.inc" ;then alter the timer routine at the bottom to suit.
    ;
    ;%include "INT1C.inc" ;(example code)
    ; CALL INT1Con
    ;your program code here
    ; CALL INT1Coff
    ;exit your program here
    ;
    ;Note: if segment register GS is set to 0 at your programs startup,
    ; you can access the vector table & bios areas with immediates easily.
    ; MOV AL,[GS:0449h] ; get video mode in AL, type stuff.
    ; MOV EAX,[GS:21h*4] ; get address of INT 21h from vector table.
    ; MOV WORD [GS:0450h],0102h ; move cursor row1, col2, page0.

    align 16
    INT1Con: ; Hook INT 1Ch = 28
    PUSH CS ; CALL WITH seg reg GS=0 (set GS=0 at program start?)
    POP DS ; DS=CS
    CLI ; disable interrupts
    MOV AX,[GS:0070h] ; get INT 1Ch adr in vector table (= INT# * 4)
    MOV WORD [OFF1C],AX ; store offset
    MOV AX,[GS:0072h]
    MOV WORD [SEG1C],AX ; store segment

    MOV WORD [GS:0070h],INT1C ; install our INT1C routine in vector table
    MOV AX,CS
    MOV WORD [GS:0072h],AX
    STI ; enable interrupts
    RET ; returns DS = CS (destroys AX)

    ; These bytes can be updated by the INT1C routine below
    ; Then your program can access & reset the bytes.
    IC00 DB 0 ; Flags byte (bit info below)
    IC01 DB 0 ; Extra byte here
    IC02 DB 0 ; Extra bytes or words for INT1C here
    IC03 DB 0
    IC04 DB 0 ;word = even offset here
    IC05 DB 0 ;byte = odd offset here
    IC06 DB 0
    IC07 DB 0
    IC08 DB 0
    IC09 DB 0

    ; Flags byte bit info (make up your own flag info)
    ; 7 = 1 if INT1C is active (skip getting data if it's active.)
    ; 6 = 1 if
    ; 5 = 1 if
    ; 4 = 1 if
    ; 3 = 1 if bits 2-0 rolled over
    ; 2-0 = 3 bits holds a value 0-7 incremented ptr to IC10-IC16 below?

    align 16
    INT1Coff: ; UnHook INT 1Ch = 28
    PUSH CS ; CALL WITH seg reg GS=0 is a must
    POP DS
    CLI ; disable interrupts
    MOV AX,[OFF1C] ; restore INT 1Ch address in vector table
    MOV WORD [GS:0070h],AX ; restore offset
    MOV AX,[SEG1C]
    MOV WORD [GS:0072h],AX ; restore segment
    STI ; enable interrupts
    RET ; returns DS = CS (destroys AX)

    IC10 DB 0 ;byte = odd offset here
    IC11 DB 0
    IC12 DB 0
    IC13 DB 0
    IC14 DB 0
    IC15 DB 0
    IC16 DB 0

    ; INT 1Ch routine is automatically called at 18.2065hz with the interrupts off.
    ; Preserve/restore any registers you use.
    ; Keep the INT1C routine small. (update your programs variables (bytes))
    ; DOS interrupts (INT 21h) won't work in INT1C, but some BIOS interrupts do.
    ; EOI (End Of Interrupt)=(OUT 20h,20h) is not needed in the INT1C routine.
    ; KBDOFFm turns off keyboard interrupts at the beginning of your program.
    ; KBDONm turns them back on at the end of your program. (See STDMAC.MAC)
    ; This timer could be used to check the keyboard IN AL,60h type stuff.

    align 16
    INT1C: PUSHAW ; PUSH AX,CX,DX,BX,SP,BP,SI,DI (no segment regs pushed)
    OR BYTE [CS:IC00],10000000b ; set bit-7, INT1C is active

    INC WORD [CS:IC02] ; write your routine here (this uses byte IC03 too)

    ICbye: AND BYTE [CS:IC00],01111111b ; clear bit-7, INT1C is inactive
    POPAW ; POP DI,SI,BP,SP ignored,BX,DX,CX,AX
    DB 0xEA ; JMP xxxx:xxxx (immediate)
    OFF1C DW 0 ; The original INT 1Ch PROC is just an IRET at F000:FF53h
    SEG1C DW 0 ; so DB 0xEA JMP im can be IRET = 207 = 0xCF = NO CHAINING.
    [/code]

  • : I'm using it in a pure DOS program running in a win95 DOS-prompt, but win95 doesn't like it when I play around with the PIT. What would be the safest way to call an interrupt like 1C every 1ms?
    :
    [green]
    Look for pctim003.zip on www.google.com or right here.
    Click on Advanced Search to the left, choose files, enter the string
    pctim003.zip & download ? if it's there?
    It covers lots of timeing stuff, PIC, PIT, sound blaster, INT hooking like your INT 1Ch hook stuff.
    You mentioned PIT and Win95 troubles, but using PIC & PIT by checking which channels are available and other stats, then setting up the APPROPERATE timer properly, is fairly intricate & not something to play around with. A good source of info for that stuff is Ralf Browns INTER61D.ZIP and look for PORTS.A files.
    A PIT or PIT search should get you to port 20h, 40h, 43h etc.
    Gud Luk
    Bitdog
    [/green]

  • [b][red]This message was edited by AsmGuru62 at 2003-10-5 8:7:26[/red][/b][hr]
    [b][red]This message was edited by AsmGuru62 at 2003-10-5 8:7:9[/red][/b][hr]
    : I need a procedure, that will increase a double word in the data seggment, run at least 18 times per second. I tried to run this program in win98 and it just locks or reboots the computer.
    :
    : I've tryed many different aproaches so I can't post any code.
    : It seems like the routines that work with other interrupts just won't work with the timer.
    :
    : Any suggestions?
    :
    [blue]The question is - why would you need such a procedure? The reason I am asking is that DOS [b][italic]ALREADY HAS[/italic][/b] the DWORD at 0x0000:0x046C which is a mirror of the counter you are looking for. So, to time DOS events - you just read this value into the 32-bit register and that is it. To use 32-bit registers - specify [b].386[/b] at the top of your source file.[/blue]




  • Why would you need a procedure that increments a Dword
    when there already is an incrementing DWORD at 0x0000:0x046C

    [green]
    The advantage is having an incrementing Dword in your program that
    you can zero out at any time, makes it real easy to wait a certian amount of time.
    Multiple Dwords incrementing allows a couple wait/watch events to be
    easily timed, and with zeroing out a Dword, it takes 16? days to flip
    from the time it was zeroed, so you program doesn't have to worry
    about being run just before midnight where the 0000:046Ch Dword
    would be flipped at midnight.
    AND you can write what you want in your INT so some tasks can be automated.
    Port get key & write to buffer in your program.
    Gives you a keyboard buffer that doesn't slow down your program, or beep when it's full.
    Hooking INT 1Ch is kinda easy to do and doesn't add much code size or interfere with the computers general operations.
    Infact, INT 1Ch is a dummy routine that simply has an IRET in it
    and it's whole intention was for programmers to use.

    BUT, then on the other hand, I haven't worked it into any of my programs yet either :)

    Bitdog
    [/green]

Sign In or Register to comment.

Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Categories