.286 .model small .code org 100h ; UART Registers SER_RBF EQU 0 ; Буфер чтения SER_THR EQU 0 ; буфер записи SER_IER EQU 1 ; регистр разрешения прерываний SER_IIR EQU 2 ; рег. идентификации прерываний SER_LCR EQU 3 ; рег. управл. данных и разрешен. загрузки делителя SER_MCR EQU 4 ; рег. управл. модемом SER_LSR EQU 5 ; рег. состояния линии SER_MSR EQU 6 ; рег. сост. модема SER_DLL EQU 0 ; рег. младш. байт делителя SER_DLH EQU 1 ; рег. старш. байт делителя ; Registers Bit masks SER_BAUD_1200 EQU 96 ; делители для различных скоростей SER_BAUD_2400 EQU 48 SER_BAUD_9600 EQU 12 SER_BAUD_19200 EQU 6 SER_BAUD_38400 EQU 3 SER_BAUD_57600 EQU 2 SER_GP02 EQU 8 ; разрешение прерываний COM1 EQU 3f8h ; Начальные порты комов COM2 EQU 2f8h ; SER_STOP_1 EQU 0 ; стоп-бит на символ SER_STOP_2 EQU 4 SER_BITS_5 EQU 0 ; х зачащих бит на символ SER_BITS_6 EQU 1 SER_BITS_7 EQU 2 SER_BITS_8 EQU 3 SER_PARITY_NONE EQU 0 ; контроль четности SER_PARITY_ODD EQU 8 SER_PARITY_EVEN EQU 24 SER_DIV_LATCH_ON EQU 128 ; исп при загрузке делителя PIC_IMR EQU 21h ; маска для регистра прерываний PIC_ICR EQU 20h ; маска для контроллера прерываний INT_SER_PORT_0 EQU 0Ch ; для управления прерыван. COM1 & COM3 INT_SER_PORT_1 EQU 0Bh ; для управления прерыван. COM2 & COM4 ; Current setting(for COM1), change them ;------------------------------- PORT EQU 3f8h INT_SER_PORT EQU 0Ch INT_MASK EQU 0EFh ; (0F7h - for COM2-4) CONFIG EQU 3 ; (PARITY_NONE|SER_BITS_8|SER_STOP_1) SER_BAUD EQU 3 ; 38400 BUF_LEN EQU 1024 ;------------------------------- start: ; Open sereal port ;---------------------------- ; Set port speed mov dx, PORT+SER_LCR ;------- mov al, SER_DIV_LATCH_ON ; разрешаем загрузку делителя out dx, al ;------- mov dx, PORT+SER_DLL ;------- mov al, SER_BAUD ; посылаем младш байт делителя out dx, al ;------- mov dx, PORT+SER_DLH ;------- mov al, 0 ; посылаем старш байт делителя out dx, al ;------- mov dx, PORT+SER_LCR ;------- mov al, CONFIG ; уст конфигурацию порта out dx, al ;------- mov dx, PORT+SER_MCR ;------- mov al, SER_GP02 ; out dx, al ; Разрешаем mov dx, PORT+SER_IER ; прерывания mov al, 1 ; out dx, al ;------- mov ah, 35h ;----------- mov al, INT_SER_PORT ; Get Old int 21h ; Vector mov old_vec_seg, es ; PORT COM1 mov old_vec_offs, bx ;----------- mov ah, 25h ;----------- mov al, INT_SER_PORT ; Set NEW mov dx, offset Serial_ISR ; Vector int 21h ;----------- in al, PIC_IMR ; Старые биты контроллера прерываний mov old_int_mask, al ; and al, INT_MASK out PIC_IMR, al ; разрешаем прерывание COM1 ;----------------------------------------------------------------- mov ah, 08h int 21h ;------------------------------------ ; Close port ; mov dx, PORT+SER_MCR ;------- mov al, 0 ; out dx, al ; Запрещаем mov dx, PORT+SER_IER ; прерывания mov al, 0 ; out dx, al ;------- mov al, old_int_mask ; out PIC_IMR, al ; Уст старые настройки контроллера прерыван mov ah, 25h ;----------- mov al, INT_SER_PORT ; Set OLD mov dx, old_vec_offs ; Vector mov ds, old_vec_seg ; Vector int 21h ;----------- int 20h ; Interrupt vector Serial_ISR: pusha mov ser_lock, 1 mov dx, PORT+SER_RBF in al, dx inc pos_wrt cmp pos_wrt, BUF_LEN-1 jna OK mov pos_wrt, 0 OK: mov di, pos_wrt mov buffer[di], al inc char_ready mov al, 20h cli out PIC_ICR, al mov ser_lock, 0 popa iret Ser_Write proc near ; Ser_Write(ch: char) push bp mov bp, sp CHAR EQU byte ptr [bp+4] pusha mov dx, PORT+SER_LSR WT: in al, dx and al, 20h jz WT mov dx, PORT+SER_THR mov al, CHAR cli out dx, al sti popa pop bp ret 2 endp old_vec_offs dw 0 old_vec_seg dw 0 old_int_mask db 0 ser_lock db 0 pos_wrt dw -1 pos_rd dw -1 char_ready db 0 buffer db BUF_LEN dup (?) end start