; ============================================================================= ; ; Litos8 serial COM ports ; ; ============================================================================= ; ----------------------------------------------------------------------------- ; Exported user functions (11): ; COMSet - set COM port ; COMSend - send byte to COM port ; COMRecv - receive byte from COM port (with waiting) ; COMRecvNoWait - receive byte from COM port (without waiting) ; COMRecvTest - test if some byte from COM port is ready ; COMState - get COM port state ; COMPort - get address of COM port ; COMCheck - check COM port ; COMGetNum - get number of COM ports ; COMRead - read data from COM port ; COMWrite - write data to COM port ; ----------------------------------------------------------------------------- CODEINIT_SECTION ; ----------------------------------------------------------------------------- ; INIT: Initialize COM ports ; ----------------------------------------------------------------------------- ; ------------- initialize COM ports to 9600 Baud/no parity/1 stop/8 bits COMInit: mov bl,COM_MAX-1 ; BL <- index of last COM COMInit2: mov al,(7<<5)+(0<<3)+(0<<2)+3 ; 9600 Baud/no par/1 stop/8b call COMSet ; setup COM port dec bl ; BL <- next COM port jns short COMInit2 ; initialize next COM port ret CODE_SECTION ; ----------------------------------------------------------------------------- ; Set COM port ; ----------------------------------------------------------------------------- ; INPUT: AL = setup parameters ; bit 0,1: data bits 0=5b, 1=6b, 2=7b, 3=8b ; bit 2: stop bits 0=1 bit, 1=2 bits (or 1.5 with 5 bits) ; bit 3,4: parity 0 or 2=none, 1=odd, 3=even ; bit 5..7: baud rate 0=110 Baud, 1=150 Baud, 2=300 Baud, ; 3=600 Baud, 4=1200 Baud, 5=2400 Baud, ; 6=4800 Baud, 7=9600 Baud ; BL = COM port index (0..3) ; OUTPUT: CY = invalid COM port or operation error ; ----------------------------------------------------------------------------- COMSet: push ax ; push AX mov ah,0 ; AH <- function code call COMInt ; COM port service pop ax ; pop AX ret ; ----------------------------------------------------------------------------- ; Send byte to COM port ; ----------------------------------------------------------------------------- ; INPUT: AL = byte to send ; BL = COM port index (0..3) ; OUTPUT: CY = invalid COM port or operation error (time-out) ; ----------------------------------------------------------------------------- COMSend: push ax ; push AX mov ah,1 ; AH <- function code call COMInt ; COM port service pop ax ; pop AX ret ; ----------------------------------------------------------------------------- ; Receive byte from COM port (without waiting) ; ----------------------------------------------------------------------------- ; INPUT: BL = COM port index (0..3) ; OUTPUT: AL = byte from COM port (or 0 on error) ; CY = invalid COM port or operation error (time-out, AL = 0) ; ----------------------------------------------------------------------------- COMRecvNoWait: call COMRecvTest ; test if some byte is ready mov al,0 ; AL <- 0, invalid byte jc short COMRecv8 ; byte is not ready ; === COMRecvWait must follow ; ----------------------------------------------------------------------------- ; Receive byte from COM port (with waiting) ; ----------------------------------------------------------------------------- ; INPUT: BL = COM port index (0..3) ; OUTPUT: AL = byte from COM port (or 0 on error) ; CY = invalid COM port or operation error (time-out, AL = 0) ; ----------------------------------------------------------------------------- COMRecv: push bx ; push BX push ax ; push AX mov ah,2 ; AH <- function code call COMInt ; COM port service cmp ah,1 ; check status cmc ; CY = some error xchg ax,bx ; BL <- character pop ax ; pop AX mov al,bl ; AL <- character jnc short COMRecv4 ; operation OK mov al,0 ; AL <- invalid character COMRecv4: pop bx ; pop BX COMRecv8: ret ; ----------------------------------------------------------------------------- ; Test if some byte from COM port is ready ; ----------------------------------------------------------------------------- ; INPUT: BL = COM port index (0..3) ; OUTPUT: CY = invalid COM port or byte is not ready ; ----------------------------------------------------------------------------- COMRecvTest: push ax ; push AX call COMState ; get COM state jc COMRecvTest6 ; error and ax,B8+B5 ; data ready status and data set ready cmp ax,B8+B5 ; CY <- byte is not ready COMRecvTest6: pop ax ; pop AX ret ; ----------------------------------------------------------------------------- ; Get COM port state ; ----------------------------------------------------------------------------- ; INPUT: BL = COM port index (0..3) ; OUTPUT: AL = modem status ; bit 0: 1=delta clear to send ; bit 1: 1=delta data set ready ; bit 2: 1=trailing edge ring detector ; bit 3: 1=delta recv line signal detect ; bit 4: 1=clear to send ; bit 5: 1=data set ready ; bit 6: 1=ring indicator ; bit 7: 1=received line detect signal ; AH = line status ; bit 0: 1=data ready status ; bit 1: 1=overrun error ; bit 2: 1=parity error ; bit 3: 1=framing error ; bit 4: 1=break detect ; bit 5: 1=trans holding reg empty ; bit 6: 1=trans shift reg empty ; bit 7: 1=time-out or general error ; CY = invalid COM port or operation error ; ----------------------------------------------------------------------------- COMState: mov ah,3 ; AH <- function code ; === COMInt must follow ; ----------------------------------------------------------------------------- ; Call COM port interrupt ; ----------------------------------------------------------------------------- ; INPUT: BL = COM port index (0..3) ; OUTPUT: CY = invalid COM port or operation error ; AH = line status ; AL = modem status or received byte ; ----------------------------------------------------------------------------- COMInt: call COMCheck ; check COM port jc short COMInt4 ; invalid COM port push dx ; push DX mov dl,bl ; DL <- COM port int 14h ; call COM port service pop dx ; pop DX rol ah,1 ror ah,1 ; return AH, CF <- error flag COMInt4: ret ; ----------------------------------------------------------------------------- ; Get address of COM port ; ----------------------------------------------------------------------------- ; INPUT: BL = COM port index (0..3) ; OUTPUT: AX = addres of COM port (3f8h=COM1, 2f8h=COM2, 0=no port) ; CY = invalid COM port (AX = 0) ; ----------------------------------------------------------------------------- COMPort: xor ax,ax ; AX <- 0, invalid COM port call COMCheck ; check COM port jc short COMPort4 ; invalid COM port push bx ; push BX mov bh,0 ; BX <- COM port index shl bx,1 ; BX <- offset in address table mov ax,[400h+bx] ; AX <- COM port address pop bx ; pop BX COMPort4: ret ; ----------------------------------------------------------------------------- ; Check COM port ; ----------------------------------------------------------------------------- ; INPUT: BL = COM port index (0..3) ; OUTPUT: CY = invalid COM port ; ----------------------------------------------------------------------------- COMCheck: push bx ; push BX cmp bl,COM_MAX ; check COM index cmc ; CY = error jc short COMCheck4 ; invalid COM port mov bh,0 ; BX <- COM port index shl bx,1 ; BX <- offset in address table cmp word [400h+bx],1 ; check if COM port address is valid COMCheck4: pop bx ; pop BX ret ; ----------------------------------------------------------------------------- ; Get number of COM ports ; ----------------------------------------------------------------------------- ; OUTPUT: AL = number of COM ports ; ----------------------------------------------------------------------------- COMGetNum: mov al,COM_MAX ; AL <- counter of COM ports push bx ; push BX mov bl,COM_MAX-1 ; BL <- index of last COM COMGetNum2: call COMCheck ; check COM port sbb al,0 ; decrease number of COM ports dec bl ; BL <- next COM port jns short COMGetNum2 ; check next COM port pop bx ; pop BX ret ; ----------------------------------------------------------------------------- ; Read data from COM port ; ----------------------------------------------------------------------------- ; INPUT: BL = COM port index (0..3) ; CX = number of bytes ; DI = destination buffer ; OUTPUT: CY = invalid COM port or operation error (CX > 0) ; CX = remaining bytes (or CX = 0 if no error NC) ; ----------------------------------------------------------------------------- ; ------------- push registers COMRead: push ax ; push AX push di ; push DI ; ------------- check zero length clc ; clear error flag jcxz COMRead6 ; no data ; ------------- read data COMRead2: call COMRecv ; receive byte from COM port jc short COMRead6 ; error stosb ; store byte to buffer loop COMRead2 ; receive next byte ; ------------- pop registers COMRead6: pop di ; pop DI pop ax ; pop AX ret ; ----------------------------------------------------------------------------- ; Write data to COM port ; ----------------------------------------------------------------------------- ; INPUT: BL = COM port index (0..3) ; CX = number of bytes ; DI = source buffer ; OUTPUT: CY = invalid COM port or operation error (CX > 0) ; CX = remaining bytes (or CX = 0 if no error NC) ; ----------------------------------------------------------------------------- ; ------------- push registers COMWrite: push ax ; push AX push si ; push SI ; ------------- check zero length clc ; clear error flag jcxz COMWrite6 ; no data ; ------------- write data mov si,di ; SI <- source buffer COMWrite2: lodsb ; AL <- load byte from buffer call COMSend ; send byte to COM port jc short COMWrite6 ; error loop COMWrite2 ; send next byte ; ------------- pop registers COMWrite6: pop si ; pop SI pop ax ; pop AX ret