📄 tvcode.asm
字号:
; SAVE PARAMETERS
push si
push di
; CONFIGURE DATA PIN FOR OUTPUT
mov si, SELECT_DDC
; START CONDITION
call StartCondition
; WRITE DATA VALUES
mov bl, 0A0h ; Chip address
call OEMSetI2CData
mov bl, 00 ; startaddr = 0
call OEMSetI2CData
; RESTART CONDITION
call StartCondition
; WRITE CHIP ADDRESS
mov bl, 0A0h + 1
call OEMSetI2CData
call OEMSetI2CClockLow
mov cx, 80h
read_loop:
push cx
call OEMGetI2CData ; bx = read data
mov al, bl
cld
stosb ; store byte in buffer
pop cx
loop read_loop
; STOP CONDITION
call StopCondition
pop di ; restore starting offset
pop si
clc
ret
Return_DDC2_Information ENDP
; BITS FOR SYSTEM BIOS INTERFACE
I2C_CLOCK_VALUE EQU 01h
I2C_DATA_VALUE EQU 02h
I2C_OUTEN_VALUE EQU 04h
I2C_CLOCK_MASK EQU 10h
I2C_DATA_MASK EQU 20h
I2C_OUTEN_MASK EQU 40h
;**************************************************************************
;*
;* OEMInitializeI2C
;*
;* This routine initializes the I2C interface. It configures the
;* clock pin as an output (stays that way forever) and the data pin
;* as an output (switched to an input when needed). It is called
;* once during boot.
;*
;* Entry:
;* Exit:
;* Destroys:
;*
;**************************************************************************
; public OEMInitializeI2C
OEMInitializeI2C PROC NEAR
; STEVE - NEED TO DO THIS IN INITIALIZATION
; MAKE SURE GPIO PINS ARE ENABLED
mov ax, 0bf00h
mov bx, 'CX'
mov cx, 0e02h
int 15h
ret
OEMInitializeI2C ENDP
;**************************************************************************
;*
;* OEM_SetTVRegister
;*
;* This routine loads a register across the I2C bus.
;*
;* Entry:
;* CH = register address
;* DL = value
;*
;* Exit:
;* CX = register address
;*
;* Destroys:
;* AX, DX
;*
;**************************************************************************
OEMSetTVRegister PROC NEAR
IF CH7002
mov bl, CH7002_CHIP_ADDRESS ; CH7002 address
ENDIF
IF CH7003
mov bl, CH7003_CHIP_ADDRESS ; CH7003 address
ENDIF
OEMSetI2CRegister::
mov si, SELECT_I2C
push cx
push dx ; Save parameters to pop in this routine
push cx
push bx
; START CONDITION
call StartCondition
; WRITE DATA VALUES
pop bx ; Get TV chip address
and bl, 0FEh ; Make sure its a write
call OEMSetI2CData
pop bx ; Get register address
call OEMSetI2CData
pop bx ; Get data value
call OEMSetI2CData
; STOP CONDITION
call StopCondition
; RESTORE PARAMETERS
pop cx
ret
OEMSetTVRegister ENDP
;**************************************************************************
;*
;* OEMSetTVRegMulti
;*
;* This routine loads a register table across the I2C bus.
;*
;* Entry:
;* CS:SI = table to load
;*
;* Exit:
;*
;* Destroys:
;* AX, DX
;*
;**************************************************************************
OEMSetTVRegMulti PROC
mov al, cs:[si] ; get reg
cmp al, -1 ; done
je @f ; yes
mov cl, al ; put reg in cl
mov dl, cs:[si+1] ; put data in dl
call OEMSetTVRegister ; set it
inc si ; point to next
inc si
jmp SHORT OEMSetTVRegMulti ; loop for more
@@:
ret ; done
OEMSetTVRegMulti ENDP
;**************************************************************************
;*
;* OEMSetI2CData
;*
;* This routine writes the 8-bit value in BX across the I2C bus.
;*
;* Entry:
;* BL = data value
;* SI = bus select (80h = DDC, 00h = I2C)
;*
;* Exit:
;* ZF set = acknowledge bit = 0
;* ZF clear = acknowledge bit = 1
;*
;* Destroys:
;* AX, BX, CX, DX
;*
;**************************************************************************
OEMSetI2CData PROC NEAR
call OEMSetI2CClockLow ; make sure clock pin is low
mov cx, 8 ; 8 bits to send
OEMSetI2CDataBitLoop:
push bx
push cx
test bl, 80h ; check data bit
jz SHORT OEMSetI2CdataBitLow ; branch if low
call OEMSetI2CDataHigh ; set data pin high
jmp SHORT OEMSetI2CDataBitClock
OEMSetI2CDataBitLow:
call OEMSetI2CDataLow ; set data pin low
OEMSetI2CDataBitClock:
call OEMSetI2CClockHigh ; set clock pin high
call OEMSetI2CClockLow ; set clock pin low
pop cx
pop bx
shl bx, 1 ; justify next bit
loop OEMSetI2CDataBitLoop; next bit
call OEMSetI2CDataLow ; set data low when done
; CONFIGURE DATA PIN AS INPUT FOR ACKNOWLEDGE BIT
call OEMConfigI2CDataIn ; configure data as input
call OEMSetI2CClockHigh ; set clock pin high
call OEMGetI2CPins ; get data pin
push ax
call OEMSetI2CClockLow ; set clock pin low
call OEMConfigI2CDataOut ; configure back as output
pop ax
test al, 02h
ret
OEMSetI2CData ENDP
;**************************************************************************
;*
;* OEMGetI2CRegister
;*
;* This routine loads a register across the I2C bus.
;*
;* Entry:
;* BL = chip address
;* CL = register address
;* SI = bus select (80h = DDC, 00h = I2C)
;*
;* Exit:
;*
;* Destroys:
;* AX, BX, CX, DX
;*
;**************************************************************************
OEMGetI2CRegister PROC NEAR
; SAVE PARAMETERS
push bx
push cx
push bx
; START CONDITION
call StartCondition
; WRITE DATA VALUES
pop bx ; get chip address
call OEMSetI2CData
pop bx ; get register address
call OEMSetI2CData
; RESTART CONDITION
call StartCondition
; WRITE CHIP ADDRESS
pop bx ; get chip address
or bl, 1 ; Make it a read
call OEMSetI2CData
call OEMSetI2CClockLow
call OEMGetI2CData ; bx = read data
; STOP CONDITION
StopCondition::
call OEMConfigI2CDataOut ; Configure DATA pin as OUTPUT
call OEMSetI2CDataLow
call OEMSetI2CClockHigh
call OEMSetI2CDataHigh
jmp OEMSetI2CClockLow
OEMGetI2CRegister ENDP
StartCondition PROC NEAR
call OEMConfigI2CDataOut ; Configure DATA pin as OUTPUT
call OEMSetI2CDataHigh
call OEMSetI2CClockHigh
call OEMSetI2CDataLow
jmp OEMSetI2CClockLow
StartCondition ENDP
;**************************************************************************
;*
;* OEMGetI2CData
;*
;* This routine reads an 8-bit value from the I2C bus
;*
;* Entry:
;* SI = bus select (80h = DDC, 00h = I2C)
;*
;* Exit:
;*
;* Destroys:
;* AX, BX, CX, DX
;*
;**************************************************************************
OEMGetI2CData PROC NEAR
call OEMSetI2CClockLow ; make sure clock pin is low
call OEMConfigI2CDataIn
mov cx, 8 ; 8 bits to read
xor bx, bx
OEMGetI2CDataBitLoop:
call OEMSetI2CClockLow ; set clock pin low
call OEMSetI2CClockLow ; set clock pin low
shl bx, 1
call OEMGetI2CPins
test al, I2C_DATA_VALUE
jz OEMGetI2CDataBitLow
or bx, 01h
OEMGetI2CDataBitLow:
call OEMSetI2CClockHigh ; set clock pin high
call OEMSetI2CClockHigh ; set clock pin high
loop OEMGetI2CDataBitLoop ; next bit
; RESET PIN TO OUTPUT AND GET ACK
call OEMSetI2CClockLow
call OEMConfigI2CDataOut
test si, 80h ; check if I2C
jz getdata_done ; branch if I2C
; CLOCK THROUGH ACKNOWLEDGE BIT
; This is strange. This is needed to get the DDC2 working, which reads
; multiple bytes, but it totally screws up the I2C for the Chrontel
; part, which only reads a byte at a time. No explanation.
call OEMSetI2CDataLow
call OEMSetI2CClockHigh
call OEMSetI2CClockLow
getdata_done:
ret
OEMGetI2CData ENDP
;**************************************************************************
;*
;* OEMSetI2CPins
;*
;* This routine calls the system BIOS to set the appropriate I2C
;* pins. It is abstracted by the system BIOS so that changes to
;* the board (such as which GPIOs or which SuperIO/5510/5520 chip)
;* can be handled there.
;*
;* Entry:
;* DL = Bit 0: Clock value
;* Bit 1: Data value
;* Bit 2: Output enable value
;* Bit 4: Clock mask (only change value when set)
;* Bit 5: Data mask (only change value when set)
;* Bit 6: Output enable mask (only change value when set)
;* SI = bus select (80h = DDC, 00h = I2C)
;*
;* Exit:
;*
;* Destroys:
;* None
;*
;**************************************************************************
; extrn Set_Pins:near
OEMSetI2CPins PROC NEAR
pusha
or dx, si ; set DDC select bit
; call Set_Pins
mov cl, 0 ; set
call geodeI2cDdc
popa
ret
OEMSetI2CPins ENDP
;**************************************************************************
;*
;* OEMGetI2CPins
;*
;* This routine calls the system BIOS to set the appropriate I2C
;* pins. It is abstracted by the system BIOS so that changes to
;* the board (such as which GPIOs or which SuperIO/5510/5520 chip)
;* can be handled there.
;*
;* Entry:
;* SI = DDC/I2C select (80h = DDC, 00h = I2C)
;*
;* Exit:
;* AL = Bit 0: Clock value
;* Bit 1: Data value
;* Bit 2: Output enable value
;*
;* Destroys:
;* None;
;*
;**************************************************************************
; extrn Get_Pins:near
OEMGetI2CPins PROC NEAR
push bx
push cx
push dx
push si
or dx, si ; set DDC select bit
; call Get_Pins
mov cl, 1 ; get
call geodeI2cDdc
pop si
pop dx
pop cx
pop bx
ret
OEMGetI2CPins ENDP
;**************************************************************************
;*
;* OEMConfigI2CDataOut
;*
;* This routine configures the I2C data pin as an output.
;*
;* Entry:
;* SI = DDC/I2C select (80h = DDC, 00h = I2C)
;*
;* Exit:
;*
;* Destroys:
;* DL
;*
;**************************************************************************
OEMConfigI2CDataOut PROC NEAR
mov dl, I2C_OUTEN_MASK or I2C_OUTEN_VALUE
jmp OEMSetI2CPins
OEMConfigI2CDataOut ENDP
;**************************************************************************
;*
;* OEMConfigI2CDataIn
;*
;* This routine configures the I2C data pin as an input.
;*
;* Entry:
;* SI = DDC/I2C select (80h = DDC, 00h = I2C)
;*
;* Exit:
;*
;* Destroys:
;* DL
;*
;**************************************************************************
OEMConfigI2CDataIn PROC NEAR
mov dl, I2C_OUTEN_MASK
jmp OEMSetI2CPins
OEMConfigI2CDataIn ENDP
;**************************************************************************
;*
;* OEMSetI2CClockLow
;*
;* This routine sets the I2C clock pin low.
;*
;* Entry:
;* SI = DDC/I2C select (80h = DDC, 00h = I2C)
;*
;* Exit:
;*
;* Destroys:
;* DL
;*
;**************************************************************************
OEMSetI2CClockLow PROC NEAR
mov dl, I2C_CLOCK_MASK
jmp OEMSetI2CPins
OEMSetI2CClockLow ENDP
;**************************************************************************
;*
;* OEMSetI2CClockHigh
;*
;* This routine sets the I2C clock pin high.
;*
;* Entry: SI = DDC/I2C select (80h = DDC, 00h = I2C)
;*
;* Exit:
;*
;* Destroys:
;* AX, DX
;**************************************************************************
OEMSetI2CClockHigh PROC NEAR
mov dl, I2C_CLOCK_MASK or I2C_CLOCK_VALUE
jmp OEMSetI2CPins
OEMSetI2CClockHigh ENDP
;**************************************************************************
;*
;* OEMSetI2CDataLow
;*
;* This routine sets the I2C data pin low.
;*
;* Entry:
;* SI = DDC/I2C select (80h = DDC, 00h = I2C)
;*
;* Exit:
;*
;* Destroys:
;* DL
;**************************************************************************
OEMSetI2CDataLow PROC NEAR
mov dl, I2C_DATA_MASK
jmp OEMSetI2CPins
OEMSetI2CDataLow ENDP
;**************************************************************************
;*
;* OEMSetI2CDataHigh
;*
;* This routine sets the I2C data pin high.
;*
;* Entry: SI = DDC/I2C select (80h = DDC, 00h = I2C)
;*
;* Exit:
;*
;* Destroys:
;* DL
;**************************************************************************
OEMSetI2CDataHigh PROC NEAR
mov dl, I2C_DATA_MASK or I2C_DATA_VALUE
jmp OEMSetI2CPins
OEMSetI2CDataHigh ENDP
_TEXT ENDS
END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -