News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

Timer in DPMI app

Started by Gustav, October 04, 2005, 01:17:24 PM

Previous topic - Next topic

Gustav


Hello,

I'm playing with a dos extended application which uses the RTC timer at IRQ 8.

This is the test app, which displays a counter at the upper right corner of the screen. The timer usually has a frequency of 1024 Hz.

a side note: the code runs in a true-flat 32bit memory model!



;***   test irq 8 ***

        .386
        .Model FLAT, stdcall

        .data
       
oldint70    df 0
csalias     dw 0
dwScrnPos   dd 0
bMask       db 0
bStatus     db 0

        .code

; increment the screen counter

IncScr  proc    uses ecx ebx
        mov     cl,8
        mov     ebx,cs:[dwScrnPos]
nextchar:
        inc     byte ptr [ebx]
        cmp     byte ptr [ebx],'9'
        jbe     done
        mov     byte ptr [ebx],'0'
        dec     ebx
        dec     ebx
        dec     cl
        jnz     nextchar
done:
        ret
IncScr  endp

; irq 8 handler

myint70 proc

        push    ds
        mov     ds,cs:[csalias]
        call    IncScr
        pop     ds
        db 2eh                             ;CS prefix
        jmp     fword ptr oldint70
       
myint70 endp

; init the screen counter

InitScr proc
        mov     eax,0B8000h
        add     eax,79*2
        mov     dwScrnPos,eax
        mov     cl,8
nextchar:
        mov     byte ptr ds:[eax],'0'
        dec     eax
        dec     eax
        dec     cl
        jnz     nextchar
        ret
InitScr endp


main    proc c

        mov     [csalias],ds
        call    InitScr
        mov     ax,0204h
        mov     bl,70h
        int     31h
        mov     dword ptr [oldint70+0],edx
        mov     word ptr [oldint70+4],cx
        mov     ax,0205h
        push    cs
        pop     ecx
        mov     edx, offset myint70
        int     31h
       
        in      al,0A1h
        mov     bMask, al
        and     al,not 1    ;unmask IRQ 8
        out     0A1h,al

        in      al,021h     ;unmask IRQ 2
        and     al,not 4
        out     021h,al
       
        cli
        mov     al,0Bh
        out     70h,al
        in      al,71h
        mov     bStatus, al
        or      al,40h
        out     71h, al
        sti
       

main_0:
        mov     ah,0
        int     16h
        cmp     ah,1        ;wait until ESC is pressed
        jnz     main_0
exit:
        cli
        mov     al,0Bh
        out     70h,al
        mov     al,bStatus
        out     71h, al
        sti
       
        mov     al,bMask
        out     0A1h,al
       
        mov     ax,0205h
        mov     bl,70h
        mov     cx, word ptr [oldint70+4]
        mov     edx, dword ptr [oldint70+0]
        int     31h
       
        mov     ah,4ch
        int     21h
        ret
main    endp

        END main


The problem is that it works only when launched the second - and any further - time. When running the first time the interrupt procedure is called only once, then the counter stops!

Any ideas why?







MichaelW

I don't know that this could cause the problem, but hardware interrupt handlers are generally supposed to preserve all registers, and yours is altering EAX and CL in the call to InitScr.

eschew obfuscation

Gustav


Hi,

InitScr is not called by the interrupt handler, just IncScr.

MichaelW

Sorry, too many distractions.

I think the problem is that csalias is defined in the data segment and the handler expects to find it in the code segment.

eschew obfuscation

Gustav

> I think the problem is that csalias is defined in the data segment and the handler expects to find it in the code segment.

the model is flat so using CS as segment prefix for accessing members in .DATA is valid. If this wouldn't work I would get GPFs.

But I found the error in the meantime. As it turned out one has to access the RTC ports (port 71h, index 0Ch) to reenable RTC interrupts. It is quite similiar to the keyboard, where one has to access port 60h to tell the keyboard device that the interrupt was handled.

And then, why did it work when launched the second time? That has to do with how the BIOS works. There is a built in timer software (int 15h, ax=86h), which comes in the way and which does read the RTC status port, but without further action it is sort of "one shot".




MichaelW

Quote
the model is flat so using CS as segment prefix for accessing members in .DATA is valid. If this wouldn't work I would get GPFs.
OK, but why the DS override in InitScr, and the CS override in IncScr?

I am curious how you are building this, and how it is being loaded.

eschew obfuscation

Gustav

> OK, but why the DS override in InitScr, and the CS override in IncScr?

they are both redundant, I copied some parts of the source from another app.

I use the hx dos extender, which supports PE file format natively.

I attached the binary, source and makefile


[attachment deleted by admin]

MichaelW

eschew obfuscation