中国DOS联盟论坛

中国DOS联盟

-- 联合DOS 推动DOS 发展DOS --

联盟域名:www.cn-dos.net  论坛域名:www.cn-dos.net/forum
DOS,代表着自由开放与发展,我们努力起来,学习FreeDOS和Linux的自由开放与GNU精神,共同创造和发展美好的自由与GNU GPL世界吧!

游客:  注册 | 登录 | 命令行 | 搜索 | 上传 | 帮助 »
中国DOS联盟论坛 » DOS开发编程 & 发展交流 (开发室) » 谁能给我一份DOS下串口编程的资料或者源代码?谢谢!
作者:
标题: 谁能给我一份DOS下串口编程的资料或者源代码?谢谢! 上一主题 | 下一主题
saliwen302
新手上路





积分 18
发帖 9
注册 2008-5-21
状态 离线
『第 31 楼』:  贴一段phoenix 的int 14h的code吧 2 使用 LLM 解释/回答一下

这个是int 14h的入口函数,用来dispatch任务

;============================================================================
;
; DECLARE SERIAL COMMAND TABLE
;
PUBLIC coreSerialCmdTable
coreSerialCmdTable LABEL WORD
DW coreSerialInit
DW coreSerialSend
DW coreSerialReceive
DW coreSerialStatus
DW coreExtendedSerialInit
DW coreExtendedPortControl


coreBiosSerialInterface PROC FAR
sti
PUSH_REG_STACK ; Save regs, set BP
cmp ah, 05 ; Command out of range?
ja serialExit ; Yes - Don't do anything
cmp dx, 3 ; Requesting > COM4?
ja serialExit ; Yes - Don't do anything
mov ds, SegAddressBDA ; Access BIOS data area
mov bx, dx ; Get COM channel number
mov cl, bdaRS232TimeOut[bx] ; Get timeout value
shl bx, 1 ; Double for Base address
mov dx, bdaRS232Table[bx] ; Read base address for COM
or dx, dx ; Test for COM not available
jz serialExit ; Yes-Dont do anything
movzx bx, ah ; Save command number in BX
mov ah, cl ; Keep timeut in AH
shl bx, 1 ; Double for table offset
add dx, 04 ; Advance DX to MCR

call cs:coreSerialCmdTable[bx] ; Go perform command

serialExit:
mov BYTE PTR [bp].regStack.axReg + 1, ah ; Save line status in AH
POP_REG_STACK ; Restore callers registers
iret
coreBiosSerialInterface ENDP


2008-5-22 14:52
查看资料  发送邮件  发短消息  网志   编辑帖子  回复  引用回复
saliwen302
新手上路





积分 18
发帖 9
注册 2008-5-21
状态 离线
『第 32 楼』:  贴一段phoenix 的int 14h的code吧 3 使用 LLM 解释/回答一下

两个macro,帮助理解程序:

;;---------------------------------------------------------------------------
;;
;; PUSH_REG_STACK - set up register stack
;;
;; Processing:
;; pushes all regs associated with register stack structure
;; copies SP to BP
;;
;; Usage:
;; PUSH_REG_STACK - to set up register stack
;; [bp].regStack.axReg - to reference AX register on regStack
;;
PUSH_REG_STACK MACRO
pusha
push es
push ds
mov bp, sp
ENDM

;;---------------------------------------------------------------------------
;;
;; POP_REG_STACK - restore regs from register stack
;;
;; Usage:
;; POP_REG_STACK - to restore regs from register stack
;;
POP_REG_STACK MACRO
pop ds
pop es
popa
ENDM


2008-5-22 14:54
查看资料  发送邮件  发短消息  网志   编辑帖子  回复  引用回复
saliwen302
新手上路





积分 18
发帖 9
注册 2008-5-21
状态 离线
『第 33 楼』:  贴一段phoenix 的int 14h的code吧 3 使用 LLM 解释/回答一下

Init COM的代码,分为legacy init和extend mode init

;+---------------------------------------------------------------------------
;
; coreSerialInit - Initialize the specified RS232 channel.
;
; Entry:
;
; Exit:
;
; Modifies:
;
; Processing:
; Initialization consists of programming the line control registers,
; the baud rate divisor, and clearing the interrupt enable register.
;
coreSerialInit PROC NEAR PUBLIC
and al, 01Fh ; Clear Baud bits from init
mov ch, al ; Save to restore w DLAB off
or al, 080h ; Set the DLAB bit on
dec dx ; Decrement to LCR (xFBH)
out dx, al ; Keep Stick and Set Break low
mov al, BYTE PTR [bp].regStack.axReg ; Get init byte again
mov cl, 05 ; Shift baud bits down
shr al, cl ; to bit 0 position
mov cl, al ; Save baud rate number
or al, al ; Are we setting 110 baud ?
mov ax, 417h ; Handle 110 baud special
jz setBaudRate ; Yes-Use value in AX
mov ax, 0600h ; Compute divisor based
shr ax, cl ; on baud rate number

