📄 lanc_if.asm
字号:
;; mov com_port, 0 ; COM1
mov com_port, 1 ; COM2
.endif
ret
set_defaults endp
;IN: DS:SI Pointer to first string
; ES:DI Pointer to second string
;OUT: Zero set strings are equal
compare_strings proc uses ax bx cx si di
; get length of first string
push si
xor cx, cx
xor al, al
.repeat
cmp al, ds:[si]
.break .if (zero?)
.untilcxz
not cx
mov bx, cx
pop si
; get length of second string
push di
xor cx, cx
xor al, al
.repeat
cmp al, es:[di]
.break .if (zero?)
.untilcxz
not cx
pop di
cmp bx, cx
.if (!zero?)
; string lengths are different, strings couldn't be the same
ret
.endif
repe cmpsb
cmp cx, 0
ret
compare_strings endp
;=============================================================================
; public functions
;=============================================================================
OPTION PROC:public
;-----------------------------------------------------------------------------
;PUBLIC FUNCTION: lanc_if_init
;
;DESC:
;
;IN: Nothing
;OUT: Nothing
;NOTE:
;-----------------------------------------------------------------------------
lanc_if_init proc far uses ax
mov ax, PRG_DATA_SEGM
mov cs:ds_reg, ax
ret
lanc_if_init endp
;-----------------------------------------------------------------------------
;PUBLIC FUNCTION: lanc_if_deinit
;
;DESC:
;
;IN: Nothing
;OUT: AL Error code
;NOTE:
;-----------------------------------------------------------------------------
lanc_if_deinit proc far uses ds
SET_DS
mov al, NOERROR
ret
lanc_if_deinit endp
;-----------------------------------------------------------------------------
;PUBLIC FUNCTION: lanc_if_set_parameter
;
;DESC:
;
;IN: ES:BX Pointer to a zero-terminated command line string
;OUT: AL Error code
; BL 0: Parameter accepted
; 1: Parameter not for us
;NOTE: The command line may contain LANC_IF specific and other commands.
; The lanc_if_init() function should ignore the other commands.
;
; Command line parameters for the IRdeo interface:
; /COM[1|2|3|4] to select serial port, default is COM1
; e.g.: /COM1
; /X[1|2|3] to select IRdeo LANC port, default is X1
;-----------------------------------------------------------------------------
lanc_if_set_parameter proc far uses si di ds
local accepted:byte
SET_DS
mov accepted, 0
mov di, bx
push cs
pop ds
mov si, offset com1_string
call compare_strings
.if (zero?)
mov com_port, 0
mov accepted, 1
.endif
mov si, offset com2_string
call compare_strings
.if (zero?)
mov com_port, 1
mov accepted, 1
.endif
mov si, offset com3_string
call compare_strings
.if (zero?)
mov com_port, 2
mov accepted, 1
.endif
mov si, offset com4_string
call compare_strings
.if (zero?)
mov com_port, 3
mov accepted, 1
.endif
mov si, offset x1_string
call compare_strings
.if (zero?)
mov lanc_channel, 0
mov accepted, 1
.endif
mov si, offset x2_string
call compare_strings
.if (zero?)
mov lanc_channel, 1
mov accepted, 1
.endif
mov si, offset x3_string
call compare_strings
.if (zero?)
mov lanc_channel, 2
mov accepted, 1
.endif
.if (accepted)
mov bl, 0
.else
mov bl, 1
.endif
mov al, NOERROR
ret
lanc_if_set_parameter endp
;-----------------------------------------------------------------------------
;PUBLIC FUNCTION: lanc_if_open
;
;DESC:
;
;IN: Nothing
;OUT: AL Error code
;NOTE:
;-----------------------------------------------------------------------------
lanc_if_open proc far uses ds
SET_DS
call set_defaults
call init_comport
mov al, lanc_channel
call lanc_if_set_channel
mov al, NOERROR
ret
lanc_if_open endp
;-----------------------------------------------------------------------------
;PUBLIC FUNCTION: lanc_if_close
;
;DESC:
;
;IN: Nothing
;OUT: AL Error code
;NOTE:
;-----------------------------------------------------------------------------
lanc_if_close proc far uses ds
SET_DS
sti
mov al, NOERROR
ret
lanc_if_close endp
;-----------------------------------------------------------------------------
;PUBLIC FUNCTION: lanc_if_set_channel
;
;DESC:
;
;IN: AL = LANC Channel to use (0-2 on IRdeo)
;OUT: AL Error code
;NOTE:
;-----------------------------------------------------------------------------
lanc_if_set_channel proc far uses cx dx ds
SET_DS
IFDEF IRDEO_LANC_INTERFACE
push ax
.if (al > 2)
pop ax
mov al, E__LANC_WRONG_CHANNEL
ret
.endif
inc al ; convert channel from 0-2 to 1-3
mov ah, al
mov dx, ser_port_mcr
in al, dx
or al, ah
out dx, al
mov ecx, 50000
call delay ; wait for channel to stabilize
pop ax
ENDIF ;IFDEF IRDEO_LANC_INTERFACE
mov al, NOERROR
ret
lanc_if_set_channel endp
;-----------------------------------------------------------------------------
;PUBLIC FUNCTION: lanc_if_check_active
;
;DESC:
;
;IN: Nothing
;OUT: AL Error code
; BL 0: LANC bus seems to be active
; 1: LANC bus inactive or data wrong
;NOTE:
;-----------------------------------------------------------------------------
lanc_if_check_active proc far uses ecx dx ds
local result:byte
SET_DS
push ax
push bx
mov result, 0
mov dx, RECEIVE_PORT
mov bh, RECV_MASK
mov ecx, TICKS_PER_SEC / 50
mov bl, RECV_HIGH
call wait_port_ticks
.if (!carry?)
mov bl, RECV_LOW
mov ecx, TICKS_PER_SEC / 50
call wait_port_ticks
.endif
.if carry?
mov result, 1
.endif
done:
pop bx
mov bl, result
pop ax
mov al, NOERROR
ret
lanc_if_check_active endp
;-----------------------------------------------------------------------------
;PUBLIC FUNCTION: lanc_if_calibrate
;
;DESC:
;
;IN: Nothing
;OUT: AL Error code
;NOTE:
;-----------------------------------------------------------------------------
lanc_if_calibrate proc far uses si ds
SET_DS
mov calibrated, 1
call send_calibrate
.if (carry?)
mov al, E__LANC_CALIBRATION_SEND
.endif
done:
ret
lanc_if_calibrate endp
;-----------------------------------------------------------------------------
;PUBLIC FUNCTION: lanc_if_telegram_syncronize
;
;DESC:
;
;IN: Nothing
;OUT: AL Error code
;-----------------------------------------------------------------------------
lanc_if_telegram_syncronize proc far uses ebx cx edx ds
local errorcode:byte
SET_DS
push ax
; ensure interrupts are off
pushf
cli
.if (!calibrated)
mov errorcode, E__LANC_NOT_CALIBRATED
jmp done
.endif
; reset the byte receive counter
mov send_byte_recvd, 0
mov bytes_recvd, 0
mov cx, 17
xor edx, edx
.repeat
call byte_in ; out: al=received byte, ebx=time to start receiving
.if (ebx > edx)
mov edx, ebx
.endif
.untilcxz
shr edx, 2
mov cx, 9
.repeat
call byte_in ; out: al=received byte, ebx=time to start receiving
.break .if (ebx > edx)
.untilcxz
.if (cx == 0)
mov errorcode, E__LANC_TELEGRAMS
jmp done
.endif
; now we have received the first byte of a telegram
inc bytes_recvd
.repeat
call byte_in ; out: al=received byte, ebx=time to start receiving
inc bytes_recvd
.until (bytes_recvd >= 8)
mov bytes_recvd, 0
mov errorcode, NOERROR
done:
; restore previous interrupt state
popf
pop ax
mov al, errorcode
ret
lanc_if_telegram_syncronize endp
;-----------------------------------------------------------------------------
;PUBLIC FUNCTION: lanc_if_receive_telegram
;
;DESC:
;
;IN: Nothing
;OUT: AL Error code
; ES:BX pointer to telegram (only if no error occured)
;
;NOTE: If no errors occured the last 8 received bytes are a telegram.
;-----------------------------------------------------------------------------
lanc_if_receive_telegram proc far uses ecx dx ds
SET_DS
mov al, send_byte_recvd ; maybe the lanc_if_send function did already receive some bytes of this telegram
mov send_byte_recvd, 0 ; reset the counter
mov bytes_recvd, al ; error free received bytes
push ebx
.repeat
call byte_in ; out: al=received byte, ebx=time to start receiving
movzx bx, bytes_recvd
mov recv_data[bx], al
inc bytes_recvd
.until (bytes_recvd >= 8)
pop ebx
push ds
pop es
movzx bx, bytes_recvd
sub bx, 8
add bx, offset recv_data
done:
mov al, NOERROR
ret
lanc_if_receive_telegram endp
;-----------------------------------------------------------------------------
;PUBLIC FUNCTION: lanc_if_send
;
;DESC:
;
;IN: al first byte to send
; ah second byte to send
;OUT: AL Error code
;
;NOTE:
;-----------------------------------------------------------------------------
public lanc_if_send
lanc_if_send proc far uses dx ds
local errorcode:byte
SET_DS
push ax
.if (!calibrated)
mov errorcode, E__LANC_NOT_CALIBRATED
jmp done
.endif
call byte_out
mov recv_data[0], al
mov al, ah
call byte_out
mov recv_data[1], al
mov send_byte_recvd, 2
mov errorcode, NOERROR
done:
pop ax
mov al, errorcode
ret
lanc_if_send endp
MYCODE ENDS
END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -