![]() |
中国DOS联盟-- 联合DOS 推动DOS 发展DOS --联盟域名:www.cn-dos.net 论坛域名:www.cn-dos.net/forum |
| 游客 | 登录 | 注册 | 会员 | 搜索 | 中国DOS联盟 |
|
中国DOS联盟论坛 现在时间是 2026-09-14 23:23 |
共 47,812 主题排行 / 349,917 发帖 / 今日 0 篇 / 48,268 会员排行 |
| DOS开发编程 & 发展交流 (开发室) » 谁能给我一份DOS下串口编程的资料或者源代码?谢谢! |
| 可打印版本 15,494 / 57 |
| 第31楼 saliwen302 | 发表于 2008-05-22 14:52 |
| 新手上路 发帖 9 积分 18 | |
|
贴一段phoenix 的int 14h的code吧 2 这个是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 |
|
| 第32楼 saliwen302 | 发表于 2008-05-22 14:54 |
| 新手上路 发帖 9 积分 18 | |
|
贴一段phoenix 的int 14h的code吧 3 两个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 |
|
| 第33楼 saliwen302 | 发表于 2008-05-22 14:55 |
| 新手上路 发帖 9 积分 18 | |
|
贴一段phoenix 的int 14h的code吧 3 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 |
|
| 第34楼 saliwen302 | 发表于 2008-05-22 14:56 |
| 新手上路 发帖 9 积分 18 | |
|
贴一段phoenix 的int 14h的code吧 4 然后是发送和接受
;+--------------------------------------------------------------------------- ; ; 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 |
|
| 第35楼 saliwen302 | 发表于 2008-05-22 14:58 |
| 新手上路 发帖 9 积分 18 | |
|
贴一段phoenix 的int 14h的code吧 5 取得当前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 |
|
| 第36楼 saliwen302 | 发表于 2008-05-22 14:59 |
| 新手上路 发帖 9 积分 18 | |
|
最后一个函数,如果是用 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 |
|
| 第37楼 saliwen302 | 发表于 2008-05-22 15:04 |
| 新手上路 发帖 9 积分 18 | |
|
贴一段phoenix 的int 14h的code吧 6 以下这个函数是在发送和接受的时候会用到的。这个是一个通用的函数,不得不佩服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 |
|
| 第38楼 biqiang | 发表于 2008-05-23 15:07 |
| 新手上路 发帖 3 积分 6 | |
|
学习一下吧,现在想弄一下DOS下Modem通讯
|
|
| 第39楼 yanchunyun | 发表于 2008-07-16 11:53 |
| 新手上路 发帖 1 积分 2 | |
|
一直都沒上論壇,積分居然為 0,丟人啊!
|
|
| 第40楼 cmangel | 发表于 2008-08-28 23:17 |
| 新手上路 发帖 2 积分 4 | |
|
谢谢,没想到这里有我想找的东东,好好学习一下,太感谢了。
|
|
| 第41楼 112223333 | 发表于 2009-02-15 17:35 |
| 新手上路 发帖 1 积分 2 | |
|
xiexie
|
|
| 第42楼 zhanglitao422 | 发表于 2009-02-23 12:29 |
| 新手上路 发帖 1 积分 2 | |
|
关注中,看看。。
|
|
| 第43楼 weiguohua | 发表于 2009-03-16 00:03 |
| 新手上路 发帖 2 积分 4 | |
|
2008 这年头搞这个的人不多见了.
|
|
| 第44楼 chali | 发表于 2009-04-09 23:30 |
| 新手上路 发帖 3 积分 5 | |
|
ding
|
|
| 第45楼 lonegoer | 发表于 2009-04-21 12:41 |
| 新手上路 发帖 4 积分 8 | |
|
有没有具体点的关于rts,dtr握手处理相关的串口c源码啊?
|
|
| 上一页 1 2 3 4 下一页 |
|
[ 联系联盟系统管理团队 -
中国DOS联盟 -
标准版 ] Sponsored by ifanr Inc | © 2001–2023 |