⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tvcode.asm

📁 X86 GX1 BOOTLOAD代码 ,支持WINCE操作系统!
💻 ASM
📖 第 1 页 / 共 3 页
字号:
	; we need to reset the position every time to set a known reference.
	; This is done by entering mode 0 and back (if in modes 1-6), or
	; entering mode 1 and back (if in mode 0).

	or	dx, dx			; check if mode 0
	mov	dx, 0			; assume reset with mode 0
	jnz	SetTVMode_ResetPos	; skip if wasn't mode 0
	inc	dx			; reset with mode 1, not mode 0
SetTVMode_ResetPos:
	call	LoadDisplayMode		; Load mode 0 or mode 1

	pop	dx			; restore original mode
LoadDisplayMode:
	mov	cl, CH7002_DISPLAY_MODE
	call	OEMSetTVRegister
	clc
elseif CH7003
; 7003
	push	dx			; save dx
	; 1st load common values
	lea	si, CH7003_tab_common	; point to common table
	call	OEMSetTVRegMulti	; set common values

; mode specific stuff
	pop	dx			; restore input
	push	dx			; save again
	lea	di, ch7003_ntsc_modes	; assume ntsc
	.if (dl & 80h)			; pal?
		lea	di,ch7003_pal_modes	; yes
	.endif
	mov	bx, dx			; get to bx
	and	bx, 03h			; isolate
	shl	bx, 1			; *2 for word access
	mov	si, cs:[di+bx]		; get mode table
	call	OEMSetTVRegMulti	; set values
	pop	dx			; retsore input

; set timings
	lea	di, NTSC_Timings
	.IF	(dl & 80h)
		lea	di, PAL_Timings
	.ENDIF
	mov	bl, dl
	and	bx, 0003h

; Generate offset into timing table
	mov	al, SIZE VIDEO_TIMINGS
	mul	bl
	add	di, ax
	push	cs
	pop	es
	mov	ax, 4F14h		; Set timings
	mov	bx, 0103h
	int	10h

	clc
ELSE
	stc
ENDIF

	ret

VIDEO_TIMINGS struc
	fpResolution	DB	?
	fpControl	DB	?
	fpDither	DB	?
	fpClockFreq	DB	?
	fpHtotal	DB	?
	fpVtotal	DB	?
	fpHsyncStart	DB	?
	fpHsyncEnd	DB	?
	fpVsyncStart	DB	?
	fpVsyncEnd	DB	?
	crtHsyncStart	DB	?
	crtHsyncEnd	DB	?
	crtVsyncStart	DB	?
	crtVsyncEnd	DB	?
VIDEO_TIMINGS ENDS

tblFLATPANEL	label	BYTE
	VIDEO_TIMINGS <00h, 031h, 000h, 50, 014h, 02Dh, 002h, 00Eh, 009h, 00Bh, 002h, 00Eh, 00Ah, 00Ch > ; 640x480
	VIDEO_TIMINGS <01h, 031h, 000h, 80, 020h, 01Ch, 005h, 015h, 000h, 004h, 005h, 015h, 00Bh, 00Fh > ; 800x600

;**************************************************************************
;*  NTSC TIMINGS
;**************************************************************************
IF ch7002
	DB	6	; NTSC - 800 x 600 under
	DB	6	; NTSC - 800 x 600 over
	DB	3	; NTSC - 640 x 480 underscan
	DB	2	; NTSC - 640 x 480 overscan
ENDIF
NTSC_Timings:
IF CH7003
; 640x480 NTSC Overscan
	VIDEO_TIMINGS <20h, 031h, 000h, 51, 014h, 02Dh, 005h, 00Fh, 007h, 00Ah, 005h, 00Fh, 007h, 00Ah >
; 640x480 NTSC Underscan
	VIDEO_TIMINGS <20h, 031h, 000h, 56, 012h, 078h, 005h, 00Fh, 03Ch, 03Fh, 005h, 00Fh, 03Ch, 03Fh >
; 800x600 NTSC Overscan
	VIDEO_TIMINGS <21h, 031h, 000h, 87, 01Eh, 064h, 005h, 015h, 032h, 035h, 005h, 015h, 032h, 035h >
; 800x600 NTSC Underscan
	VIDEO_TIMINGS <21h, 031h, 000h, 87, 01Eh, 064h, 005h, 015h, 032h, 035h, 005h, 015h, 032h, 035h >
ENDIF
IF CH7002
; 640x480 NTSC Overscan
	VIDEO_TIMINGS <00h, 031h, 000h, 51, 014h, 02Dh, 005h, 00Fh, 007h, 00Ah, 005h, 00Fh, 007h, 00Ah >
; 640x480 NTSC Underscan
	VIDEO_TIMINGS <00h, 031h, 000h, 56, 012h, 078h, 005h, 00Fh, 03Ch, 03Fh, 005h, 00Fh, 03Ch, 03Fh >
; 800x600 NTSC Underscan
	VIDEO_TIMINGS <01h, 031h, 000h, 87, 01Eh, 064h, 005h, 015h, 032h, 035h, 005h, 015h, 032h, 035h >
ENDIF

IF AITECH
; 640x480 NTSC Overscan - 2 Hsyncs per Vsync for NTSC
	VIDEO_TIMINGS <00h, 031h, 000h, 50, 014h, 02Dh, 002h, 00Dh, 009h, 00Bh, 002h, 00Bh, 003h, 005h >
; 640x480 NTSC Underscan - Same as overscan - 2 Hsyncs per Vsync for NTSC
	VIDEO_TIMINGS <00h, 031h, 000h, 50, 014h, 02Dh, 002h, 00Dh, 009h, 00Bh, 002h, 00Bh, 003h, 005h >
; 800x600 NTSC Underscan ### NOT USED- MEANING NOT VALID ###
	VIDEO_TIMINGS <01h, 031h, 000h, 80, 020h, 01Ch, 005h, 015h, 000h, 004h, 005h, 015h, 00Bh, 00Fh >
ENDIF

;**************************************************************************
;*		PAL TIMINGS
;**************************************************************************
IF ch7002
	DB	0	; PAL - 800 x 600 under
	DB	0	; PAL - 800 x 600 over
	DB	1	; PAL - 640 x 480 underscan
	DB	4	; PAL - 640 x 480 overscan
ENDIF
PAL_Timings:
IF CH7003
; 640x480 PAL Overscan
	VIDEO_TIMINGS <20h, 031h, 000h, 50, 014h, 091h, 005h, 00Fh, 048h, 04Bh, 005h, 00Fh, 048h, 04Bh >
; 640x480 PAL Underscan
	VIDEO_TIMINGS <20h, 031h, 000h, 50, 014h, 091h, 005h, 00Fh, 048h, 04Bh, 005h, 00Fh, 048h, 04Bh >
; 800x600 PAL Overscan
	VIDEO_TIMINGS <21h, 031h, 000h, 71, 012h, 096h, 001h, 00Ah, 04Bh, 04Eh, 001h, 00Ah, 04Bh, 04Eh >
; 800x600 PAL Underscan
	VIDEO_TIMINGS <21h, 031h, 000h, 71, 012h, 096h, 001h, 00Ah, 04Bh, 04Eh, 001h, 00Ah, 04Bh, 04Eh >
ENDIF

IF CH7002
; 640x480 PAL Overscan
	VIDEO_TIMINGS <00h, 031h, 000h, 50, 014h, 091h, 005h, 00Fh, 048h, 04Bh, 005h, 00Fh, 048h, 04Bh >
; 640x480 PAL Underscan
	VIDEO_TIMINGS <00h, 031h, 000h, 50, 014h, 091h, 005h, 00Fh, 048h, 04Bh, 005h, 00Fh, 048h, 04Bh >
