скачать рефераты
  RSS    

Меню

Быстрый поиск

скачать рефераты

скачать рефератыДипломная работа: Апаратно–програмний комплекс GSM-МТМ

DIV50 DW 2304

; поточний номер області даних порту

CURRENT_AREA DW AREA1

; область даних для кожного порту

AREA1 SP_TAB <0,1,INT_COM1,E_IRQ4,D_IRQ4,EOI4>; область даних COM1

AREA2 SP_TAB <0,2,INT_COM2,E_IRQ3,D_IRQ3,EOI3>; область даних COM2

AREA3 SP_TAB <0,3,INT_COM3,E_IRQ4,D_IRQ4,EOI4>; область даних COM3

AREA4 SP_TAB <0,4,INT_COM4,E_IRQ3,D_IRQ3,EOI3>; область даних COM4

_DATA ENDS

COM_TEXT SEGMENT PARA public 'CODE'

ASSUME cs:COM_TEXT,ds:DGROUP,es:NOTHING

public _select_port

public _save_com

public _install_com

public _restore_com

public _open_com

public _close_com

public _dtr_on

public _dtr_off

public _r_count

public _s_count

public _receive_com

public _send_com

public _break_com

public _com_errors

public _com_ring

; вибір активного порту

; [bp+6] - номер порту

_select_port PROC FAR

push bp

mov bp, sp

mov ax, [bp+6];одержуємо в ax аргумент функції

cmp al,1; установлений порт 1?

je port1; да

cmp al,2; установлений порт 2?

je port2; да

cmp al,3; установлений порт 3?

je port3; да

cmp al,4; установлений порт 4?

je port4; да

jmp set_carrent_area

port1:

mov ax,OFFSET DGROUP:AREA1; вибираємо область даних COM1

jmp short set_carrent_area

port2:

mov ax,OFFSET DGROUP:AREA2; вибираємо область даних COM2

jmp short set_carrent_area

port3:

mov ax,OFFSET DGROUP:AREA3; вибираємо область даних COM3

jmp short set_carrent_area

port4:

mov ax,OFFSET DGROUP:AREA4; вибираємо область даних COM4

set_carrent_area:

; записуємо в перемінної CURRENT_AREA зсув

; поточно області даних

mov CURRENT_AREA,ax

mov sp,bp

pop bp

ret

_select_port ENDP

;

; збереження поточного вектора COM переривання

_save_com  PROC FAR

push bp

mov bp,sp

push si

; записуємо в si покажчик на поточну область даних

mov si,CURRENT_AREA

push es

mov AREA1.int_hndlr,OFFSET int_hndlr1

mov AREA2.int_hndlr,OFFSET int_hndlr2

mov AREA3.int_hndlr,OFFSET int_hndlr3

mov AREA4.int_hndlr,OFFSET int_hndlr4

; зберігаємо старий вектор переривання

mov ah,35H

mov al,int_com[si]; номер переривання

int 21h

; записуємо в перемінні old_com_off і old_com_seg

; відповідно сегмент і зсув старого вектора переривання

mov old_com_off[si],bx

mov bx,es

mov old_com_seg[si],bx

pop es

pop si

mov sp,bp

pop bp

ret

_save_com  ENDP

; install_com: установити активний порт

; повертає в регістрі ax - 1 при успішній установці

; і 0 у випадку помилки

_install_com PROC FAR

push bp

mov bp,sp

push si

mov si,CURRENT_AREA

push es

cmp installed[si],1

jne go_install

jmp alredy_ok

; очищаємо лічильники помилок

go_install:

mov WORD PTR EOVFLOW[si],0; переповнення буфера передавача

mov WORD PTR EOVRUN[si],0; помилка переповнення при прийомі

mov WORD PTR EBREAK[si],0; виявлений запит на переривання

mov WORD PTR EFRAME[si],0; помилка синхронізації

mov WORD PTR EPARITY[si],0; помилка парності

mov WORD PTR EXMIT[si],0; помилка при передачі

mov WORD PTR EDSR[si],0; не отриманий сигнал DSR

mov WORD PTR ECTS[si],0; не отриманий сигнал CTS

; визначаємо базова адреса використовуваного COM порту

mov bx,BIOS_VAR

mov es,bx

ASSUME es:BIOS_VAR

cmp port[si],1; порт 1?

je adr_3F8

cmp port[si],2; порт 2?

je adr_2F8

cmp port[si],3; порт 3?

je adr_3E8

cmp port[si],4; порт 4?

je adr_2E8

int 20H

adr_3F8:

mov ax,3F8H

jmp cmp_bios

adr_2F8:

mov ax,2F8H

jmp cmp_bios

adr_3E8:

cmp rs232_base+4,0

je adr_3E8_A

mov ax,rs232_base+4

jmp cmp_bios

adr_3E8_A:

mov ax,3E8H

mov rs232_base+4,ax

jmp cmp_bios

adr_2E8:

cmp rs232_base+6,0

je adr_2E8_A

mov ax,rs232_base+6

jmp cmp_bios

adr_2E8_A:

mov ax,2E8H

mov rs232_base+6,ax

; перевіряємо чи існує визначена відповідна змінна

; BIOS

cmp_bios:

cmp ax,rs232_base

je set_reg_adr

cmp ax,rs232_base+2

je set_reg_adr

cmp ax,rs232_base+4

je set_reg_adr

cmp ax,rs232_base+6

jne bad_exit

set_reg_adr:

mov bx,DATREG

mov cx,7

set_next_reg_adr:

mov WORD PTR [si][bx],ax

inc ax

add bx,2

loop set_next_reg_adr

; установлюємо вектор переривання на наш оброблювач

mov AREA1.int_hndlr,OFFSET int_hndlr1

mov AREA2.int_hndlr,OFFSET int_hndlr2

mov AREA3.int_hndlr,OFFSET int_hndlr3

mov AREA4.int_hndlr,OFFSET int_hndlr4

mov ah,25H

mov al,int_com[si]; номер переривання

mov dx,OFFSET DGROUP:int_hndlr[si]

push ds

push cs

pop ds

int 21h

pop ds

; піднімаємо прапор - порт установлений

alredy_ok:

mov installed[si],1

pop es

; повертаємо 1

mov ax,1

pop si

mov sp,bp

pop bp

ret

; порт не встановлений

bad_exit:

mov installed[si],0

pop es

; повертаємо 0

mov ax,0

pop si

mov sp,bp

pop bp

ret

_install_com ENDP

; відновлення векторів переривань

_restore_com PROC FAR

push bp

mov bp,sp

push si

; відзначаємо COM порт як не активний

mov si,CURRENT_AREA

mov installed[si],0

; відновлюємо вектор переривання

mov ah,25H

mov al,int_com[si]

mov dx,old_com_off[si]

mov bx,old_com_seg[si]

push ds

mov ds,bx

int 21h

pop ds

pop si

mov sp,bp

pop bp

ret

_restore_com ENDP

; відкрити COM порт

; скидання буферів передавача і приймача,

; ініціалізація регістрів UART 8250

; дозвіл переривань від UART 8250

; (програмування контролера переривань)

; [bp+6] = швидкість обміну

; [bp+8] = спосіб з'єднання - M(Модем), D(Нуль-модем)

; [bp+10] = парність - N(ONE), O(DD), E(VEN), S(PACE), M(ARK)

; [bp+12] = кількість стопових бітів 1, 2

_open_com PROC FAR

push bp

mov bp,sp

push si

mov si,CURRENT_AREA

; забороняємо переривання

cli

mov ax,[bp+6]

mov baud_rate[si],ax

mov bh,[bp+8]

mov device_conn[si],bh

mov bl,[bp+10]

mov parity[si],bl

mov ch,[bp+12]

mov stop_bits[si],CH

; скидаємо буфери і покажчики

mov start_s_data[si],0

mov end_s_data[si],0

mov start_r_data[si],0

mov end_r_data[si],0

mov size_s_data[si],0

mov size_r_data[si],0

; чи перевіряємо установлений вже оброблювач переривань

test installed[si],1

jnz reset_uart

jmp exit_open

reset_uart:

; установлюємо регістри UART 8250

; скидаємо регістр керування модемом

mov al,0

mov dx,MCR[si]

out dx,al

jmp $+2

; скидаємо регістр стану лінії

mov dx,LSR[si]

in al,dx

jmp $+2

; скидаємо регістр даних

mov dx,DATREG[si]

in al,dx

jmp $+2

; скидаємо регістр стану модему

mov dx,MSR[si]

in al,dx

; визначаємо дільник частоти тактового генератора

mov ax,50

mul DIV50

div baud_rate[si]

mov bx,ax

; переключаємо регістир даних і регістр керування перериваннями

; для введення дільника частоти тактового генератора

mov dx,LCR[si]

mov al,80H

out dx,al

jmp $+2

; уводимо молодший байт дільника частоти тактового генератора

mov dx,WORD PTR DLL[si]

mov al,bl

out dx,al

jmp $+2

; уводимо старший байт дільника частоти тактового генератора

mov dx,WORD PTR DLH[si]

mov al,bh

out dx,al

jmp $+2

; визначаємо парність і кількість стоп-бітів

mov al,03H

cmp parity[si],'O'

jne next1

mov al,0ah

jmp short next3

next1:

cmp parity[si],'E'

jne next2

mov al,1ah

jmp short next3

next2:

cmp parity[si],'M'

jne next3

mov al,2ah

next3:

test stop_bits[si],2

jz stop1

or al,4

stop1:

mov dx,LCR[si]

out dx,al

; дозволяємо переривання для 8259 і 8250

; установлюємо регістр маски переривань щоб

; дозволити переривання від асинхронного порту

in al,IMR

and al,d_irq[si]

out IMR,al

; дозволяємо генерацію переривань при готовності прийнятих

; даних, по стані "BREAK" і помилково

mov dx,IER[si]

mov al,0Dh

out dx,al

jmp $+2

; установлюємо DTR, RTS, OUT2

mov dx,MCR[si]

mov al,0bh

out dx,al

exit_open:

sti

pop si

mov sp,bp

pop bp

ret

_open_com ENDP

; забороняємо переривання від асинхронного порту

_close_com PROC FAR

push bp

mov bp,sp

push si

mov si,CURRENT_AREA

test installed[si],1

jz exit_close

; забороняємо переривання UART 8250

mov dx,IER[si]

mov al,0

out dx,al

; маскуємо переривання від UART

mov dx,IMR

in al,dx

or al,e_irq[si]

jmp $+2

out dx,al

exit_close:

pop si

mov sp,bp

pop bp

ret

_close_com ENDP

;процедура повертає 1 якщо з МТМ надійшов дзвінок

_com_ring proc far

push bp

mov bp,sp

push si

mov si,CURRENT_AREA

test installed[si],1

jz exit_com_ring

xor ax,ax

mov al,BYTE PTR RING[si]

nop

mov RING[si],0

nop;

exit_com_ring:

pop si

mov sp,bp

pop bp

ret

_com_ring endp

; ДОПОМІЖНІ ФУНЦІЇ

; знімаємо сигнал DTR

_dtr_off       PROC FAR

push bp

mov bp,sp

push si

pushf

push ax

push dx

push si

mov si,CURRENT_AREA

test installed[si],1

jz exit_dtr_off

; установлюємо регістр керування модемом,

; скидаємо сигнали DTR і RTS

mov dx,MCR[si]

mov al,08H

out dx,al

exit_dtr_off:

pop si

pop dx

pop ax

popf

pop si

mov sp,bp

pop bp

ret

_dtr_off       ENDP

; установлюємо сигнал DTR

_dtr_on PROC FAR

push bp

mov bp,sp

push si

pushf

push ax

push dx

push si

mov si,CURRENT_AREA

test installed[si],1

jz exit_dtr_on

; установлюємо регістр керування модемом,

; установлюємо сигнали DTR, RTS, OUT2

mov dx,MCR[si]

mov al,0bh

out dx,al

exit_dtr_on:

pop si

pop dx

pop ax

popf

pop si

mov sp,bp

pop bp

ret

_dtr_on ENDP

;

; повертаємо в регістрі ax число байтів у регістрі приймача,

; а в регістрі dx загальний розмір буфера приймача

_r_count      PROC FAR

push bp

mov bp,sp

push si

pushf

push si

mov si,CURRENT_AREA

mov ax,0

mov dx,R_SIZE

test installed[si],1

jz exit_r_count

; записуємо в регістр ax число символів у буфері приймача

mov ax,size_r_data[si]

exit_r_count:

pop si

popf

pop si

mov sp,bp

pop bp

ret

_r_count      ENDP

; одержуємо черговий символ з буфера приймача,

; отриманий символ віддаляється з буфера

_receive_com        PROC FAR

push bp

mov bp,sp

push si

pushf

push bx

push si

mov si,CURRENT_AREA

mov ax,-1

test installed[si],1

jz exit_receive_com

; повертаємося якщо буфер приймача порожній

cmp size_r_data[si],0

je exit_receive_com

mov ah,0

mov bx,start_r_data[si]

mov al,reciave_buf[si][bx]

cmp parity[si],'N'

je no_parity

; якщо виробляється перевірка на парність, то маскуємо старший біт

and al,7FH

no_parity:

inc bx

cmp bx,R_SIZE

jb rec_ptr_no_max

mov bx,0

rec_ptr_no_max:

mov start_r_data[si],bx

dec size_r_data[si]

exit_receive_com:

pop si

pop bx

popf

pop si

mov sp,bp

pop bp

ret

_receive_com        ENDP

; функція повертає в регістрі ax число вільних байт у

; буфер передавача, а в регістрі dx загальний розмір буфера передавача

_s_count      PROC FAR

push bp

mov bp,sp

push si

pushf

push si

mov si,CURRENT_AREA

mov ax,0

mov dx,S_SIZE

test installed[si],1

jz exit_s_count

mov ax,S_SIZE

sub ax,size_s_data[si]

exit_s_count:

pop si

popf

pop si

mov sp,bp

pop bp

ret

_s_count      ENDP

; помістити символ у буфер передавача

; [bp+6] - символ

_send_com PROC FAR

push bp

mov bp,sp

push si

mov al,[bp+6]

pushf

push ax

push bx

push dx

push si

mov si,CURRENT_AREA

test installed[si],1

jz exit_send_com

cmp size_s_data[si],S_SIZE

jl no_s_EOVFLOW

; відбулося переповнення буфера передавача

inc WORD PTR EOVFLOW[si]

jmp short exit_send_com

no_s_EOVFLOW:

mov bx,end_s_data[si]

mov send_buf[si][bx],al

inc bx

cmp bx,S_SIZE

jl no_send_ptr_max

mov bx,0

no_send_ptr_max:

mov end_s_data[si],bx

inc size_s_data[si]

; зчитуємо регістр керування перериваннями

mov dx,IER[si]

in al,dx

; завершуємо функцію якщо дозволені переривання після передачі байта

test al,2

jnz exit_send_com

; дозволяємо переривання після передачі байта, після прииема байта,

; при виявленні стану "BREAK" і при виникненні помилки

mov al,7

out dx,al

exit_send_com:

pop si

pop dx

pop bx

pop ax

popf

pop si

mov sp,bp

pop bp

ret

_send_com ENDP

; передаємо вилученому модему сигнал "BREAK"

_break_com           PROC FAR

push bp

mov bp,sp

push si

pushf

push ax

push cx

push dx

mov si,CURRENT_AREA

test installed[si],1

jz exit_break_com

; передаємо сигнал "BREAK"

mov dx,LCR[si]

in al,dx

jmp $+2

or al,40h

out dx,al

mov cx,0C000h

do_BREAK:

loop do_BREAK

and al,0BFh

out dx,al

exit_break_com:

pop dx

pop cx

pop ax

popf

pop si

mov sp,bp

pop bp

ret

_break_com           ENDP

; повертаємо в dx:ax покажчик на лічильники помилок

_com_errors PROC FAR

push bp

mov bp,sp

mov ax,OFFSET DGROUP:CURRENT_AREA

add ax,error_block

mov dx,ds

mov sp,bp

pop bp

ret

_com_errors ENDP

; заповнюємо лічильники помилок

set_err PROC NEAR

test al,2

jz test1

inc WORD PTR EOVRUN[si]

test1:

test al,4

jz test2

inc WORD PTR EPARITY[si]

test2:

test al,8

jz test3

inc WORD PTR EFRAME[si]

test3:

test al,16

jz exit_set_err

inc WORD PTR EBREAK[si]

exit_set_err:

ret

set_err ENDP

; протокол модему для передачі даних

modem_protocol PROC NEAR

cmp device_conn[si],'M'

jne no_modem

; установлюємо сигнали DTR, RTS і OUT2

mov dx,MCR[si]

mov al,00001011B

out dx,al

jmp $+2

; очікуємо поки модем відповість про готовність сигналом DSR

mov cx,1000

mov dx,MSR[si]

wait_dsr:

in al,dx

test al,20H

jnz test_cts

loop wait_dsr

; модем не відповів сигналом DSR

inc WORD PTR EDSR[si]

jmp short no_modem

test_cts:

; очікуємо поки модем відповість про готовність сигналом CTS

mov cx,1000

wait_cts:

in al,dx

test al,10H

jnz test_lcr

loop wait_cts

; модем не відповів сигналом CTS

inc WORD PTR ECTS[si]

test_lcr:

no_modem:

; чи перевіряємо порожній регситр збереження передавача

mov dx,LSR[si]

in al,dx

test al,20H

jnz s_reg_empty

; помилка при передачі

inc WORD PTR EXMIT[si]

s_reg_empty:

ret

modem_protocol ENDP

; оброблювач переривань від COM1

int_hndlr1 PROC FAR

push si

mov si,OFFSET DGROUP:AREA1

jmp short handle_int

; оброблювач переривань від COM2

int_hndlr2 PROC FAR

push si

mov si,OFFSET DGROUP:AREA2

jmp short handle_int

; оброблювач переривань від COM3

int_hndlr3 PROC FAR

push si; SAVE si

mov si,OFFSET DGROUP:AREA3

jmp short handle_int

;

; оброблювач переривань від COM4

int_hndlr4 PROC FAR

push si; SAVE si

mov si,OFFSET DGROUP:AREA4

;

; оброблювач переривань

handle_int:

push ax

push bx

push cx

push dx

push bp

push di

push ds

push es

mov ax,DGROUP

mov ds,ax

next_pr:

; передаємо контролеру переривань команду кінця обробки

; переривання

mov dx,OCR

mov al,eoi[si]

out dx,al

next_inter:

; зчитуємо значення регістра ідентифікації переривання

mov dx,IIR[si]

in al,dx

; визначаємо причину переривання

; виявлено сотояние "BREAK" чи відбулася помилка

cmp al,0

je MSTAT_int

; дан прийняті і доступні для читання

cmp al,4

je RX_int

; буфер передавача порожній

cmp al,2

je TX_int

; змінився стан ліній CTS, RI, DCD, DSR

cmp al,6

je LSTAT_int

; завершуємо обробку переривань

jmp FAR PTR exit_handler

LSTAT_int:

; зчитуємо регістр стану лінії і викликаємо функцію

; set_err, що визначить причину переривання

mov dx,LSR[si]

in al,dx

mov al,0FFh

mov RING[si],al

call set_err

jmp next_inter

MSTAT_int:

; зчитуємо регістр стану модему

mov dx,MSR[si]

in al,dx

mov al,0FFh

mov RING[si],al

jmp next_inter

TX_int:

; дивимося сти чи дані для передачі модему

cmp size_s_data[si],0

jg have_data_for_send

; якщо буфер передавача порожній переустановлюємо регістр

; керування перериваннями

mov dx,IER[si]

mov al,0Dh 

out dx,al

jmp next_inter

have_data_for_send:

; передаємо символ модему відповідно до стану

; ліній RS-232-З

call modem_protocol

; передаємо черговий символ з буфера передавача

mov bx,start_s_data[si]

mov al,send_buf[si][bx]

mov dx,DATREG[si]

out dx,al

inc bx

cmp bx,S_SIZE

jb ptr_no_max

mov bx,0

ptr_no_max:

mov start_s_data[si],bx

dec size_s_data[si]

jmp next_inter

; дан прийняті і доступні для читання

RX_int:

; зчитуємо прийнятий байти із регістра даних UART

mov dx,DATREG[si]

in al,dx

cmp size_r_data[si],R_SIZE

jl no_r_EOVFLOW

; буфер приймача переповнений, збільшуємо відповідний

; лічильник помилок

inc WORD PTR EOVFLOW[si]

jmp next_inter

no_r_EOVFLOW:

mov bx,end_r_data[si]

mov reciave_buf[si][bx],al

inc size_r_data[si]

inc bx

cmp bx,R_SIZE

jb no_max_r_ptr

mov bx,0

no_max_r_ptr:

mov end_r_data[si],bx

jmp next_inter

exit_handler:

mov al,20h

out 20h,al

pop es

pop ds

pop di

pop bp

pop dx

pop cx

pop bx

pop ax

pop si

iret

int_hndlr4 ENDP

int_hndlr3 ENDP

int_hndlr2 ENDP

int_hndlr1 ENDP

COM_TEXT ENDS

END


Страницы: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10


Новости

Быстрый поиск

Группа вКонтакте: новости

Пока нет

Новости в Twitter и Facebook

  скачать рефераты              скачать рефераты

Новости

скачать рефераты

Обратная связь

Поиск
Обратная связь
Реклама и размещение статей на сайте
© 2010.