setBaudRate:
xchg al, ah ; Get high divisor into AL
dec dx ; Move back to high divisor
dec dx ; located at xF9H.
out dx, al ; Write MSB of divisor
IODELAY
dec dx ; Move back to LSB of divisor
mov al, ah ; Get LSB divisor byte
out dx, al ; Write at xF8H.
add dx, 03 ; Advance to LCR
mov al, ch ; Get LCR value w/o DLAB set
out dx, al ; Write LCR (xFBH)
sub dx, 02 ; Go back to interrupt
mov al, 00 ; Dont allow any 8250
out dx, al ; interrupts occur
add dx, 03h ; Move to (LSR-1) (xFCH)
jmp coreSerialStatus ; Go return Line & Modem status
coreSerialInit ENDP


;+---------------------------------------------------------------------------
; coreExtendedSerialInit - For PS/2 Compatibility
; Extended communications port initialization.
;
; Entry:
; DX points to MCR
;
; Exit:
;
; Modified:
;
coreExtendedSerialInit PROC NEAR PUBLIC
mov cx, [bp].regStack.cxReg
cmp cl, 8
ja extendedSerialInitEx
xor ch, ch ; Retrieve the baud rate divisor
shl cx, 1 ; and set the baud rate.
mov di, cx
mov bx, baudDivisorTable[di]
dec dx ; Reference the line control register.
push ax
call setBd
pop ax
and al, 00000001b ; Use only the break/no break.
shl al, 6 ; Build the line control word. AL is
mov bx, [bp].regStack.bxReg
shl bl, 2 ; Break/no break, BL is stops,
or al, bl ; Doesn't match the control register's
mov cx, [bp].regStack.cxReg
or al, ch
mov bl, bh
and bx, 00000111b
or al, BYTE PTR BHTranslate[BX]
out dx, al ; Set LCR
IODELAY
sub dx, 02 ; Go back to interrupt
mov al, 00 ; Dont allow any 8250
out dx, al ; interrupts occur
add dx, 03h ; Move to MCR

ExtendedSerialInitEx:
jmp coreSerialStatus ; Go return Line & Modem status
coreExtendedSerialInit ENDP


2008-5-22 14:55
查看资料  发送邮件  发短消息  网志   编辑帖子  回复  引用回复
saliwen302
新手上路





积分 18
发帖 9
注册 2008-5-21
状态 离线
『第 34 楼』:  贴一段phoenix 的int 14h的code吧 4 使用 LLM 解释/回答一下

然后是发送和接受


;+---------------------------------------------------------------------------
;
; coreSerialSend - Send specified character to 8250 Serial Device.
;
; Entry:
;
; Exit:
;
; Modifies:
;
; Processing:
; Before the data is sent, CTS and DTR must be set and the tranmitter
; holding register must be empty.
;
coreSerialSend PROC NEAR PUBLIC
movzx cx, ah ; Set timeout in CX
mov al, 03h ; Set DTR and RTS
out dx, al ; Write to MCR (xFCH)
inc dx ; Advance to Modem status
inc dx ; register (MSR at xFEH)

sendWaitLoop:
push cx ; Save Timeout count
mov bx, 3030h ; Mask for CTS and DSR
mov cx, 8235h ; Wait for 1 sec

call coreIOstatus30us ; Wait for CTS and DSR
jz lsrTranReg
pop cx ; Restore count
loop sendWaitLoop ; Loop again if I/O timeout
jmp coreSerialTimeout

lsrTranReg:
pop cx
dec dx ; Else-Move back to LSR

transmitWait:
push cx ; Save timeout
mov bx, 2020h ; Wait for Transmit Reg empty
mov cx, 8235h
call coreIOstatus30us
pop cx ; Restore timeout
loopne transmitWait ; Go wait if not ready and time left
jnz coreserialTimeout ; Exit if error

serialTransmit:
sub dx, 05 ; Move back to Data reg (xF8H)
mov al, BYTE PTR [bp].regStack.axReg ; Get byte to send
out dx, al ; Send it to 8250
add dx, 05 ; Advance to LSR
jmp coreserialStatus1 ; Go return Line Status

