Search code examples
assemblyx86x86-16masm

The interrupt signal is transmitted only once by the RTC


I have a small problem with the RTC + CMOS (Real time clock), more precisely the Motorola MC146818A. The task performed by the program is to display the letter "A" at regular time intervals equal to 1s. so I set the bits of register A and register B correctly, the fact is that the subroutine I intercepted is activated only once and I don't understand why. Here is the code:

This is the module of the function:

_text SEGMENT PARA PUBLIC 
    
  farjmp  09C0h, _start

  times    db     0h 

 mount_rtc_subroutine PROC NEAR 

    push    ax
    push    es 

    xor     ax, ax 
    mov     es, ax 

    ;I mask the line of break n0 of the slave PIC
    in      al, 0A1h 
    or      al, 01h 
    out     0A1h, al

    ;memorize in the IVT the SEG: OFF components of the 
    ;first instruction of my service subroutine
    mov     WORD PTR es:[1C0h], _rtc_subroutine 
    mov     WORD PTR es:[1C2h], 09C0h 

    mov     al, 0Ah 
    out     70h, al 
    mov     al, 2Fh 
    out     71h, al

    mov     al, 0Bh 
    out     70h, al 
    mov     al,  42h 
    out     71h, al 

    ;active the break line n0 of the slave PIC 
    in      al, 0A1h 
    and     al, 0FEh
    out     0A1h, al

    pop     es 
    pop     ax 
    ret

 mount_rtc_subroutine ENDP 

_rtc_subroutine:
   push    ax
   push    bx

   mov     bx, OFFSET times 

   cmp     BYTE PTR [bx], 0h 
   jne     _write

   inc    BYTE PTR [bx]
   jmp     _EOI 

   _write: mov     ax, 0F41h 
           stosw
           mov    WORD PTR [bx], 0h

   _EOI: mov     al, 20h 
         out     0A0h, al 
         out     20h, al 

   pop     bx
   pop     ax
   iret    

_text ENDS 

Main module:

farjmp MACRO segm, off

   db  0EAh
   dw  off
   dw  segm

ENDM 

INCLUDE rtc_sub

_text SEGMENT PARA PUBLIC 

_start:
    mov    ax, 09C0h  
    mov    ds, ax 
    mov    ss, ax
    mov    sp, 0FFFFh 
    mov    ax, 0B800h
    mov    es, ax 

    call   mount_rtc_subroutine

    jmp $

_text ENDS 
     END _start

I don't find any problem and yet there is. What do you think is the problem?


Solution

  • The problem is the failure to read the register C of the RTC at the end of the service subroutine, in this way the RTC is not allowed to transmit any stealthy interrupt signal, with the consequent non-activation of the interrupt manager.

    Add this intrsuction:

    mov  al, 0Ch
    out  70h, al
    in   al, 71h