; 800x600 PAL Underscan
	VIDEO_TIMINGS <01h, 031h, 000h, 71, 012h, 096h, 001h, 00Ah, 04Bh, 04Eh, 001h, 00Ah, 04Bh, 04Eh >
ENDIF

IF AITECH
; 640x480 PAL Overscan- 7 Hsyncs per Vsync for PAL
	VIDEO_TIMINGS <00h, 031h, 000h, 50, 015h, 091h, 002h, 00Eh, 038h, 03Fh, 004h, 00Ch, 034h, 03Ah >
; 640x480 PAL Underscan - Same as overscan - 7 Hsyncs per Vsync for PAL
	VIDEO_TIMINGS <00h, 031h, 000h, 50, 015h, 091h, 002h, 00Eh, 038h, 03Fh, 004h, 00Ch, 034h, 03Ah >
; 800x600 PAL Underscan ### NOT USED - MEANING NOT VALID ###
	VIDEO_TIMINGS <01h, 031h, 000h, 80, 020h, 01Ch, 005h, 015h, 000h, 004h, 005h, 015h, 00Bh, 00Fh >
ENDIF
Set_TV_Mode	ENDP

;**************************************************************************
;*
;*	Adjust_TV_Position
;*
;*	This routine adjusts the registers on the TV support chip.  It is
;*	called when an application is centering the image for a certain
;*	mode.
;*
;*	Entry:
;*	  CH = 02
;*	  DL = new signed absolute horizontal position (positive left)
;*	  DH = new signed absolute vertical position (positive down)
;*
;*	Exit:
;*	Destroys:
;*
;**************************************************************************
Adjust_TV_Position	PROC NEAR
IF CH7002
	; GET CURRENT POSITION VALUES
	; For CH7002, we need relative values.

	push	dx			; save new position
; Get current TV position
        mov     ax, 4F14h               ; Geode video BIOS extensions
	mov	bx, 0206h		; Query TV position
	int	10h			; current position returned in CX

	pop	dx			; restore new position
	push	dx
	sub	dl, cl			; relative X
	sub	dh, ch			; relative Y

	call	AdjustTVRelativePosition
	pop	dx
	clc
ENDIF ; CH7002

IF CH7003
	push	cx			; save cx

;	push	dx			; save input
;	; get current mode
;       mov     ax, 04f14h              ; Geode video BIOS extensions
;	mov	bx, 0006h		; get mode
;	int	10h			; call videobios
;	pop	dx			; restore input
;	push	cx			; save mode
; HPR is 9 bits - each bit moves 4 pixels
; just use the value for now
	push	dx			; save input
	mov	cl, CH7003_HPR
	call	OEMSetTVRegister
	pop	dx			; restore input

; VPR is 9 bits -each bit is 2 lines
; max value is PAL-312 ntsc-262
; so lets just use the value for now
	pop	dx
	push	dx
	xchg	dh, dl			; get vert
	mov	cl, CH7003_VPR
	call	OEMSetTVRegister
	pop	dx			; restore input

;	pop	cx			; get mode back

	pop	cx			; restore cx
	clc				; clear carry
ENDIF ; CH7003

	ret
Adjust_TV_Position	ENDP

;**************************************************************************
;*
;*	AdjustTVRelativePosition
;*
;*	This routine adjusts the position if the TV image
;*
;*	Entry:
;*	  If Chrontel CH7002:
;*	    DL = signed horizontal adjustment (positive left)
;*	    DH = signed vertical adjustment (positive down)
;*
;*	Exit:
;*	Destroys:
;*
;**************************************************************************
IF CH7002
AdjustTVRelativePosition PROC NEAR

	mov	ax, dx			; copy adjustment

TVPos_loop:
	test	ah, 07Fh
	jz	SHORT TVPos_horz
	test	ah, 080h
	jnz	SHORT TVPos_up

	; MOVE DOWN
	dec	ah
	mov	dl, CH7002_POSITION_DOWN
	jmp	SHORT TVPos_set