coreSerialTimeout::
mov ah, 080h ; Return timeout error
ret
coreSerialSend ENDP

;+---------------------------------------------------------------------------
;
; coreSerialReceive - Receive a character from the 8250.
;
; Entry:
;
; Exit:
;
; Modifies:
;
; Processing:
; In order for a character to be received, DSR must be set in
; the modem status register and em status register and data ready must be set in the
; line status register. If the break key is pressed during the
; timeout period, then a premature timeout will occur.
;
coreSerialReceive PROC NEAR PUBLIC
movzx cx, ah ; Set timeout in CX
mov al, 01 ; Set DTR in MCR
out dx, al ; Write to Modem Control reg
inc dx ; Advance to modem status
inc dx ; register (MSR at xFEH)

dsrWaitLoop:
push cx ; Save timeout count
mov bx, 2020h ; Mask for DSR
mov cx, 8235h ; Wait for 1 sec
call coreIOstatus30us ; Wait for DSR - All registers
; are preserved across call
pop cx ; Restore count
jz checkLsrDataRdy
loop dsrWaitLoop ; Loop again if I/O timeout
jmp coreSerialTimeout ; Exit if error

checkLsrDataRdy:
dec dx ; Else-Decrement to LSR
in al, dx ; Read LSR
mov ah, al ; Save line status
and ah, 1Eh ; Isolate error bits

receiveWait:
push cx ; Save timeout
mov bx, 0101h ; Mask for Data Ready
mov cx, 8235h ; 1 sec wait
call coreIOstatus30us ; Wait for Data Ready - All registers
; are preserved across call
pop cx ; Restore timeout
loopne receiveWait ; Go wait if not ready and time left
jnz coreSerialTimeout ; Exit if error

coreDataReady:
sub dx, 05 ; Move back to data register
in al, dx ; Read character from line
mov BYTE PTR [bp].regStack.axReg, al ; Save character in AL
ret ; Return to caller
coreSerialReceive ENDP


2008-5-22 14:56
查看资料  发送邮件  发短消息  网志   编辑帖子  回复  引用回复
saliwen302
新手上路





积分 18
发帖 9
注册 2008-5-21
状态 离线
『第 35 楼』:  贴一段phoenix 的int 14h的code吧 5 使用 LLM 解释/回答一下

取得当前COM状态的函数

;+---------------------------------------------------------------------------
;
; coreSerialStatus - Return the status of the line status register
; and the modem status register.
;
; Entry:
;
; Exit:
;
coreSerialStatus PROC NEAR PUBLIC
inc dx ; Advance to LSR
call coreSerialStatus1 ; Read status of registers
mov BYTE PTR [bp].regStack.axReg, al ; Save the Modem status in AL
ret
coreSerialStatus ENDP

;+---------------------------------------------------------------------------
;
; coreSerialStatus1 - Return the status of the line status register
; and the modem status register.
;
; Entry:
;
; Exit:
;
coreSerialStatus1 PROC NEAR PUBLIC
in al, dx ; Read Line Status register
mov ah, al ; Save line status in AH
inc dx ; Advance to Modem status reg
in al, dx ; Read modem status register
ret
coreSerialStatus1 ENDP


2008-5-22 14:58
查看资料  发送邮件  发短消息  网志   编辑帖子  回复  引用回复
saliwen302
新手上路





积分 18
发帖 9
注册 2008-5-21
状态 离线
『第 36 楼』:   使用 LLM 解释/回答一下

最后一个函数,如果是用 ah=05 int 14h的话,就会到以下这个函数执行。


;+---------------------------------------------------------------------------
;
; coreExtendedPortControl - For PS/2 compatability
;
; Entry:
; DX points to MCR
;
; Exit:
;
coreExtendedPortControl PROC NEAR PUBLIC
cmp al, 1 ; Check function in range
je ecpcWrite ; If AL == 1, then WRITE requested.
jb ecpcRead ; If AL == 0, then READ requested.
ret

; the READ returns the contents of the Modem Control Port, of the Line Status
; Register, and of the Modem Status Register.

ecpcRead:
in al, dx ; Read it and
mov BYTE PTR [bp].regStack.bxReg, al
jmp ecpcExit

; the WRITE sets the contents of the Modem Control Register, and then returns
; the contents of the Modem Status Register and of the Line Status Register.

ecpcWrite:
mov al, BYTE PTR [bp].regStack.bxReg ; Get original bx
and al, 01Fh
out dx, al ; Set modem control

ecpcExit:
IODELAY
jmp coreSerialStatus
coreExtendedPortControl ENDP


