I replied once with some code, but it seems you didn't see it, so I'm
replying again.
> 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