| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176 |
- .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
|