2008-5-22 14:59
查看资料  发送邮件  发短消息  网志   编辑帖子  回复  引用回复
saliwen302
新手上路





积分 18
发帖 9
注册 2008-5-21
状态 离线
『第 37 楼』:  贴一段phoenix 的int 14h的code吧 6 使用 LLM 解释/回答一下

以下这个函数是在发送和接受的时候会用到的。这个是一个通用的函数,不得不佩服Phoenix的功力。

至于里面调用的coreDelayMin15us的实现是通过读取acpi timer来实现的。这个就要看具体的南桥的spec了。就不贴了。

;+---------------------------------------------------------------------------
;
; coreIOStatus30us - Wait a specified time for an IO port status
;
; Entry:
; BH - Mask
; BL - Match
; CX - Time in 30us
; DX - IO Address
;
; Exit:
; ZF = 0 - Timed out waiting for desired status
; = 1 - Data value matched
;
; Modifies:
; Minor flags
;
; Process:
; This routine waits until either the specified port matches
; the desired state or for the specified time to expire.
;
coreIOStatus30us PROC NEAR PUBLIC
push ax
push ecx

movzx ecx, cx ; Convert to 15uS intervals
shl ecx, 1
jmp IOS30CheckEntry

IOS30Check:
push cx

mov cx, 1 ; Delay at least 15us
call coreDelayMin15us

pop cx

IOS30CheckEntry:
in al, dx ; AL := Current value of target port
and al, bh ; Eliminate don't care bits
cmp al, bl ; Remaining bits = expected pattern?
je IOS30GotStatus ; Yes-Exit check loop
loopd IOS30Check ; No -Repeat until timer expires

IOS30GotStatus:
pop ecx
pop ax
ret
coreIOStatus30us ENDP


2008-5-22 15:04
查看资料  发送邮件  发短消息  网志   编辑帖子  回复  引用回复
biqiang
新手上路





积分 6
发帖 3
注册 2007-6-17
状态 离线
『第 38 楼』:   使用 LLM 解释/回答一下

学习一下吧,现在想弄一下DOS下Modem通讯


2008-5-23 15:07
查看资料  发短消息  网志   编辑帖子  回复  引用回复
yanchunyun
新手上路





积分 2
发帖 1
注册 2006-8-1
状态 离线
『第 39 楼』:   使用 LLM 解释/回答一下

一直都沒上論壇,積分居然為 0,丟人啊!


2008-7-16 11:53
查看资料  发短消息  网志   编辑帖子  回复  引用回复
cmangel
新手上路





积分 4
发帖 2
注册 2008-8-28
状态 离线
『第 40 楼』:   使用 LLM 解释/回答一下

谢谢,没想到这里有我想找的东东,好好学习一下,太感谢了。


2008-8-28 23:17
查看资料  发送邮件  发短消息  网志   编辑帖子  回复  引用回复
112223333
新手上路





积分 2
发帖 1
注册 2009-2-14
状态 离线
『第 41 楼』:   使用 LLM 解释/回答一下

xiexie


2009-2-15 17:35
查看资料  发送邮件  发短消息  网志   编辑帖子  回复  引用回复
zhanglitao422
新手上路





积分 2
发帖 1
注册 2009-2-12
状态 离线
『第 42 楼』:   使用 LLM 解释/回答一下

关注中,看看。。


2009-2-23 12:29
查看资料  发送邮件  发短消息  网志   编辑帖子  回复  引用回复
weiguohua
新手上路





积分 4
发帖 2
注册 2008-4-14
状态 离线
『第 43 楼』:  2008 使用 LLM 解释/回答一下

这年头搞这个的人不多见了.


2009-3-16 00:03
查看资料  发送邮件  发短消息  网志   编辑帖子  回复  引用回复
chali
新手上路





积分 5
发帖 3
注册 2009-4-9
状态 离线
『第 44 楼』:   使用 LLM 解释/回答一下

ding


2009-4-9 23:30
查看资料  发送邮件  发短消息  网志   编辑帖子  回复  引用回复
lonegoer
新手上路





积分 8
发帖 4
注册 2009-2-25
状态 离线
『第 45 楼』:   使用 LLM 解释/回答一下

有没有具体点的关于rts,dtr握手处理相关的串口c源码啊?


2009-4-21 12:41
查看资料  发送邮件  发短消息  网志   编辑帖子  回复  引用回复

请注意:您目前尚未注册或登录,请您注册登录以使用论坛的各项功能,例如发表和回复帖子等。


可打印版本 | 推荐给朋友 | 订阅主题 | 收藏主题



论坛跳转: