Практика критерий истины.
Вот маленькая програмка.
отправляет строку АТ комманд модему и принимает ответ
cmd_str - АТ команды для модема
можно пробовать разные варианты
мдем подлючен к сом1 прерывание по дефолту
запускать можно в WIN и в DOS но в WIN результаты могут отличаться
в конце дает статистику сколько байт отправлено и сколько THR_пуст прерываний было
FIFO отключен специально
0х0а в конце АТ команды используется как терминатор строки для
функции send
include 'proc32.inc'
format MZ
heap 0
stack 8000h
entry main:start
THR equ 0x3f8 ;0x2F8
IER equ 0x3f9 ;0x2F9
IIR equ 0x3fa ;0x2Fa
LCR equ 0x3FB ;0x2FB
MCR equ 0x3FC ;0x2FC
IRQ_VEC equ 0x0C ;0x0B
RATE equ 12; 9600 bps
IDLE equ 0;
TRANSMIT equ 1;
segment main use16
use16
start:
mov ax,_data
mov ds, ax
mov es, ax
mov ss,ax
mov sp, 0x2000
mov bp, sp
mov dx,_logo
mov ah,9
int 21h
call disable_uart_intr
call disable_FIFO
call set_mode
lea ax, [inp_buffer]
mov [inp_ptr], ax
call set_handler
call enable_uart_intr
call enable_com_irq
lea ax, [inp_buffer]
mov [inp_ptr], ax
xor ax, ax
mov [inp_count], ax
mov [out_count], ax
mov [trhe_count], ax
lea ax, [cmd_str]
call send_str
mov dx, _trans
mov ah,9
int 21h
mov dx, cmd_str
mov ah,9
int 21h
mov dx, _rec
mov ah,9
int 21h
mov dx, _anykey
mov ah,9
int 21h
mov ah, 0
int 16h
call restore_handler
mov dx, _msg_rec
mov ah,9
int 21h
mov dx, inp_buffer
mov ah,9
int 21h
mov dx, _t_bytes
mov ah,9
int 21h
mov di, inp_buffer
mov bx, [out_count]
call word2str
mov dx, inp_buffer
mov ah,9
int 21h
mov dx, _msg_trhe
mov ah,9
int 21h
mov di, inp_buffer
mov bx, [trhe_count]
call word2str
mov dx, inp_buffer
mov ah,9
int 21h
mov ah,4ch
int 21h
align 4
proc disable_uart_intr
mov edx, IER
xor eax,eax
out dx, al
ret
endp
align 4
proc enable_com_irq
cli
in al, 21h
and al, 011100111b ;размаскируем irq3 и irq4
out 21h, al
sti
ret
endp
align 4
proc enable_uart_intr
mov dx, IER
mov ax, 0x03 ;приемник полон передатчик пуст
out dx, al
ret
endp
proc set_mode
mov dx, LCR
in al, dx
or al, 80h
out dx, al
mov dx, THR
mov al, RATE
out dx, al
inc dx
xor al, al
out dx, al
mov dx, LCR
mov al, 3
out dx, al
mov dx, MCR
mov al,0bh
out dx, al
ret
endp
proc set_handler
push es
mov ax, 0
mov es, ax
mov bx, IRQ_VEC
shl bx, 2
mov ax, [es:bx]
mov [old_offset], ax
mov ax, [es:bx+2]
mov [old_seg], ax
cli
lea ax, [com_handler]
mov [es:bx], ax
mov ax, cs
mov [es:bx+2], ax
sti
pop es
ret
endp
proc restore_handler
push es
mov ax, 0
mov es, ax
mov bx, 0x30
cli
mov ax, [old_offset]
mov [es:bx], ax
mov ax, [old_seg]
mov [es:bx+2], ax
sti
pop es
ret
endp
align 4
proc send_str
mov [out_ptr], ax
mov [out_count], 0
mov [mode], TRANSMIT
mov si, ax
mov al, [si]
mov dx, THR
out dx, al
sti
.l1: cmp [mode], TRANSMIT ;надо вставить проверку на таймаут
jnz .l2
hlt
jmp .l1
.l2:
ret
endp
align 4
proc send
add [trhe_count], 1
cmp [mode], TRANSMIT
jne .exit
mov si, [out_ptr]
add si, 1
mov [out_ptr], si
add [out_count], 1
mov al, [si]
cmp al, 0ah
jz .trans_end
mov dx, THR
out dx, al
.exit:
ret
.trans_end:
mov [mode], IDLE
ret
endp
align 4
proc recieve
mov si,[inp_ptr]
mov dx, THR
in al, dx
mov [si], al
add [inp_ptr], 1
add [inp_count], 1
ret
endp
align 4
proc com_handler
cli
pusha
push ds
push es
mov ax,_data
mov ds, ax
xor ax, ax
mov dx, IIR
in al, dx
mov [iir_save], al
and ax, 0110b
cmp ax, 2 ;передатчик пуст
jnz .m1
call send
jmp .l2
.m1:
cmp ax, 4 ; приемник заполнен
jnz .l2
call recieve
jmp .l2
.l2:
mov al, 20h
out 20h, al
pop es
pop ds
popa
sti
iretw
endp
align 4
proc disable_FIFO
mov dx, IIR
xor al, al
out dx, al
ret
endp
proc word2str
rol bx, 4
call conv
rol bx, 4
call conv
rol bx, 4
call conv
rol bx, 4
call conv
mov byte [di], 24h
ret
endp
proc conv
mov al, bl
and ax, 0x0f
aaa
adc al, 0x30
db 0xd5
db 0x10
mov [di], al
add di, 1
ret
endp
segment _data use16
align 4
old_offset dw ?
old_seg dw ?
row dw 0
mode dd 0
out_ptr dw 0
out_count dw 0
iir_save db 0
trhe_count dw 0
inp_ptr dw 0
inp_count dw 0
align 4
inp_buffer dd 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
dd 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,24000000h
_logo db ' init uart... ',0Dh, 0Ah,24h
cmd_str db 'AT', 0Dh, 0ah,24h
;cmd_str db 'ATQ0V1E0', 0dh, 0ah , 24h
;cmd_str db 'AT+GMM', 0dh, 0ah, 24h
_trans db 0dh, 0ah,' transmit command $'
_rec db 0dh, 0ah, ' recieve data... please wait, then$'
_anykey db 0dh, 0ah, ' press any key...$'
_msg_rec db 0dh, 0ah, ' recieve message',0dh,0ah, 24h
_t_bytes db 0dh, 0ah, ' bytes transmitted $'
_msg_trhe db 0dh, 0ah, ' total trhe interrupts $'