law@janus.Berkeley.EDU (Katherina Law) (12/09/89)
Hi, netlanders, I have just modified an assembly program from a book. The program is to define its own interrupt driver for the serial port controller, reads data in and stuff it into the keyboard buffer. The problem I have now is I couldn't get through the port enabling part. I have no problem with it in C. Right now it just hungs the system. When I trace through it in debug, it will go as far as to the "in" statement in asc_enb, but once that is executed and I cannot quit out of debug, I'll get memory allocation error. Please help, right now I am just too blind to see anything I am doing?! Many thanks in advance!! The following is my program: DOSSEG .MODEL SMALL low_mem SEGMENT AT 0000h buffer_head equ 41ah buffer_tail equ 41ch low_mem ENDS pic_mask equ 21h ;port address, 8259 mask register pic_eoi equ 20h ;port address, 8259 EOI instr. comm_data equ 03f8h ;COM1 comm_ier equ 03f9h comm_lcr equ 03fbh comm_mcr equ 03fch comm_stat equ 03fdh com_int equ 0ch int_mask equ 10h ;Mask for 8259, COM1 is IRQ4. .CODE ORG 0h intc_offs dw 0 ;original contents of Int 0Ch intc_seg dw 0 ;service vector ascenb proc far call asc_enb ;enable interrupt again: mov ah,01h ;check keyboard int 16h jz again ;exit if key is pressed call asc_dsb mov ax,4c00h int 21h ascenb endp asc_enb proc near push bx push es mov ah,35h ;get current address of asynch mov al,com_int ;port's interrupt handler int 21h ;ES:BX = addr mov intc_seg,es ;save segment mov intc_offs,bx ;save offset mov dx,offset asc_int mov ah,25h ;set address of new handler mov al,com_int int 21h mov dx,comm_lcr ;9600, 1 stop, 7 bits mov al,09ah out dx,al mov dx,comm_data mov al,0ch out dx,al mov dx,comm_mcr mov al,00h out dx,al mov dx,comm_mcr ;modem controller DTR & OUT2 mov al,0bh out dx,al mov dx,comm_lcr mov al,01ah out dx,al mov dx,comm_ier ;interrupt enable register mov al,1 ;on asynch controller out dx,al in al,pic_mask ;read current 8259A int. mask. and al,not int_mask ;reset mask for this COM port. out pic_mask,al ;write back 8259A int. mask. pop es pop bx ret asc_enb endp asc_int proc far ;interrupt service for asynch controller sti ;turn interrupts back on. push ax ;save all registers. push bx push dx push ds ;save and go to low mem mov ax,cs mov ds,ax mov dx,comm_data in al,dx ;read this character. mov dl,al push ds cli ;clear interrupts for pnter. mov ax,low_mem mov ds,ax ;get keyboard buffer addr mov di,buffer_tail mov bx,ds:[di] add bx,400h mov byte ptr [bx],dl ;put in keyboard buffer add WORD PTR[di],2h cmp WORD PTR[di],03eh jne buffit mov WORD PTR[di],01eh buffit: sti ;turn interrupts back on. pop ds mov al,20h ;send EOI to 8259A. out pic_eoi,al pop ds ;restore all registers pop dx pop bx pop ax iret ;exit handler. asc_int endp asc_dsb proc near ;disable interrupt and release service vector in al,pic_mask ;read current 8259A int. mask. or al,int_mask ;set mask for this COM port. out pic_mask,al ;write int. mask back to 8259A. push ds mov dx,intc_offs ;saved offset mov ds,intc_seg ;saved segment mov ah,25h ;restore address of original mov al,com_int ;com port interrupt handler. int 21h pop ds ret asc_dsb endp END