I've been tried over and over to get this code working correctly but it
doesn't. So i ask to any guru of modems programming to help me to find what
wrong i did. Currently you need to change INTNUM, UART_BASE and OFFMASK to
reflect your com setting.
seg_a segment byte public 'seg_a'
assume cs:seg_a, ds:seg_a, ss:seg_a
org 100h
UART_BASE = 03E8h ; COM1: 3F8h etc...
INTNUM equ 74h ; COM1; 0Ch COM2: 0Bh COM3: 0Ch COM4: 0Bh
OFFMASK equ 00010000b ; COM1; COM2: 00001000b
ONMASK equ not OFFMASK
UART_RATE equ 12 ; 9600 bps, see table in this file
UART_PARAMS equ 00000011b ; 8n1, see tables
RXFIFOSIZE equ 8096 ; set this to your needs
TXFIFOSIZE equ 8096 ; dito.
start: mov ah,35h
mov al,INTNUM ; irq12
int 21h
mov oldirq+2, es
mov oldirq, bx
mov ah,25h
mov al,INTNUM ; irq12
mov dx,offset newirq
int 21h
; initialize the UART
cli
mov dx,UART_BASE+3 ; 03EBh
mov al,80h ; set DLAB
out dx,al
mov dx,UART_BASE ; 03E8h
mov ax,UART_RATE ; 9600 bps
out dx,ax ; write bps rate divisor
xor ax,ax
inc dx
out dx,al ; set baud rate divisor high byte
mov dx,UART_BASE+3 ; 03EBh
mov al,UART_PARAMS ;set to 8N1
out dx,al ; write parameters
mov dx,03EFh
in al,dx
mov al,0f0h
out dx,al
in al,dx
mov al,00h
out dx,al
mov dx,UART_BASE+4 ; MCR
xor ax,ax ; clear loopback
out dx,al
; is it a 16550A?
; mov dx,UART_BASE+2
; in al,dx ; IRR
; and al,11000000b
; cmp al,11000000b
; jne iu_nofifos
; mov bitxfifo,16
mov dx,UART_BASE+2 ; FCR
mov al,11000111b ; trigger level 14 bytes RX
out dx,al ; clear and enable the fifos if they exist
; iu_nofifos:
mov dx,UART_BASE+1
mov al,00001101b ; allow RX interrupts
; enable line status interrupt
; enable modem-status interrupt
out dx,al
mov dx,UART_BASE
in al,dx ; clear receiver
mov dx,UART_BASE+5
in al,dx ; clear line status
inc dx
in al,dx ; clear modem status
; and enable ints from the UART
mov dx,UART_BASE+4
mov al,00001000b ; enable interrupts and force dtr
out dx,al
in al,0a1h
and al,ONMASK
out 0a1h,al ; free interrupt in the ICU
sti ; release interrupts if any
mov dx,offset red ; paragraph
mov cl,04h
shr dx,cl
inc dx
cmp dx,0011h
jnb exit1
mov dx,0011h
exit1: mov ah,31h
int 21h
newirq proc near
push bx
push ax
push dx
push si
int_loop:
mov dx,UART_BASE+2 ; IIR
xor ax,ax
in al,dx ; check IIR info
test al,1 ; interrupt pending?
jnz int_end ; jump if no int. pending
and ax,6
mov si,ax
call word ptr cs:int_servicetab[si]
jmp int_loop
int_end: jmp no_ring
int_modem proc near
mov dx,UART_BASE+6 ; 03EEh
in al,dx ; read MSR (lowest priority)
and al,04h ; mask ring indicator (RI) changed
cmp al,04h
jne by_pass
inc byte ptr cs:[ring]
by_pass: ret
int_modem endp
int_tx proc near
; transmit routine not used.
ret
int_tx endp
int_rx proc near
get_me: mov dx,UART_BASE ; 03E8h read it fast
in al,dx
mov bx,offset cs:mess
add bx,word ptr cs:[pointer]
mov byte ptr cs:[bx],al
cmp byte ptr cs:[pointer],08h
je ugc_nochar
inc cs:[pointer]
ugc_nochar: mov dx,UART_BASE+5 ; 03edh
in al,dx
test al,01h
jnz get_me ; ugc_nochar
ret
test ah,0eh
jz no_error
test ah,02h
jz no_overrun
mov cs:[over],01h
no_overrun: test ah,04h
jz no_parity
mov cs:[over],02h
no_parity: test ah,08h
jz no_framing
mov cs:[over],03h
no_framing:
no_error: ret
int_rx endp
line_status_int proc near
mov dx,UART_BASE+5 ; 03EDh
in al,dx ; clear the status
ret ; just read it only! and return
line_status_int endp
no_ring:
pop si
pop dx
pop ax
pop bx
mov al,20h ; acknowledge interrupt
out 20h,al
out 0a0h,al ; comment out this line if using lower irq level
iret
db 0eah
oldirq dw 0
dw 0
newirq endp
ring db 00h
pointer dw 0000h
mess db 00h,00h,00h,00h,00h,00h,00h,00h,00h,00h,00h,66h
over db 00h
int_servicetab DW int_modem, int_tx, int_rx, line_status_int
red equ $
seg_a ends
end start
--- Renegade v5-11 Exp
---------------
* Origin: CoM BBS (merely seeking the truth) (1:167/146)
|