TVPos_up:
	; MOVE UP
	inc	ah
	mov	dl, CH7002_POSITION_UP
	jmp	SHORT TVPos_set

TVPos_horz:
	test	al, 07Fh
	jz	SHORT TVPos_done
	test	al, 080h
	jnz	SHORT TVPos_left

	; MOVE RIGHT
	dec	al
	mov	dl, CH7002_POSITION_RIGHT
	jmp	SHORT TVPos_set

TVPos_left:
	; MOVE LEFT
	inc	al
	mov	dl, CH7002_POSITION_LEFT

TVPos_set:
	push	ax			; save position
	mov	cl,CH7002_POSITION_CONTROL
	call	OEMSetTVRegister	; move screen image

	mov	cl, CH7002_POSITION_CONTROL
	mov	dl, CH7002_POSITION_NONE	; normal register value
	call	OEMSetTVRegister		; set register back to normal

	pop	ax			; restore position
	jmp	TVPos_loop		; branch back for more

TVPos_done:

	clc
	ret

AdjustTVRelativePosition ENDP
ENDIF ; CH7002

;**************************************************************************
;*
;*	Adjust_TV_Brightness
;*
;*	Entry:
;*	  CH = 03
;*	  DL = brightness
;*
;*	Exit:
;*
;*	Destroys:
;*
;**************************************************************************
Adjust_TV_Brightness	PROC NEAR
IF CH7003

	; SET THE "BLACK LEVEL" REGISTER ON THE CH7003
	; 7003 range is 51-208
	; input is 0-255
	; mutlipy by 157 and divide by 255 then add 51 to scale
	mov	al, dl			; get value
	mov	bl, 157
	mul	bl			; multiply by 157
	; ah is result / 255
	add	ah, 51			; add offset
	mov	dl, ah			; to dl
	mov	cl, CH7003_BLR		; CH7003 register
	call	OEMSetTVRegister	; write CH7003 register
ENDIF

IF CH7002
	; SET THE "BLACK LEVEL" REGISTER ON THE CH7002
	shr	dl, 2			; scale down by 4 (0-63)
	add	dl, 52			; add base (52-115)
	mov	cl, CH7002_BLACK_LEVEL	; CH7002 register
	call	OEMSetTVRegister		; write CH7002 register
ENDIF
	clc
	ret
Adjust_TV_Brightness	ENDP

;**************************************************************************
;*
;*	Adjust_TV_Output
;*
;*	Entry:
;*	  CH = 04
;*	  DL = Bit 0: Enable S-video output
;*	       Bit 1: Enable composite output
;*	       Bit 2: Enable contrast circuitry
;*
;*	Exit:
;*
;*	Destroys:
;*
;**************************************************************************
Adjust_TV_Output	PROC NEAR

IF CH7003
	; SET THE "POWER Management" REGISTER ON THE CH7003
;	test	cl, 4h			; check contrast bit
;	jz	TVOut_10
;	or	dl, 80h			; set contrast enhancement
;TVOut_10:

	mov	cl, dl			; copy input parameter
	mov	dl, CH7003_PMR_POWER_DOWN	; assume power down
	and	cl, 3			; keep lower 2 bits
	jz	TVOut_20		; done if power down

	mov	dl, CH7003_PMR_ON	; assume both on
	cmp	cl, 3			; check if both on
	je	TVOut_20		; jump if both on
	mov	dl, CH7003_PMR_S_VID_OFF	; assume S-video off
	cmp	cl, 2			; check if S-video off
	je	TVOut_20		; jump if S-video off
	mov	dl, CH7003_PMR_COMP_OFF	; must be composite off

TVOut_20:
	mov	cl, CH7003_PMR
	call	OEMSetTVRegister	; set outputs

ENDIF

IF CH7002
	; SET THE "MISC CONTROL" REGISTER ON THE CH7002
	mov	cl, dl			; copy input parameter
	mov	dl, 01			; assume power down
	test	cl, 4h			; check contrast bit
	jz	TVOut_10
	or	dl, 80h			; set contrast enhancement
