I replied once with some code, but it seems you didn't see it, so I'm   
   replying again.   
      
   It was thus said that the Great Paul Edwards    
   once stated:   
   >   
   > And now it is working, with the simple design.   
   >   
   > I will look into refinements now that the basics are working.   
   >   
   > static void writecomm(int port, int ch)   
   > {   
    ...   
      
   > old1 = G_intloc[(intno + 0xb0) * 2];   
   > old2 = G_intloc[(intno + 0xb0) * 2 + 1];   
   > intaddr = (unsigned long)hltinthit;   
      
    ...   
      
   > intdesc1 = (0x8 << 16) | (intaddr & 0xffff);   
   > intdesc2 = (intaddr & 0xffff0000)   
   > | (1 << 15)   
   > | (0 << 13)   
   > | (0x0e << 8);   
   > G_intloc[(intno + 0xb0) * 2] = intdesc1;   
   > G_intloc[(intno + 0xb0) * 2 + 1] = intdesc2;   
      
    ...   
      
   > G_intloc[(intno + 0xb0) * 2] = old1;   
   > G_intloc[(intno + 0xb0) * 2 + 1] = old2;   
      
    ...   
      
   > }   
      
    Why are you installing, then uninstalling, the interrupt handler for each   
   character? And I think you are making this out to be more complicated that   
   it should be. As I wrote before, the interrupt handler for the UART can be   
   as simple as:   
      
   uart_irq_handler:   
    push ax ; or eax if 32-bit   
    mov al,20h ; sent end-of-interrupt to 8259 PIC   
    out 20h,al   
    pop ax   
    iret   
      
    That's it. No mucking with return addresses, or CLI/STI instructions or   
   anything like that. Let the interrupt happen, and inform the 8259 it's been   
   handled. Set the vector once, and be done with it.   
      
    And the code to transmit the character, which assumes the UART has been   
   initialized with the baud rate and bit settings:   
      
    ; assume character to transmit is in AL   
    ; also assume the transmitter register   
    ; is empty   
      
    mov dx,[port] ; get port address   
    out dx,al ; send the character   
    inc dx ; point to interrupt enable register   
    in al,dx ; read current setting   
    or al,2 ; set transmitter empty IRQ   
    out dx,al ; tell UART   
    inc dx ; point to interrupt ID register   
      
   pause:   
      
    hlt ; halt CPU   
      
    ; read interrupt ID reg; this also clears the IRQ on the serial chip   
    ; and checks to see if we're the cause of the IRQ, and not something   
    ; else like the keyboard.   
      
    in al,dx ; read UART interrupt register   
    and al,0eh ; isolate source of interrupt bits   
    cmp al,2 ; is it the transmitter empty IRQ?   
    bne pause ; if not, keep waiting   
    dec dx ; point to interrupt enable register   
    in al,dx ; read current setting   
    and al,0FDh ; disable transmit empty IRQ   
    out dx,al   
      
    ; and we're done with transmitting the character   
      
    You need to tell both the 8259 and the UART that the interrupt has been   
   handled.   
      
    -spc   
      
   --- SoupGate-Win32 v1.05   
    * Origin: you cannot sedate... all the things you hate (1:229/2)   
|