📄 tvmpc.asm
字号:
clc
ret
Get_TV_Format ENDP
;**************************************************************************
;*
;* Set_TV_Format
;*
;* Entry:
;* CH = 02
;*
;* Exit:
;* DX = 01 - NTSC
;* = 02 - PAL
;*
;* Destroys:
;*
;**************************************************************************
Set_TV_Format PROC NEAR
and dl, 3
dec dl ; 0 or 1
;;;; mov al,dl ; to al
;;;; mov cx,TOKEN_TV_FORMAT ; format
;;;; call SetNVRAMValue ; setit
call Get_TV_Mode ; set Mode
call Set_TV_Mode ; set it
clc
ret
Set_TV_Format ENDP
;**************************************************************************
;*
;* Get_TV_Mode
;*
;* Entry:
;* CH = 03
;*
;* Exit:
;* DX = 01 - 640x480
;* = 02 - 800x600
;* = 03 - 1024x768 (Not used)
;*
;* Destroys:
;*
;**************************************************************************
Get_TV_Mode PROC NEAR
;;;; mov cx,TOKEN_TV_MODE
;;;; call GetNVRAMValue
mov al, DEFAULT_TV_MODE
inc al ; make 1 relative
mov dl,al
xor dh,dh
clc
ret
Get_TV_Mode ENDP
;**************************************************************************
;*
;* Set_TV_Mode
;*
;* Entry:
;* CH = 04
;* DX = 01 - 640x480
;* = 02 - 800x600
;* = 03 - 1024x768
;*
;
;* Exit:
;*
;* Destroys:
;*
;**************************************************************************
Set_TV_Mode PROC NEAR
;;;; push dx ; save the Mode
;;;; mov cx,TOKEN_TV_OUTPUT
;;;; call GetNVRAMValue
mov al, DEFAULT_TV_OUTPUT
cmp al,TVALUE_TV_OUTPUT_NONE
;;;; pop dx ; Restore the Mode
je TVset_exit
and dx, 3h
dec dx ; 0 or 1
push dx ; save Mode
;;;; mov al,dl ; to al
;;;; mov cx,TOKEN_TV_MODE
;;;; call SetNVRAMValue
; Set TV format
;;;; mov cx,TOKEN_TV_FORMAT
;;;; call GetNVRAMValue
mov al, DEFAULT_TV_FORMAT
push ax ; save format
lea di, NTSC_Common ; Assume NTSC
.if (al == 1) ; PAL?
lea di, PAL_Common ; Yes
.endif
call SetTVRegTable
pop ax ; get format back
; Set TV Resolution
lea di, NTSC_modes ; Assume NTSC
.if (al == 1) ; PAL?
lea di, PAL_modes ; Yes
.endif
pop bx ; get mode
push bx ; save mode again
push ax ; save format
shl bx, 1 ; *2 for word access
mov di, cs:[di+bx] ; Get mode table
call SetTVRegTable
pop ax ; get format
xor bx, bx
; Set VGA timings
lea di, NTSC_Timings
.IF (al == 1)
lea di, PAL_Timings
.ENDIF
pop bx ; get mode
push ax ; Store TV mode (PAL or NTSC)
; Generate offset into timing table
mov al, SIZE VIDEO_TIMINGS
mul bl
add di, ax
; di contains offset to table
push es ; save es
push cs
pop es
mov ax, 4F14h ; Set timings
mov bx, 0103h
int 10h
; Enable flat panel
mov ax, 4f14h
mov bx, 0702h
int 10h
pop es ; restore es
; Re-Set Bhargava Registers (New scaler)
mov dx, GEODE_VIDEO_REV
call GetTVRegister
pop bx ; Restore the TV mode
cmp eax, 157h ; If Bhargava revision is 157h or higher
jnae @f ; Re-Set the TV scaler registers
; This scaler is used on Carmel rev C1 or newer chips
lea di, Bhargava_D_NTSC ; NTSC or PAL ?
.IF (bl)
lea di, Bhargava_D_PAL
.ENDIF
call SetTVRegTable
@@:
call Enable_Encoder
TVset_exit:
clc
ret
Set_TV_Mode ENDP
;**************************************************************************
;*
;* Get_TV_Output
;*
;* Entry:
;* CH = 05
;*
;* Exit:
;* DL - Bit 0: S-Video enabled
;* - Bit 1: Composite enabled
;*
;* Destroys:
;*
;**************************************************************************
Get_TV_Output PROC NEAR
xor dx,dx
;;;; mov cx,TOKEN_TV_OUTPUT
;;;; call GetNVRAMValue
mov al, DEFAULT_TV_OUTPUT
mov dl,al
clc
ret
Get_TV_Output ENDP
;**************************************************************************
;*
;* Set_TV_Output
;*
;* Entry:
;* CH = 06
;* DX = 01 - S_VIDEO
;* = 02 - COMPOSITE
;* = 3 both
;*
;* Exit:
;*
;* Destroys:
;*
;**************************************************************************
Set_TV_Output PROC NEAR
and dl, 3h
;;;; push dx
;;;; mov al,dl
;;;; mov cx,TOKEN_TV_OUTPUT
;;;; call SetNVRAMValue
;;;; pop dx
lea di, S_VIDEO ; Assume S-Video
.if (dl & 02h) ; Composite?
lea di, COMPOSITE ; Yes
.endif
call SetTVRegTable
clc
ret
Set_TV_Output ENDP
;**************************************************************************
;*
;* Get_TV_Position
;*
;* Entry:
;* CH = 07
;*
;* Exit:
;* DL = new signed absolute horizontal position
;* DH = new signed absolute vertical position
;*
;* Destroys:
;*
;**************************************************************************
Get_TV_Position PROC NEAR
;;;; mov cx,TOKEN_TV_HPOS
;;;; call GetNVRAMValue
mov al, DEFAULT_TV_HPOS
mov dl,al
;;;; mov cx,TOKEN_TV_VPOS
;;;; call GetNVRAMValue
mov al, DEFAULT_TV_VPOS
mov dh,al
clc
ret
Get_TV_Position ENDP
;**************************************************************************
;*
;* Set_TV_Position
;*
;* Entry:
;* CH = 08
;* DL = new signed absolute horizontal position
;* DH = new signed absolute vertical position
;*
;* Exit:
;*
;* Destroys:
;*
;**************************************************************************
Set_TV_Position PROC NEAR
;;;; push dx
;;;; mov cx,TOKEN_TV_HPOS
;;;; mov al,dl
;;;; call SetNVRAMValue
;;;; pop dx
push dx
;;;; mov al,dh ; vpos
;;;; mov cx, TOKEN_TV_VPOS
;;;; call SetNVRAMValue
pop bx ; get pos in bx
;************************************************************
; find out what the current difference is between the
; h_disp_end and the h_disp_start as we need this when
; calculating the new h_hisp_end
; This is # active Pixels in line
;************************************************************
; get h_disp_start
mov edx, GEODE_TVOUT_HORIZONTAL_TIMING
call GetTVRegister
ror eax, 16 ; get start to ax
push ax ; save start
mov edx, GEODE_TVOUT_DISPLAY_LINE_END
call GetTVRegister
ror eax, 16 ; Put h_disp_end in ax
pop dx ; get start
sub ax,dx ; calc difference
push ax ; save # active Pixels in line
; Adjust horizontal position
mov edx, GEODE_TVOUT_HORIZONTAL_TIMING
call GetTVRegister
ror eax, 16 ; Put the value in 27:16 bits
mov ah,0 ; clear high part
mov al, bl ; get start pixel
ror eax, 16 ; put back in high part
call SetTVRegister ; re-write
pop ax ; get diff (# active pixels in line)
movzx cx, bl ; get start pos
add ax, cx ; Calculate the new horizontal display end
push ax ; Store the value
; Adjust horizontal display end
mov edx, GEODE_TVOUT_DISPLAY_LINE_END
call GetTVRegister
ror eax, 16 ; Put the value in 27:16 bits
pop ax
ror eax, 16 ; put back in high
; ; Adjust vertical position
;; since this really doesn't set vert pos just stuff a F0 in bh to make it work
; mov bh,0f0h
; mov al, bh
; and ah, 0FCh
call SetTVRegister ; write h_disp_end
clc
ret
Set_TV_Position ENDP
;-----------------------------------------------------------------------------
; Disable_Encoder
;
; This routine disables sync signals, and blank the video output
;-----------------------------------------------------------------------------
Disable_Encoder PROC NEAR
mov edx, GEODE_ENCODER_CTRL1
call GetTVRegister
ror eax, 16
and ah, 77h ; Disable Video timing
or ah, 08h ; Enable blanking
ror eax, 16
call SetTVRegister
mov edx, GEODE_ENCODER_DAC_CTRL
call GetTVRegister
or al, 020h ; Disable TV DAC
call SetTVRegister
clc
ret
Disable_Encoder ENDP
;-----------------------------------------------------------------------------
; Enable_Encoder
;
; This routine enables sync signals, and disables blanking of the video output
;-----------------------------------------------------------------------------
Enable_Encoder PROC NEAR
mov edx, GEODE_ENCODER_CTRL1
call GetTVRegister
ror eax, 16
and ah, 77h ; Disable blanking
or ah, 80h ; Enable Video timing
ror eax, 16
call SetTVRegister
mov edx, GEODE_ENCODER_DAC_CTRL
call GetTVRegister
and al, 0DFh ; Enable TV DAC
call SetTVRegister
clc
ret
Enable_Encoder ENDP
;**************************************************************************
;*
;* GetTVRegister
;*
;* Entry:
;* DX = register to get
;*
;* Exit:
;* EAX = data read
;*
;* Destroys:
;*
;**************************************************************************
GetTVRegister PROC NEAR
push edx
movzx eax, dx
; TV registers are memory mapped to GX_BASE+10000h address, that
; allows to use the cpu registers read function
call CpuMemRegReadStack
mov eax, edx
pop edx
clc
ret
GetTVRegister ENDP
;**************************************************************************
;*
;* SetTVRegister
;*
;* Entry:
;* DX - register to write
;* EAX = data to write
;*
;* Exit:
;* Destroys:
;*
;**************************************************************************
SetTVRegister PROC NEAR
push edx ; Store register index
; csRegWrite requires the register index to be in EAX, and
; the data in EDX
mov edx, eax
pop eax
push eax
ror eax, 16 ; Clear high 16-bits
xor ax, ax
ror eax, 16
; TV registers are memory mapped to GX_BASE+10000h address, that
; allows to use the cpu registers write function
call CpuMemRegWriteStack
pop edx ; Restore register index
clc
ret
SetTVRegister ENDP
;**************************************************************************
;*
;* SetTVRegTable
;*
;* This routine loads a registers table
;*
;* Entry:
;* CS:DI point to table to load
;*
;* Exit:
;*
;* Destroys:
;* AX, EBX, DX
;*
;**************************************************************************
SetTVRegTable PROC NEAR
xor edx, edx ; Clear high word
mov ax, cs:[di] ; Get reg
cmp ax, 0FFFFh ; Done?
je @f ; yes
mov dx, ax
call GetTVRegister
add di, SIZEOF(WORD)
mov ebx, cs:[di] ; Get AND mask
not ebx
and eax, ebx
add di, SIZEOF(DWORD) ; Get OR mask
or eax, cs:[di]
call SetTVRegister ; Set Register
add di, SIZEOF(DWORD) ; Point to next record
jmp short SetTVRegTable ; Loop for more
@@:
ret
SetTVRegTable ENDP
;**************************************************************************
;*
;* SetVideoReg
;*
;* Entry:
;* AX = index
;* BX = value
;*
;* Exit:
;* Destroys:
;*
;**************************************************************************
SetVideoReg PROC NEAR
push edx
push ebx
call CpuMemRegReadStack
pop ebx
or edx, ebx ; EDX = value read
call CpuMemRegWriteStack
pop edx
ret
SetVideoReg ENDP
_TEXT ENDS
END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -