Эксперт
  
Профиль
Группа: Участник Клуба
Сообщений: 1232
Регистрация: 25.3.2002
Где: Москва
Репутация: нет Всего: 18
|
Покажи, как точно ты инициализируешь порт, разрешаешь прерывания и тому подобное. Вот как примерно я работал с портом (плюс ухищрения для 98-ой): Код | { base - базовый адрес порта (3F8 для Com1) } { irq - уровень прерывания (4 для Com1) } { opcode - код настройки порта } { 76543210 76543210 } { ¦¦¦¦¦ L+++++++ код скорости (6*2**N=19200/2**N) } { ¦¦¦L+---------- код длины (00=5, 01=6, 10=7, 11=8) } { ¦¦L------------ код кадра (0=1, 1=2) } { L+------------- код четности (00=n, 01=o, 10=n, 11=e); }
Const {*** Регистры модема/порта ***} DAT = 0; { регистр данных } IER = 1; { регистр разрешения прерывания } IIR = 2; { регистр идентификации прерывания } LCR = 3; { регистр управления линией } MCR = 4; { регистр управления модемом } LSR = 5; { регистр состояния линии } MSR = 6; { регистр состояния модема }
Var LineInUse :boolean; SavedExit :pointer;
Var
SaveOldIn1C: pointer; { Old 1Ch vector } Dword0087: longint; { Old 1Bh vector } Dword008B: longint; { Old 23h vector } Dword008F: longint; { Old xx vector (com port interrupt) } Word0093: Word; { Port base address } Byte0095: Byte; { Relative com port interrupt number } Byte0096: Byte; TimeCount: Word; { Timeout ticks } Byte0099: Byte;
Const
IntMaskList: array[1..8] of Byte = ($01,$02,$04,$08,$10,$20,$40,$80);
Var { Буфер передачи } { Word: количество байтов в буфере } { Word: указатель записи (start=SendBuffer) } { Word: указатель извлечения (start=SendBuffer) } { Array[1..BufferSize] of bytes: буфер } SendRing: Array[1..(2+2+2+BufferSize)] of Byte;
{ Буфер приема } { Word: количество байтов в буфере } { Word: указатель записи (start=RecBuffer) } { Word: указатель извлечения (start=RecBuffer) } { Array[1..BufferSize] of bytes: буфер } RecvRing: Array[1..(2+2+2+BufferSize)] of Byte;
{*** local subprograms ***} {*** Startup the RingBuffer ***} Procedure Clear_RingBuffer(BuffAddr:Word); begin asm mov si,BuffAddr mov word ptr [si],0000h mov bx,si add bx,0006h mov [si+02],bx mov [si+04],bx end; end; {*** Переместить указатель в кольцевом буфере ***} Function IncrementRingPointer(StartPo:Word):Word; begin asm mov bx,StartPo inc bx add si,BufferSize+6 cmp bx,si jb @@L0AEA sub bx,BufferSize @@L0AEA: sub si,BufferSize+6 mov @Result,bx end; end; {*** Put data byte into ring buffer ***} Procedure PutDataIntoRingBuff(SendData: Byte; RingAddr:Word); begin asm mov si,RingAddr cmp word ptr [si],BufferSize jnb @@BufferFull inc word ptr [si] mov bx,[si+02] mov al,SendData mov [bx],al push bx call IncrementRingPointer mov [si+02],ax @@IsData: clc jmp @@Done @@BufferFull: stc @@Done: end; end; {*** Get byte from ring buffer ***} Function GetByteFromRingBuffer(RingAddr:Word):Byte; begin asm mov si,RingAddr cmp word ptr [si],0000 jz @@BuffEmpty dec word ptr [si] mov bx,[si+04] mov al,[bx] push ax push bx call IncrementRingPointer mov [si+04],ax pop ax jmp @@IsData @@IsData: mov @Result,al clc jmp @@Done @@BuffEmpty: mov @Result,0 stc @@Done: end; end; {*** Запись в порт=Base(Word0093)+Register байта OutByte ***} {*** Выполняется с задержкой ***} Procedure OutPortByte(OutByte:Byte; Register:Byte); begin asm pusha mov dx,Word0093 add dl,Register adc dh,0 mov al,OutByte {Задержка} mov cx,0FFFFh @@WaitDevice: loop @@WaitDevice out dx,al popa end; end; {*** Чтение из порта=Base(Word0093)+Register байта ***} {*** Выполняется с задержкой ***} Function InPortByte(Register:Byte):Byte; begin asm pusha mov dx,Word0093 add dl,Register adc dh,0 {Задержка} mov cx,0FFFFh @@WaitDevice: loop @@WaitDevice in al,dx mov @Result,al popa end; end;
{$F+} procedure OpenLine(base,irq,opcode:word); begin asm mov ax,base mov Word0093,ax {Prepare Line ?} { Wr[IER],0 } push 0 push IER call OutPortByte { Wr[LCR],80h } push 80h push LCR call OutPortByte { Wr[DAT],cl } mov cx,opcode xor ax,ax mov al,cl push ax push DAT call OutPortByte { Wr[LCR],ch } xor ax,ax mov al,ch push ax push LCR call OutPortByte { Rd[LSR] } push LSR call InPortByte { Rd[DAT] } push DAT call InPortByte
mov ax,irq and al,07h mov Byte0095,al { Save old int 1Ch } mov ax,351Ch int 21h mov word ptr SaveOldIn1C,bx mov word ptr SaveOldIn1C+2,es { Save old int 1Bh } mov ax,351Bh int 21h mov word ptr Dword0087,bx mov word ptr Dword0087+2,es { Save old int 23h } mov ax,3523h int 21h mov word ptr Dword008B,bx mov word ptr Dword008B+2,es { Save old int xxh - com port line } mov al,Byte0095 add al,08h mov ah,35h int 21h mov word ptr Dword008F,bx mov word ptr Dword008F+2,es { Clear Send buffer } push offset SendRing call Clear_RingBuffer { Clear Receive buffer } push offset RecvRing call Clear_RingBuffer { Set new vector for int 1Ch } push ds push cs pop ds mov dx,offset @@Proc0B9D mov ax,251Ch int 21h { Set new vector for int 1Bh } mov dx,offset @@L0BB1 mov ax,251Bh int 21h { Set new vector for int 23h } mov dx,offset @@L0BB1 mov ax,2523h int 21h pop ds { Wr[IER],0 } push 0 push IER call OutPortByte { Set new vector for int xx - com port line } mov dx,offset @@Proc0B03 mov al,Byte0095 add al,08h mov ah,25h push ds push cs pop ds int 21h pop ds cli mov cx,opcode { Wr[LCR],80h } push 80h push LCR call OutPortByte { Wr[DAT],cl } xor ax,ax mov al,cl push ax push DAT call OutPortByte { Wr[LCR],ch } xor ax,ax mov al,ch push ax push LCR call OutPortByte { Rd[LSR] } push LSR call InPortByte { Rd[DAT] } push DAT call InPortByte mov al,0Ch mov Byte0099,al { Wr[MCR],0Ch } mov ah,0 push ax push MCR call OutPortByte { Rd[LSR] } push LSR call InPortByte { Rd[DAT] } push DAT call InPortByte push 0Fh push IER call OutPortByte mov al,Byte0095 mov bx,offset IntMaskList xlat mov Byte0096,al not al mov ah,al in al,21h and al,ah out 21h,al sti jmp @@SkipHandlers {*** Handlers Area ***} { Int xxh handler at 0B03 } @@Proc0B03: sti push ax push bx push cx push dx push si push ds push bp mov ax,seg @Data mov ds,ax @@L0B0E: mov dx,Word0093 add dx,0002h in al,dx and ax,0007h test ax,0001h jz @@L0B29 mov al,20h out 20h,al pop bp pop ds pop si pop dx pop cx pop bx pop ax iret @@L0B29: cmp ax,0004h jb @@L0B42 push ax mov dx,Word0093 add dx,0001h in al,dx or al,02 mov dx,Word0093 add dx,0001h out dx,al pop ax @@L0B42: mov bx,offset @@IntList add bx,ax jmp word ptr cs:[bx] @@IntList: dw offset @@Proc0B51,offset @@Proc0B5B dw offset @@Proc0B81,offset @@Proc0B92 @@Proc0B51: mov dx,Word0093 add dx,0006h in al,dx jmp @@L0B0E @@Proc0B5B: push offset SendRing call GetByteFromRingBuffer jb @@L0B6D mov dx,Word0093 add dx,0000h out dx,al jmp @@L0B0E @@L0B6D: mov dx,Word0093 add dx,0001h in al,dx and al,0FDh mov dx,Word0093 add dx,0001h out dx,al jmp @@L0B0E @@Proc0B81: mov dx,Word0093 add dx,0000h in al,dx push ax push offset RecvRing call PutDataIntoRingBuff jmp @@L0B0E @@Proc0B92: mov dx,Word0093 add dx,0005h in al,dx jmp @@L0B0E {*** Прерывания от таймера ***} { Уменьшает значение ячейки TimeCount при каждом вызове } @@Proc0B9D: push ax push ds mov ax,seg @Data mov ds,ax cmp word ptr ds:TimeCount,0 jz @@SetZeroCount dec ds:word ptr TimeCount @@SetZeroCount: pop ds pop ax @@L0BB1: iret @@SkipHandlers: end; end;
|
--------------------
I don't like the drugs (but the drugs like me). M.Manson.
|