TVOut_10:
	and	cl, 3			; keep lower 2 bits
	jz	TVOut_20		; done if power down
	or	dl, 3			; assume both on
	cmp	cl, 3			; check if both on
	je	TVOut_20		; jump if both on
	and	dl, 0FEh		; assume S-video off
	cmp	cl, 2			; check if S-video off
	je	TVOut_20		; jump if S-video off
	and	dl, 0FCh		; must be composite off

TVOut_20:
	mov	cl, CH7002_MISC_CONTROL
	call	OEMSetTVRegister	; move screen image

ENDIF
	clc
	ret
Adjust_TV_Output	ENDP

;**************************************************************************
;*
;*	Reset_Encoder
;*
;*	This routine resets the encoder after changing modes, if needed.
;*
;*	Entry:
;*	  CH = 05
;*
;*	Exit:
;*	Destroys:
;*
;**************************************************************************
Reset_Encoder PROC NEAR
IF CH7002

;Chrontel has suggested a workaround to a bug in their hardware that causes
;the TV display to go B&W periodically when changing modes. They suggest
;that whenever the TV display mode is changed or the video signal source is
;changed between S-video and Composite, that we do the following in our
;code:
;1. At the very end of the configuration routine, write all 0s to Register 3
;(Sampling Delay Register).
;2. Next write a value of 15 (all 1s ?) to the same register.
;3. Repeat steps 1 and 2 approximately 15 times.
;
;Apparently, flipping all of these bits over and over causes their PLLs in
;the color burst circuitry to resynchronize.

; LOOP 15 TIMES - Do 'F' then '0' to leave at default '0' value.
; MAKE SURE POWER SET TO S-VIDEO AND COMPOSITE

	mov	cx, 15
reset_loop:
	push	cx
	mov	cl, CH7002_SAMPLE_DELAY	; CH7002 register
	mov	dl, 0			; register value
	call	OEMSetTVRegister		; set sense high
	mov	cl, CH7002_SAMPLE_DELAY	; CH7002 register
	mov	dl, 0Fh			; register value
	call	OEMSetTVRegister	; set sense high
	pop	cx
	dec	cx
	jnz	reset_loop

	mov	cl, CH7002_SAMPLE_DELAY
	mov	dl, CH7002_SAMPLE_DEFAULT
	call	OEMSetTVRegister
ENDIF
	clc
	ret
Reset_Encoder ENDP

;**************************************************************************
;*
;*	Return_DDC2_Status
;*
;*	Note that the DDC2 supported bit should only be set if the monitor
;*	acknowledges an access to A0h across the I2C bus.
;*
;*	Entry:
;*	  CH = 10h
;*
;*	Exit:
;*	  CF set if DDC2 supported
;*
;*	Destroys:
;*
;**************************************************************************
Return_DDC2_Status	PROC NEAR
	mov	cx, 8
DDCStatus_loop:
	push	cx

	; START CONDITION
	mov	si, SELECT_DDC
	call	StartCondition

	; WRITE DATA VALUES

	mov	bl, 0A0h
	call	OEMSetI2CData
	pop	cx

	jz	SHORT DDCStatus_yes	; branch if ack = 0
	loop DDCStatus_loop
	clc				; DDC2 not supported
	ret

DDCStatus_yes:
	stc				; DDC2 supported
	ret
Return_DDC2_Status	ENDP

;**************************************************************************
;*
;*	Return_DDC2_Information
;*
;*	This routine reads DDC data from the monitor.
;*
;*	Entry:
;*	  CH = 11h
;*	  ES:DI = DDC data buffer
;*
;*	Exit:
;*	  ES:DI = data stored in DDC buffer
;*
;*	Destroys:
;*	  AX, BX, CX, DX.
;*	  SI must be preserved.
;*
;**************************************************************************
Return_DDC2_Information PROC NEAR

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -