1 /*-------------------------------------------------------------
3 video.c -- VIDEO subsystem
5 Copyright (C) 2004 - 2008
6 Michael Wiedenbauer (shagkur)
7 Dave Murphy (WinterMute)
9 Redistribution and use in source and binary forms, with or without modification,
10 are permitted provided that the following conditions are met:
12 1. Redistributions of source code must retain the above copyright notice,
13 this list of conditions and the following disclaimer.
14 2. Redistributions in binary form must reproduce the above copyright notice,
15 this list of conditions and the following disclaimer in the documentation and/or
16 other materials provided with the distribution.
17 3. The name of the author may not be used to endorse or promote products derived
18 from this software without specific prior written permission.
20 THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
21 WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
22 AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE
23 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
28 EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 -------------------------------------------------------------*/
38 #include "processor.h"
47 #include "video_types.h"
49 //#define _VIDEO_DEBUG
53 #define _SHIFTL(v, s, w) \
54 ((u32) (((u32)(v) & ((0x01 << (w)) - 1)) << (s)))
55 #define _SHIFTR(v, s, w) \
56 ((u32)(((u32)(v) >> (s)) & ((0x01 << (w)) - 1)))
58 #define VI_REGCHANGE(_reg) \
59 ((u64)0x01<<(63-_reg))
61 typedef struct _horVer
{
68 u16 adjustedDispSizeY
;
92 const struct _timing
*timing
;
95 GXRModeObj TVNtsc240Ds
=
97 VI_TVMODE_NTSC_DS
, // viDisplayMode
101 (VI_MAX_WIDTH_NTSC
- 640)/2, // viXOrigin
102 (VI_MAX_HEIGHT_NTSC
- 480)/2, // viYOrigin
105 VI_XFBMODE_SF
, // xFBmode
106 GX_FALSE
, // field_rendering
109 // sample points arranged in increasing Y order
111 {6,6},{6,6},{6,6}, // pix 0, 3 sample points, 1/12 units, 4 bits each
112 {6,6},{6,6},{6,6}, // pix 1
113 {6,6},{6,6},{6,6}, // pix 2
114 {6,6},{6,6},{6,6} // pix 3
117 // vertical filter[7], 1/64 units, 6 bits each
129 GXRModeObj TVNtsc240DsAa
=
131 VI_TVMODE_NTSC_DS
, // viDisplayMode
135 (VI_MAX_WIDTH_NTSC
- 640)/2, // viXOrigin
136 (VI_MAX_HEIGHT_NTSC
- 480)/2, // viYOrigin
139 VI_XFBMODE_SF
, // xFBmode
140 GX_FALSE
, // field_rendering
143 // sample points arranged in increasing Y order
145 {3,2},{9,6},{3,10}, // pix 0, 3 sample points, 1/12 units, 4 bits each
146 {3,2},{9,6},{3,10}, // pix 1
147 {9,2},{3,6},{9,10}, // pix 2
148 {9,2},{3,6},{9,10} // pix 3
151 // vertical filter[7], 1/64 units, 6 bits each
163 GXRModeObj TVNtsc240Int
=
165 VI_TVMODE_NTSC_INT
, // viDisplayMode
169 (VI_MAX_WIDTH_NTSC
- 640)/2, // viXOrigin
170 (VI_MAX_HEIGHT_NTSC
- 480)/2, // viYOrigin
173 VI_XFBMODE_SF
, // xFBmode
174 GX_TRUE
, // field_rendering
177 // sample points arranged in increasing Y order
179 {6,6},{6,6},{6,6}, // pix 0, 3 sample points, 1/12 units, 4 bits each
180 {6,6},{6,6},{6,6}, // pix 1
181 {6,6},{6,6},{6,6}, // pix 2
182 {6,6},{6,6},{6,6} // pix 3
185 // vertical filter[7], 1/64 units, 6 bits each
197 GXRModeObj TVNtsc240IntAa
=
199 VI_TVMODE_NTSC_INT
, // viDisplayMode
203 (VI_MAX_WIDTH_NTSC
- 640)/2, // viXOrigin
204 (VI_MAX_HEIGHT_NTSC
- 480)/2, // viYOrigin
207 VI_XFBMODE_SF
, // xFBmode
208 GX_TRUE
, // field_rendering
211 // sample points arranged in increasing Y order
213 {3,2},{9,6},{3,10}, // pix 0, 3 sample points, 1/12 units, 4 bits each
214 {3,2},{9,6},{3,10}, // pix 1
215 {9,2},{3,6},{9,10}, // pix 2
216 {9,2},{3,6},{9,10} // pix 3
219 // vertical filter[7], 1/64 units, 6 bits each
231 GXRModeObj TVNtsc480Int
=
233 VI_TVMODE_NTSC_INT
, // viDisplayMode
237 (VI_MAX_WIDTH_NTSC
- 640)/2, // viXOrigin
238 (VI_MAX_HEIGHT_NTSC
- 480)/2, // viYOrigin
241 VI_XFBMODE_DF
, // xFBmode
242 GX_FALSE
, // field_rendering
245 // sample points arranged in increasing Y order
247 {6,6},{6,6},{6,6}, // pix 0, 3 sample points, 1/12 units, 4 bits each
248 {6,6},{6,6},{6,6}, // pix 1
249 {6,6},{6,6},{6,6}, // pix 2
250 {6,6},{6,6},{6,6} // pix 3
253 // vertical filter[7], 1/64 units, 6 bits each
265 GXRModeObj TVNtsc480IntDf
=
267 VI_TVMODE_NTSC_INT
, // viDisplayMode
271 (VI_MAX_WIDTH_NTSC
- 640)/2, // viXOrigin
272 (VI_MAX_HEIGHT_NTSC
- 480)/2, // viYOrigin
275 VI_XFBMODE_DF
, // xFBmode
276 GX_FALSE
, // field_rendering
279 // sample points arranged in increasing Y order
281 {6,6},{6,6},{6,6}, // pix 0, 3 sample points, 1/12 units, 4 bits each
282 {6,6},{6,6},{6,6}, // pix 1
283 {6,6},{6,6},{6,6}, // pix 2
284 {6,6},{6,6},{6,6} // pix 3
287 // vertical filter[7], 1/64 units, 6 bits each
299 GXRModeObj TVNtsc480IntAa
=
301 VI_TVMODE_NTSC_INT
, // viDisplayMode
305 (VI_MAX_WIDTH_NTSC
- 640)/2, // viXOrigin
306 (VI_MAX_HEIGHT_NTSC
- 480)/2, // viYOrigin
309 VI_XFBMODE_DF
, // xFBmode
310 GX_FALSE
, // field_rendering
313 // sample points arranged in increasing Y order
315 {3,2},{9,6},{3,10}, // pix 0, 3 sample points, 1/12 units, 4 bits each
316 {3,2},{9,6},{3,10}, // pix 1
317 {9,2},{3,6},{9,10}, // pix 2
318 {9,2},{3,6},{9,10} // pix 3
321 // vertical filter[7], 1/64 units, 6 bits each
334 GXRModeObj TVNtsc480Prog
=
336 VI_TVMODE_NTSC_PROG
, // viDisplayMode
340 (VI_MAX_WIDTH_NTSC
- 640)/2, // viXOrigin
341 (VI_MAX_HEIGHT_NTSC
- 480)/2, // viYOrigin
344 VI_XFBMODE_SF
, // xFBmode
345 GX_FALSE
, // field_rendering
348 // sample points arranged in increasing Y order
350 {6,6},{6,6},{6,6}, // pix 0, 3 sample points, 1/12 units, 4 bits each
351 {6,6},{6,6},{6,6}, // pix 1
352 {6,6},{6,6},{6,6}, // pix 2
353 {6,6},{6,6},{6,6} // pix 3
356 // vertical filter[7], 1/64 units, 6 bits each
368 GXRModeObj TVNtsc480ProgSoft
=
370 VI_TVMODE_NTSC_PROG
, // viDisplayMode
374 (VI_MAX_WIDTH_NTSC
- 640)/2, // viXOrigin
375 (VI_MAX_HEIGHT_NTSC
- 480)/2, // viYOrigin
378 VI_XFBMODE_SF
, // xFBmode
379 GX_FALSE
, // field_rendering
382 // sample points arranged in increasing Y order
384 {6,6},{6,6},{6,6}, // pix 0, 3 sample points, 1/12 units, 4 bits each
385 {6,6},{6,6},{6,6}, // pix 1
386 {6,6},{6,6},{6,6}, // pix 2
387 {6,6},{6,6},{6,6} // pix 3
390 // vertical filter[7], 1/64 units, 6 bits each
402 GXRModeObj TVNtsc480ProgAa
=
404 VI_TVMODE_NTSC_PROG
, // viDisplayMode
408 (VI_MAX_WIDTH_NTSC
- 640)/2, // viXOrigin
409 (VI_MAX_HEIGHT_NTSC
- 480)/2, // viYOrigin
412 VI_XFBMODE_SF
, // xFBmode
413 GX_FALSE
, // field_rendering
416 // sample points arranged in increasing Y order
418 {3,2},{9,6},{3,10}, // pix 0, 3 sample points, 1/12 units, 4 bits each
419 {3,2},{9,6},{3,10}, // pix 1
420 {9,2},{3,6},{9,10}, // pix 2
421 {9,2},{3,6},{9,10} // pix 3
424 // vertical filter[7], 1/64 units, 6 bits each
436 GXRModeObj TVMpal480IntDf
=
438 VI_TVMODE_MPAL_INT
, // viDisplayMode
442 (VI_MAX_WIDTH_MPAL
- 640)/2, // viXOrigin
443 (VI_MAX_HEIGHT_MPAL
- 480)/2, // viYOrigin
446 VI_XFBMODE_DF
, // xFBmode
447 GX_FALSE
, // field_rendering
450 // sample points arranged in increasing Y order
452 {6,6},{6,6},{6,6}, // pix 0, 3 sample points, 1/12 units, 4 bits each
453 {6,6},{6,6},{6,6}, // pix 1
454 {6,6},{6,6},{6,6}, // pix 2
455 {6,6},{6,6},{6,6} // pix 3
458 // vertical filter[7], 1/64 units, 6 bits each
470 GXRModeObj TVPal264Ds
=
472 VI_TVMODE_PAL_DS
, // viDisplayMode
476 (VI_MAX_WIDTH_PAL
- 640)/2, // viXOrigin
477 (VI_MAX_HEIGHT_PAL
- 528)/2, // viYOrigin
480 VI_XFBMODE_SF
, // xFBmode
481 GX_FALSE
, // field_rendering
484 // sample points arranged in increasing Y order
486 {6,6},{6,6},{6,6}, // pix 0, 3 sample points, 1/12 units, 4 bits each
487 {6,6},{6,6},{6,6}, // pix 1
488 {6,6},{6,6},{6,6}, // pix 2
489 {6,6},{6,6},{6,6} // pix 3
492 // vertical filter[7], 1/64 units, 6 bits each
504 GXRModeObj TVPal264DsAa
=
506 VI_TVMODE_PAL_DS
, // viDisplayMode
510 (VI_MAX_WIDTH_PAL
- 640)/2, // viXOrigin
511 (VI_MAX_HEIGHT_PAL
- 528)/2, // viYOrigin
514 VI_XFBMODE_SF
, // xFBmode
515 GX_FALSE
, // field_rendering
518 // sample points arranged in increasing Y order
520 {3,2},{9,6},{3,10}, // pix 0, 3 sample points, 1/12 units, 4 bits each
521 {3,2},{9,6},{3,10}, // pix 1
522 {9,2},{3,6},{9,10}, // pix 2
523 {9,2},{3,6},{9,10} // pix 3
526 // vertical filter[7], 1/64 units, 6 bits each
538 GXRModeObj TVPal264Int
=
540 VI_TVMODE_PAL_INT
, // viDisplayMode
544 (VI_MAX_WIDTH_PAL
- 640)/2, // viXOrigin
545 (VI_MAX_HEIGHT_PAL
- 528)/2, // viYOrigin
548 VI_XFBMODE_SF
, // xFBmode
549 GX_TRUE
, // field_rendering
552 // sample points arranged in increasing Y order
554 {6,6},{6,6},{6,6}, // pix 0, 3 sample points, 1/12 units, 4 bits each
555 {6,6},{6,6},{6,6}, // pix 1
556 {6,6},{6,6},{6,6}, // pix 2
557 {6,6},{6,6},{6,6} // pix 3
560 // vertical filter[7], 1/64 units, 6 bits each
572 GXRModeObj TVPal264IntAa
=
574 VI_TVMODE_PAL_INT
, // viDisplayMode
578 (VI_MAX_WIDTH_PAL
- 640)/2, // viXOrigin
579 (VI_MAX_HEIGHT_PAL
- 528)/2, // viYOrigin
582 VI_XFBMODE_SF
, // xFBmode
583 GX_TRUE
, // field_rendering
586 // sample points arranged in increasing Y order
588 {3,2},{9,6},{3,10}, // pix 0, 3 sample points, 1/12 units, 4 bits each
589 {3,2},{9,6},{3,10}, // pix 1
590 {9,2},{3,6},{9,10}, // pix 2
591 {9,2},{3,6},{9,10} // pix 3
594 // vertical filter[7], 1/64 units, 6 bits each
606 GXRModeObj TVPal524IntAa
=
612 (VI_MAX_WIDTH_PAL
-640)/2,
613 (VI_MAX_HEIGHT_PAL
-528)/2,
620 // sample points arranged in increasing Y order
622 {3,2},{9,6},{3,10}, // pix 0, 3 sample points, 1/12 units, 4 bits each
623 {3,2},{9,6},{3,10}, // pix 1
624 {9,2},{3,6},{9,10}, // pix 2
625 {9,2},{3,6},{9,10} // pix 3
628 // vertical filter[7], 1/64 units, 6 bits each
640 GXRModeObj TVPal528Int
=
642 VI_TVMODE_PAL_INT
, // viDisplayMode
646 (VI_MAX_WIDTH_PAL
- 640)/2, // viXOrigin
647 (VI_MAX_HEIGHT_PAL
- 528)/2, // viYOrigin
650 VI_XFBMODE_DF
, // xFBmode
651 GX_FALSE
, // field_rendering
654 // sample points arranged in increasing Y order
656 {6,6},{6,6},{6,6}, // pix 0, 3 sample points, 1/12 units, 4 bits each
657 {6,6},{6,6},{6,6}, // pix 1
658 {6,6},{6,6},{6,6}, // pix 2
659 {6,6},{6,6},{6,6} // pix 3
662 // vertical filter[7], 1/64 units, 6 bits each
674 GXRModeObj TVPal528IntDf
=
676 VI_TVMODE_PAL_INT
, // viDisplayMode
680 (VI_MAX_WIDTH_PAL
- 640)/2, // viXOrigin
681 (VI_MAX_HEIGHT_PAL
- 528)/2, // viYOrigin
684 VI_XFBMODE_DF
, // xFBmode
685 GX_FALSE
, // field_rendering
688 // sample points arranged in increasing Y order
690 {6,6},{6,6},{6,6}, // pix 0, 3 sample points, 1/12 units, 4 bits each
691 {6,6},{6,6},{6,6}, // pix 1
692 {6,6},{6,6},{6,6}, // pix 2
693 {6,6},{6,6},{6,6} // pix 3
695 // vertical filter[7], 1/64 units, 6 bits each
707 GXRModeObj TVPal574IntDfScale
=
709 VI_TVMODE_PAL_INT
, // viDisplayMode
713 (VI_MAX_WIDTH_PAL
- 640)/2, // viXOrigin
714 (VI_MAX_HEIGHT_PAL
- 574)/2, // viYOrigin
717 VI_XFBMODE_DF
, // xFBmode
718 GX_FALSE
, // field_rendering
721 // sample points arranged in increasing Y order
723 {6,6},{6,6},{6,6}, // pix 0, 3 sample points, 1/12 units, 4 bits each
724 {6,6},{6,6},{6,6}, // pix 1
725 {6,6},{6,6},{6,6}, // pix 2
726 {6,6},{6,6},{6,6} // pix 3
728 // vertical filter[7], 1/64 units, 6 bits each
740 GXRModeObj TVEurgb60Hz240Ds
=
742 VI_TVMODE_EURGB60_DS
, // viDisplayMode
746 (VI_MAX_WIDTH_EURGB60
- 640)/2, // viXOrigin
747 (VI_MAX_HEIGHT_EURGB60
- 480)/2, // viYOrigin
750 VI_XFBMODE_SF
, // xFBmode
751 GX_FALSE
, // field_rendering
754 // sample points arranged in increasing Y order
756 {6,6},{6,6},{6,6}, // pix 0, 3 sample points, 1/12 units, 4 bits each
757 {6,6},{6,6},{6,6}, // pix 1
758 {6,6},{6,6},{6,6}, // pix 2
759 {6,6},{6,6},{6,6} // pix 3
761 // vertical filter[7], 1/64 units, 6 bits each
773 GXRModeObj TVEurgb60Hz240DsAa
=
775 VI_TVMODE_EURGB60_DS
, // viDisplayMode
779 (VI_MAX_WIDTH_EURGB60
- 640)/2, // viXOrigin
780 (VI_MAX_HEIGHT_EURGB60
- 480)/2, // viYOrigin
783 VI_XFBMODE_SF
, // xFBmode
784 GX_FALSE
, // field_rendering
787 // sample points arranged in increasing Y order
789 {3,2},{9,6},{3,10}, // pix 0, 3 sample points, 1/12 units, 4 bits each
790 {3,2},{9,6},{3,10}, // pix 1
791 {9,2},{3,6},{9,10}, // pix 2
792 {9,2},{3,6},{9,10} // pix 3
794 // vertical filter[7], 1/64 units, 6 bits each
806 GXRModeObj TVEurgb60Hz240Int
=
808 VI_TVMODE_EURGB60_INT
, // viDisplayMode
812 (VI_MAX_WIDTH_EURGB60
- 640)/2, // viXOrigin
813 (VI_MAX_HEIGHT_EURGB60
- 480)/2, // viYOrigin
816 VI_XFBMODE_SF
, // xFBmode
817 GX_TRUE
, // field_rendering
820 // sample points arranged in increasing Y order
822 {6,6},{6,6},{6,6}, // pix 0, 3 sample points, 1/12 units, 4 bits each
823 {6,6},{6,6},{6,6}, // pix 1
824 {6,6},{6,6},{6,6}, // pix 2
825 {6,6},{6,6},{6,6} // pix 3
827 // vertical filter[7], 1/64 units, 6 bits each
839 GXRModeObj TVEurgb60Hz240IntAa
=
841 VI_TVMODE_EURGB60_INT
, // viDisplayMode
845 (VI_MAX_WIDTH_EURGB60
- 640)/2, // viXOrigin
846 (VI_MAX_HEIGHT_EURGB60
- 480)/2, // viYOrigin
849 VI_XFBMODE_SF
, // xFBmode
850 GX_TRUE
, // field_rendering
853 // sample points arranged in increasing Y order
855 {3,2},{9,6},{3,10}, // pix 0, 3 sample points, 1/12 units, 4 bits each
856 {3,2},{9,6},{3,10}, // pix 1
857 {9,2},{3,6},{9,10}, // pix 2
858 {9,2},{3,6},{9,10} // pix 3
860 // vertical filter[7], 1/64 units, 6 bits each
872 GXRModeObj TVEurgb60Hz480Int
=
874 VI_TVMODE_EURGB60_INT
, // viDisplayMode
878 (VI_MAX_WIDTH_EURGB60
- 640)/2, // viXOrigin
879 (VI_MAX_HEIGHT_EURGB60
- 480)/2, // viYOrigin
882 VI_XFBMODE_DF
, // xFBmode
883 GX_FALSE
, // field_rendering
886 // sample points arranged in increasing Y order
888 {6,6},{6,6},{6,6}, // pix 0, 3 sample points, 1/12 units, 4 bits each
889 {6,6},{6,6},{6,6}, // pix 1
890 {6,6},{6,6},{6,6}, // pix 2
891 {6,6},{6,6},{6,6} // pix 3
893 // vertical filter[7], 1/64 units, 6 bits each
905 GXRModeObj TVEurgb60Hz480IntDf
=
907 VI_TVMODE_EURGB60_INT
, // viDisplayMode
911 (VI_MAX_WIDTH_EURGB60
- 640)/2, // viXOrigin
912 (VI_MAX_HEIGHT_EURGB60
- 480)/2, // viYOrigin
915 VI_XFBMODE_DF
, // xFBmode
916 GX_FALSE
, // field_rendering
919 // sample points arranged in increasing Y order
921 {6,6},{6,6},{6,6}, // pix 0, 3 sample points, 1/12 units, 4 bits each
922 {6,6},{6,6},{6,6}, // pix 1
923 {6,6},{6,6},{6,6}, // pix 2
924 {6,6},{6,6},{6,6} // pix 3
926 // vertical filter[7], 1/64 units, 6 bits each
938 GXRModeObj TVEurgb60Hz480IntAa
=
940 VI_TVMODE_EURGB60_INT
, // viDisplayMode
944 (VI_MAX_WIDTH_EURGB60
- 640)/2, // viXOrigin
945 (VI_MAX_HEIGHT_EURGB60
- 480)/2, // viYOrigin
948 VI_XFBMODE_DF
, // xFBmode
949 GX_FALSE
, // field_rendering
952 // sample points arranged in increasing Y order
954 {3,2},{9,6},{3,10}, // pix 0, 3 sample points, 1/12 units, 4 bits each
955 {3,2},{9,6},{3,10}, // pix 1
956 {9,2},{3,6},{9,10}, // pix 2
957 {9,2},{3,6},{9,10} // pix 3
959 // vertical filter[7], 1/64 units, 6 bits each
971 GXRModeObj TVEurgb60Hz480Prog
=
973 VI_TVMODE_EURGB60_PROG
, // viDisplayMode
977 (VI_MAX_WIDTH_EURGB60
- 640)/2, // viXOrigin
978 (VI_MAX_HEIGHT_EURGB60
- 480)/2, // viYOrigin
981 VI_XFBMODE_SF
, // xFBmode
982 GX_FALSE
, // field_rendering
985 // sample points arranged in increasing Y order
987 {6,6},{6,6},{6,6}, // pix 0, 3 sample points, 1/12 units, 4 bits each
988 {6,6},{6,6},{6,6}, // pix 1
989 {6,6},{6,6},{6,6}, // pix 2
990 {6,6},{6,6},{6,6} // pix 3
992 // vertical filter[7], 1/64 units, 6 bits each
1004 GXRModeObj TVEurgb60Hz480ProgSoft
=
1006 VI_TVMODE_EURGB60_PROG
, // viDisplayMode
1010 (VI_MAX_WIDTH_EURGB60
- 640)/2, // viXOrigin
1011 (VI_MAX_HEIGHT_EURGB60
- 480)/2, // viYOrigin
1014 VI_XFBMODE_SF
, // xFBmode
1015 GX_FALSE
, // field_rendering
1018 // sample points arranged in increasing Y order
1020 {3,2},{9,6},{3,10}, // pix 0, 3 sample points, 1/12 units, 4 bits each
1021 {3,2},{9,6},{3,10}, // pix 1
1022 {9,2},{3,6},{9,10}, // pix 2
1023 {9,2},{3,6},{9,10} // pix 3
1025 // vertical filter[7], 1/64 units, 6 bits each
1037 GXRModeObj TVEurgb60Hz480ProgAa
=
1039 VI_TVMODE_EURGB60_PROG
, // viDisplayMode
1043 (VI_MAX_WIDTH_EURGB60
- 640)/2, // viXOrigin
1044 (VI_MAX_HEIGHT_EURGB60
- 480)/2, // viYOrigin
1047 VI_XFBMODE_SF
, // xFBmode
1048 GX_FALSE
, // field_rendering
1051 // sample points arranged in increasing Y order
1053 {6,6},{6,6},{6,6}, // pix 0, 3 sample points, 1/12 units, 4 bits each
1054 {6,6},{6,6},{6,6}, // pix 1
1055 {6,6},{6,6},{6,6}, // pix 2
1056 {6,6},{6,6},{6,6} // pix 3
1058 // vertical filter[7], 1/64 units, 6 bits each
1071 static const u16 taps
[26] = {
1072 0x01F0,0x01DC,0x01AE,0x0174,0x0129,0x00DB,
1073 0x008E,0x0046,0x000C,0x00E2,0x00CB,0x00C0,
1074 0x00C4,0x00CF,0x00DE,0x00EC,0x00FC,0x0008,
1075 0x000F,0x0013,0x0013,0x000F,0x000C,0x0008,
1079 static const struct _timing
{
1085 u16 be1
,be2
,be3
,be4
;
1087 u8 hsy
,hcs
,hce
,hbe640
;
1091 } video_timing
[] = {
1094 0x0018,0x0019,0x0003,0x0002,
1095 0x0C,0x0D,0x0C,0x0D,
1096 0x0208,0x0207,0x0208,0x0207,
1098 0x40,0x47,0x69,0xA2,
1104 0x0018,0x0018,0x0004,0x0004,
1105 0x0C,0x0C,0x0C,0x0C,
1106 0x0208,0x0208,0x0208,0x0208,
1108 0x40,0x47,0x69,0xA2,
1114 0x0023,0x0024,0x0001,0x0000,
1115 0x0D,0x0C,0x0B,0x0A,
1116 0x026B,0x026A,0x0269,0x026C,
1118 0x40,0x4B,0x6A,0xAC,
1124 0x0021,0x0021,0x0002,0x0002,
1125 0x0D,0x0B,0x0D,0x0B,
1126 0x026B,0x026D,0x026B,0x026D,
1128 0x40,0x4B,0x6A,0xAC,
1134 0x0018,0x0019,0x0003,0x0002,
1135 0x10,0x0F,0x0E,0x0D,
1136 0x0206,0x0205,0x0204,0x0207,
1138 0x40,0x4E,0x70,0xA2,
1144 0x0018,0x0018,0x0004,0x0004,
1145 0x10,0x0E,0x10,0x0E,
1146 0x0206,0x0208,0x0206,0x0208,
1148 0x40,0x4E,0x70,0xA2,
1154 0x0030,0x0030,0x0006,0x0006,
1155 0x18,0x18,0x18,0x18,
1156 0x040e,0x040e,0x040e,0x040e,
1158 0x40,0x47,0x69,0xa2,
1164 0x002c,0x002c,0x000a,0x000a,
1165 0x18,0x18,0x18,0x18,
1166 0x040e,0x040e,0x040e,0x040e,
1168 0x40,0x47,0x69,0xa8,
1174 0x0018,0x0019,0x0001,0x0000,
1175 0x0C,0x0D,0x0C,0x0D,
1176 0x0208,0x0207,0x0208,0x0207,
1178 0x40,0x47,0x69,0x9F,
1184 0x0030,0x0030,0x0006,0x0006,
1185 0x18,0x18,0x18,0x18,
1186 0x040E,0x040E,0x040E,0x040E,
1188 0x40,0x47,0x69,0xB4,
1195 static u32 vdacFlagRegion
;
1196 static u32 i2cIdentFirst
= 0;
1197 static u32 i2cIdentFlag
= 1;
1198 static u32 oldTvStatus
= 0x03e7;
1199 static u32 oldDtvStatus
= 0x03e7;
1200 static vu32
*_i2cReg
= (u32
*)0xCD800000;
1203 static u16 regs
[60];
1204 static u16 shdw_regs
[60];
1205 static u32 encoderType
,fbSet
= 0;
1206 static s16 displayOffsetH
;
1207 static s16 displayOffsetV
;
1208 static u32 currTvMode
,changeMode
;
1209 static u32 shdw_changeMode
,flushFlag
;
1210 static u64 changed
,shdw_changed
;
1211 static vu32 retraceCount
;
1212 static const struct _timing
*currTiming
;
1213 static lwpq_t video_queue
;
1214 static horVer HorVer
;
1215 static void *currentFb
= NULL
;
1216 static void *nextFb
= NULL
;
1217 static VIRetraceCallback preRetraceCB
= NULL
;
1218 static VIRetraceCallback postRetraceCB
= NULL
;
1219 static VIPositionCallback positionCB
= NULL
;
1221 static vu16
* const _viReg
= (u16
*)0xCC002000;
1223 extern void __UnmaskIrq(u32
);
1224 extern void __MaskIrq(u32
);
1226 extern syssram
* __SYS_LockSram();
1227 extern u32
__SYS_UnlockSram(u32 write
);
1229 extern void __VIClearFramebuffer(void*,u32
,u32
);
1231 extern void udelay(int us
);
1234 static u32 messages$
128 = 0;
1235 static u32 printregs
= 1;
1237 static void printRegs()
1240 printf("displayOffsetH = %d\ndisplayOffsetV = %d\n",displayOffsetH
,displayOffsetV
);
1241 printf("%08x%08x\n",(u32
)(shdw_changed
>>32),(u32
)shdw_changed
);
1243 printf("%04x %04x %04x %04x %04x %04x %04x %04x\n",shdw_regs
[0],shdw_regs
[1],shdw_regs
[2],shdw_regs
[3],shdw_regs
[4],shdw_regs
[5],shdw_regs
[6],shdw_regs
[7]);
1244 printf("%04x %04x %04x %04x %04x %04x %04x %04x\n",shdw_regs
[8],shdw_regs
[9],shdw_regs
[10],shdw_regs
[11],shdw_regs
[12],shdw_regs
[13],shdw_regs
[14],shdw_regs
[15]);
1245 printf("%04x %04x %04x %04x %04x %04x %04x %04x\n",shdw_regs
[16],shdw_regs
[17],shdw_regs
[18],shdw_regs
[19],shdw_regs
[20],shdw_regs
[21],shdw_regs
[22],shdw_regs
[23]);
1246 printf("%04x %04x %04x %04x %04x %04x %04x %04x\n",shdw_regs
[24],shdw_regs
[25],shdw_regs
[26],shdw_regs
[27],shdw_regs
[28],shdw_regs
[29],shdw_regs
[30],shdw_regs
[31]);
1247 printf("%04x %04x %04x %04x %04x %04x %04x %04x\n",shdw_regs
[32],shdw_regs
[33],shdw_regs
[34],shdw_regs
[35],shdw_regs
[36],shdw_regs
[37],shdw_regs
[38],shdw_regs
[39]);
1248 printf("%04x %04x %04x %04x %04x %04x %04x %04x\n",shdw_regs
[40],shdw_regs
[41],shdw_regs
[42],shdw_regs
[43],shdw_regs
[44],shdw_regs
[45],shdw_regs
[46],shdw_regs
[47]);
1249 printf("%04x %04x %04x %04x %04x %04x %04x %04x\n",shdw_regs
[48],shdw_regs
[49],shdw_regs
[50],shdw_regs
[51],shdw_regs
[52],shdw_regs
[53],shdw_regs
[54],shdw_regs
[55]);
1250 printf("%04x %04x %04x %04x\n\n",shdw_regs
[56],shdw_regs
[57],shdw_regs
[58],shdw_regs
[59]);
1252 printf("%04x %04x %04x %04x %04x %04x %04x %04x\n",_viReg
[0],_viReg
[1],_viReg
[2],_viReg
[3],_viReg
[4],_viReg
[5],_viReg
[6],_viReg
[7]);
1253 printf("%04x %04x %04x %04x %04x %04x %04x %04x\n",_viReg
[8],_viReg
[9],_viReg
[10],_viReg
[11],_viReg
[12],_viReg
[13],_viReg
[14],_viReg
[15]);
1254 printf("%04x %04x %04x %04x %04x %04x %04x %04x\n",_viReg
[16],_viReg
[17],_viReg
[18],_viReg
[19],_viReg
[20],_viReg
[21],_viReg
[22],_viReg
[23]);
1255 printf("%04x %04x %04x %04x %04x %04x %04x %04x\n",_viReg
[24],_viReg
[25],_viReg
[26],_viReg
[27],_viReg
[28],_viReg
[29],_viReg
[30],_viReg
[31]);
1256 printf("%04x %04x %04x %04x %04x %04x %04x %04x\n",_viReg
[32],_viReg
[33],_viReg
[34],_viReg
[35],_viReg
[36],_viReg
[37],_viReg
[38],_viReg
[39]);
1257 printf("%04x %04x %04x %04x %04x %04x %04x %04x\n",_viReg
[40],_viReg
[41],_viReg
[42],_viReg
[43],_viReg
[44],_viReg
[45],_viReg
[46],_viReg
[47]);
1258 printf("%04x %04x %04x %04x %04x %04x %04x %04x\n",_viReg
[48],_viReg
[49],_viReg
[50],_viReg
[51],_viReg
[52],_viReg
[53],_viReg
[54],_viReg
[55]);
1259 printf("%04x %04x %04x %04x\n",_viReg
[56],_viReg
[57],_viReg
[58],_viReg
[59]);
1264 static void printDebugCalculations()
1268 printf("HorVer.dispPosX = %d\n",HorVer
.dispPosX
);
1269 printf("HorVer.dispPosY = %d\n",HorVer
.dispPosY
);
1270 printf("HorVer.dispSizeX = %d\n",HorVer
.dispSizeX
);
1271 printf("HorVer.dispSizeY = %d\n",HorVer
.dispSizeY
);
1272 printf("HorVer.adjustedDispPosX = %d\n",HorVer
.adjustedDispPosX
);
1273 printf("HorVer.adjustedDispPosY = %d\n",HorVer
.adjustedDispPosY
);
1274 printf("HorVer.adjustedDispSizeY = %d\n",HorVer
.adjustedDispSizeY
);
1275 printf("HorVer.adjustedPanPosY = %d\n",HorVer
.adjustedPanPosY
);
1276 printf("HorVer.adjustedPanSizeY = %d\n",HorVer
.adjustedPanSizeY
);
1277 printf("HorVer.fbSizeX = %d\n",HorVer
.fbSizeX
);
1278 printf("HorVer.fbSizeY = %d\n",HorVer
.fbSizeY
);
1279 printf("HorVer.panPosX = %d\n",HorVer
.panPosX
);
1280 printf("HorVer.panPosY = %d\n",HorVer
.panPosY
);
1281 printf("HorVer.panSizeX = %d\n",HorVer
.panSizeX
);
1282 printf("HorVer.panSizeY = %d\n",HorVer
.panSizeY
);
1283 printf("HorVer.fbMode = %d\n",HorVer
.fbMode
);
1284 printf("HorVer.nonInter = %d\n",HorVer
.nonInter
);
1285 printf("HorVer.tv = %d\n",HorVer
.tv
);
1286 printf("HorVer.wordPerLine = %d\n",HorVer
.wordPerLine
);
1287 printf("HorVer.wpl = %d\n",HorVer
.wpl
);
1288 printf("HorVer.std = %d\n",HorVer
.std
);
1289 printf("HorVer.xof = %d\n",HorVer
.xof
);
1290 printf("HorVer.bufAddr = %p\n",HorVer
.bufAddr
);
1291 printf("HorVer.tfbb = 0x%08x\n",HorVer
.tfbb
);
1292 printf("HorVer.bfbb = 0x%08x\n",HorVer
.bfbb
);
1293 printf("HorVer.rbufAddr = %p\n",HorVer
.rbufAddr
);
1294 printf("HorVer.rtfbb = 0x%08x\n",HorVer
.rtfbb
);
1295 printf("HorVer.rbfbb = 0x%08x\n",HorVer
.rbfbb
);
1296 printf("HorVer.black = %d\n",HorVer
.black
);
1297 printf("HorVer.threeD = %d\n",HorVer
.threeD
);
1302 static __inline__ u32
cntlzd(u64 bit
)
1304 u32 hi
,lo
,value
= 0;
1306 hi
= (u32
)(bit
>>32);
1310 if(value
>=32) value
+= cntlzw(lo
);
1315 static const struct _timing
* __gettiming(u32 vimode
)
1317 if(vimode
>0x1e) return NULL
;
1320 case VI_TVMODE_NTSC_INT
:
1321 return &video_timing
[0];
1323 case VI_TVMODE_NTSC_DS
:
1324 return &video_timing
[1];
1326 case VI_TVMODE_PAL_INT
:
1327 return &video_timing
[2];
1329 case VI_TVMODE_PAL_DS
:
1330 return &video_timing
[3];
1332 case VI_TVMODE_EURGB60_INT
:
1333 return &video_timing
[0];
1335 case VI_TVMODE_EURGB60_DS
:
1336 return &video_timing
[1];
1338 case VI_TVMODE_MPAL_INT
:
1339 return &video_timing
[4];
1341 case VI_TVMODE_MPAL_DS
:
1342 return &video_timing
[5];
1344 case VI_TVMODE_NTSC_PROG
:
1345 return &video_timing
[6];
1347 case VI_TVMODE_NTSC_PROG_DS
:
1348 return &video_timing
[7];
1350 case VI_TVMODE_DEBUG_PAL_INT
:
1351 return &video_timing
[2];
1353 case VI_TVMODE_DEBUG_PAL_DS
:
1354 return &video_timing
[3];
1363 static inline void __viOpenI2C(u32 channel
)
1365 u32 val
= ((_i2cReg
[49]&~0x8000)|0x4000);
1366 val
|= _SHIFTL(channel
,15,1);
1370 static inline u32
__viSetSCL(u32 channel
)
1372 u32 val
= (_i2cReg
[48]&~0x4000);
1373 val
|= _SHIFTL(channel
,14,1);
1377 static inline u32
__viSetSDA(u32 channel
)
1379 u32 val
= (_i2cReg
[48]&~0x8000);
1380 val
|= _SHIFTL(channel
,15,1);
1385 static inline u32
__viGetSDA()
1387 return _SHIFTR(_i2cReg
[50],15,1);
1390 static inline void __viCheckI2C()
1396 if(__viGetSDA()!=0) i2cIdentFlag
= 1;
1399 static u32
__sendSlaveAddress(u8 addr
)
1403 __viSetSDA(i2cIdentFlag
^1);
1408 if(addr
&0x80) __viSetSDA(i2cIdentFlag
);
1409 else __viSetSDA(i2cIdentFlag
^1);
1425 if(i2cIdentFlag
==1 && __viGetSDA()!=0) return 0;
1427 __viSetSDA(i2cIdentFlag
^1);
1435 static inline void __setInterruptRegs(const struct _timing
*tm
)
1440 if(tm
->nhlines
%2) hlw
= tm
->hlw
;
1441 regs
[24] = 0x1000|((tm
->nhlines
/2)+1);
1443 changed
|= VI_REGCHANGE(24);
1444 changed
|= VI_REGCHANGE(25);
1447 static inline void __setPicConfig(u16 fbSizeX
,u32 xfbMode
,u16 panPosX
,u16 panSizeX
,u8
*wordPerLine
,u8
*std
,u8
*wpl
,u8
*xof
)
1449 *wordPerLine
= (fbSizeX
+15)/16;
1450 *std
= *wordPerLine
;
1451 if(xfbMode
==VI_XFBMODE_DF
) *std
<<= 1;
1454 *wpl
= (*xof
+(panSizeX
+15))/16;
1455 regs
[36] = (*wpl
<<8)|*std
;
1456 changed
|= VI_REGCHANGE(36);
1459 static inline void __setBBIntervalRegs(const struct _timing
*tm
)
1461 regs
[10] = (tm
->be3
<<5)|tm
->bs3
;
1462 regs
[11] = (tm
->be1
<<5)|tm
->bs1
;
1463 changed
|= VI_REGCHANGE(10);
1464 changed
|= VI_REGCHANGE(11);
1466 regs
[12] = (tm
->be4
<<5)|tm
->bs4
;
1467 regs
[13] = (tm
->be2
<<5)|tm
->bs2
;
1468 changed
|= VI_REGCHANGE(12);
1469 changed
|= VI_REGCHANGE(13);
1472 static void __setScalingRegs(u16 panSizeX
,u16 dispSizeX
,s32 threeD
)
1474 if(threeD
) panSizeX
= _SHIFTL(panSizeX
,1,16);
1475 if(panSizeX
<dispSizeX
) {
1476 regs
[37] = 0x1000|((dispSizeX
+(_SHIFTL(panSizeX
,8,16)-1))/dispSizeX
);
1477 regs
[56] = panSizeX
;
1478 changed
|= VI_REGCHANGE(37);
1479 changed
|= VI_REGCHANGE(56);
1482 changed
|= VI_REGCHANGE(37);
1486 static inline void __calcFbbs(u32 bufAddr
,u16 panPosX
,u16 panPosY
,u8 wordperline
,u32 xfbMode
,u16 dispPosY
,u32
*tfbb
,u32
*bfbb
)
1488 u32 bytesPerLine
,tmp
;
1491 bytesPerLine
= (wordperline
<<5)&0x1fe0;
1492 *tfbb
= bufAddr
+((panPosX
<<5)+(panPosY
*bytesPerLine
));
1494 if(xfbMode
==VI_XFBMODE_DF
) *bfbb
= *tfbb
+bytesPerLine
;
1502 *tfbb
= MEM_VIRTUAL_TO_PHYSICAL(*tfbb
);
1503 *bfbb
= MEM_VIRTUAL_TO_PHYSICAL(*bfbb
);
1506 static inline void __setFbbRegs(struct _horVer
*horVer
,u32
*tfbb
,u32
*bfbb
,u32
*rtfbb
,u32
*rbfbb
)
1509 __calcFbbs((u32
)horVer
->bufAddr
,horVer
->panPosX
,horVer
->adjustedPanPosY
,horVer
->wordPerLine
,horVer
->fbMode
,horVer
->adjustedDispPosY
,tfbb
,bfbb
);
1510 if(horVer
->threeD
) __calcFbbs((u32
)horVer
->rbufAddr
,horVer
->panPosX
,horVer
->adjustedPanPosY
,horVer
->wordPerLine
,horVer
->fbMode
,horVer
->adjustedDispPosY
,rtfbb
,rbfbb
);
1513 if((*tfbb
)<0x01000000 && (*bfbb
)<0x01000000
1514 && (*rtfbb
)<0x01000000 && (*rbfbb
)<0x01000000) flag
= 0;
1523 regs
[14] = _SHIFTL(flag
,12,1)|_SHIFTL(horVer
->xof
,8,4)|_SHIFTR(*tfbb
,16,8);
1524 regs
[15] = *tfbb
&0xffff;
1525 changed
|= VI_REGCHANGE(14);
1526 changed
|= VI_REGCHANGE(15);
1528 regs
[18] = _SHIFTR(*bfbb
,16,8);
1529 regs
[19] = *bfbb
&0xffff;
1530 changed
|= VI_REGCHANGE(18);
1531 changed
|= VI_REGCHANGE(19);
1533 if(horVer
->threeD
) {
1534 regs
[16] = _SHIFTR(*rtfbb
,16,8);
1535 regs
[17] = *rtfbb
&0xffff;
1536 changed
|= VI_REGCHANGE(16);
1537 changed
|= VI_REGCHANGE(17);
1539 regs
[20] = _SHIFTR(*rbfbb
,16,8);
1540 regs
[21] = *rbfbb
&0xffff;
1541 changed
|= VI_REGCHANGE(20);
1542 changed
|= VI_REGCHANGE(21);
1546 static inline void __setHorizontalRegs(const struct _timing
*tm
,u16 dispPosX
,u16 dispSizeX
)
1550 regs
[2] = (tm
->hcs
<<8)|tm
->hce
;
1552 changed
|= VI_REGCHANGE(2);
1553 changed
|= VI_REGCHANGE(3);
1555 val1
= (tm
->hbe640
+dispPosX
-40)&0x01ff;
1556 val2
= (tm
->hbs640
+dispPosX
+40)-(720-dispSizeX
);
1557 regs
[4] = (val1
>>9)|(val2
<<1);
1558 regs
[5] = (val1
<<7)|tm
->hsy
;
1559 changed
|= VI_REGCHANGE(4);
1560 changed
|= VI_REGCHANGE(5);
1563 static inline void __setVerticalRegs(u16 dispPosY
,u16 dispSizeY
,u8 equ
,u16 acv
,u16 prbOdd
,u16 prbEven
,u16 psbOdd
,u16 psbEven
,s32 black
)
1569 u32 psbeven
,prbeven
;
1578 prb
= div2
*dispPosY
;
1579 psb
= div2
*(((acv
*div1
)-dispSizeY
)-dispPosY
);
1581 prbodd
= prbEven
+prb
;
1582 psbodd
= psbEven
+psb
;
1583 prbeven
= prbOdd
+prb
;
1584 psbeven
= psbOdd
+psb
;
1586 prbodd
= prbOdd
+prb
;
1587 psbodd
= psbOdd
+psb
;
1588 prbeven
= prbEven
+prb
;
1589 psbeven
= psbEven
+psb
;
1592 tmp
= dispSizeY
/div1
;
1594 prbodd
+= ((tmp
<<1)-2);
1595 prbeven
+= ((tmp
<<1)-2);
1601 regs
[0] = ((tmp
<<4)&~0x0f)|equ
;
1602 changed
|= VI_REGCHANGE(0);
1606 changed
|= VI_REGCHANGE(6);
1607 changed
|= VI_REGCHANGE(7);
1611 changed
|= VI_REGCHANGE(8);
1612 changed
|= VI_REGCHANGE(9);
1615 static inline void __adjustPosition(u16 acv
)
1618 s16 dispPosX
,dispPosY
;
1619 s16 dispSizeY
,maxDispSizeY
;
1621 dispPosX
= (HorVer
.dispPosX
+displayOffsetH
);
1622 if(dispPosX
<=(720-HorVer
.dispSizeX
)) {
1623 if(dispPosX
>=0) HorVer
.adjustedDispPosX
= dispPosX
;
1624 else HorVer
.adjustedDispPosX
= 0;
1625 } else HorVer
.adjustedDispPosX
= (720-HorVer
.dispSizeX
);
1628 if(HorVer
.fbMode
==VI_XFBMODE_SF
) fact
= 2;
1630 field
= HorVer
.dispPosY
&0x0001;
1631 dispPosY
= HorVer
.dispPosY
+displayOffsetV
;
1632 if(dispPosY
>field
) HorVer
.adjustedDispPosY
= dispPosY
;
1633 else HorVer
.adjustedDispPosY
= field
;
1635 dispSizeY
= HorVer
.dispPosY
+HorVer
.dispSizeY
+displayOffsetV
;
1636 maxDispSizeY
= ((acv
<<1)-field
);
1637 if(dispSizeY
>maxDispSizeY
) dispSizeY
-= (acv
<<1)-field
;
1640 dispPosY
= HorVer
.dispPosY
+displayOffsetV
;
1641 if(dispPosY
<field
) dispPosY
-= field
;
1643 HorVer
.adjustedDispSizeY
= HorVer
.dispSizeY
+dispPosY
-dispSizeY
;
1645 dispPosY
= HorVer
.dispPosY
+displayOffsetV
;
1646 if(dispPosY
<field
) dispPosY
-= field
;
1648 HorVer
.adjustedPanPosY
= HorVer
.panPosY
-(dispPosY
/fact
);
1650 dispSizeY
= HorVer
.dispPosY
+HorVer
.dispSizeY
+displayOffsetV
;
1651 if(dispSizeY
>maxDispSizeY
) dispSizeY
-= maxDispSizeY
;
1654 dispPosY
= HorVer
.dispPosY
+displayOffsetV
;
1655 if(dispPosY
<field
) dispPosY
-= field
;
1657 HorVer
.adjustedPanSizeY
= HorVer
.panSizeY
+(dispPosY
/fact
)-(dispSizeY
/fact
);
1660 static inline void __importAdjustingValues()
1665 sram
= __SYS_LockSram();
1666 displayOffsetH
= sram
->display_offsetH
;
1667 __SYS_UnlockSram(0);
1670 if ( CONF_GetDisplayOffsetH(&offset
) == 0 ) {
1671 displayOffsetH
= offset
;
1679 static void __VIInit(u32 vimode
)
1682 u32 vi_mode
,interlace
,progressive
;
1683 const struct _timing
*cur_timing
= NULL
;
1685 vi_mode
= ((vimode
>>2)&0x07);
1686 interlace
= (vimode
&0x01);
1687 progressive
= (vimode
&0x02);
1689 cur_timing
= __gettiming(vimode
);
1691 //reset the interface
1694 while(cnt
<1000) cnt
++;
1697 // now begin to setup the interface
1698 _viReg
[2] = ((cur_timing
->hcs
<<8)|cur_timing
->hce
); //set HCS & HCE
1699 _viReg
[3] = cur_timing
->hlw
; //set Half Line Width
1701 _viReg
[4] = (cur_timing
->hbs640
<<1); //set HBS640
1702 _viReg
[5] = ((cur_timing
->hbe640
<<7)|cur_timing
->hsy
); //set HBE640 & HSY
1704 _viReg
[0] = cur_timing
->equ
;
1706 _viReg
[6] = (cur_timing
->psbOdd
+2); //set PSB odd field
1707 _viReg
[7] = (cur_timing
->prbOdd
+((cur_timing
->acv
<<1)-2)); //set PRB odd field
1709 _viReg
[8] = (cur_timing
->psbEven
+2); //set PSB even field
1710 _viReg
[9] = (cur_timing
->prbEven
+((cur_timing
->acv
<<1)-2)); //set PRB even field
1712 _viReg
[10] = ((cur_timing
->be3
<<5)|cur_timing
->bs3
); //set BE3 & BS3
1713 _viReg
[11] = ((cur_timing
->be1
<<5)|cur_timing
->bs1
); //set BE1 & BS1
1715 _viReg
[12] = ((cur_timing
->be4
<<5)|cur_timing
->bs4
); //set BE4 & BS4
1716 _viReg
[13] = ((cur_timing
->be2
<<5)|cur_timing
->bs2
); //set BE2 & BS2
1718 _viReg
[24] = (0x1000|((cur_timing
->nhlines
/2)+1));
1719 _viReg
[25] = (cur_timing
->hlw
+1);
1721 _viReg
[26] = 0x1001; //set DI1
1722 _viReg
[27] = 0x0001; //set DI1
1723 _viReg
[36] = 0x2828; //set HSR
1725 if(vi_mode
<VI_PAL
&& vi_mode
>=VI_DEBUG_PAL
) vi_mode
= VI_NTSC
;
1727 _viReg
[1] = ((vi_mode
<<8)|0x0005); //set MODE & INT & enable
1728 _viReg
[54] = 0x0001;
1730 _viReg
[1] = ((vi_mode
<<8)|(interlace
<<2)|0x0001);
1731 _viReg
[54] = 0x0000;
1736 static u32
__VISendI2CData(u8 addr
,void *val
,u32 len
)
1742 if(i2cIdentFirst
==0) {
1747 _CPU_ISR_Disable(level
);
1752 __viSetSDA(i2cIdentFlag
);
1755 ret
= __sendSlaveAddress(addr
);
1757 _CPU_ISR_Restore(level
);
1762 for(i
=0;i
<len
;i
++) {
1765 if(c
&0x80) __viSetSDA(i2cIdentFlag
);
1766 else __viSetSDA(i2cIdentFlag
^1);
1780 if(i2cIdentFlag
==1 && __viGetSDA()!=0) {
1781 _CPU_ISR_Restore(level
);
1785 __viSetSDA(i2cIdentFlag
^1);
1791 __viSetSDA(i2cIdentFlag
^1);
1793 __viSetSDA(i2cIdentFlag
);
1795 _CPU_ISR_Restore(level
);
1799 static void __VIWriteI2CRegister8(u8 reg
, u8 data
)
1804 __VISendI2CData(0xe0,buf
,2);
1808 static void __VIWriteI2CRegister16(u8 reg
, u16 data
)
1813 buf
[2] = data
& 0xFF;
1814 __VISendI2CData(0xe0,buf
,3);
1818 static void __VIWriteI2CRegister32(u8 reg
, u32 data
)
1822 buf
[1] = data
>> 24;
1823 buf
[2] = (data
>> 16) & 0xFF;
1824 buf
[3] = (data
>> 8) & 0xFF;
1825 buf
[4] = data
& 0xFF;
1826 __VISendI2CData(0xe0,buf
,5);
1830 static void __VIWriteI2CRegisterBuf(u8 reg
, int size
, u8
*data
)
1834 memcpy(&buf
[1], data
, size
);
1835 __VISendI2CData(0xe0,buf
,size
+1);
1840 static void __VISetYUVSEL(u8 dtvstatus
)
1842 if(currTvMode
==VI_NTSC
) vdacFlagRegion
= 0x0000;
1843 else if(currTvMode
==VI_PAL
|| currTvMode
==VI_EURGB60
) vdacFlagRegion
= 0x0002;
1844 /* FIXME: setting this to 1 causes monochrome output on PAL systems*/
1845 else if(currTvMode
==VI_MPAL
) vdacFlagRegion
= 0x0002;
1846 else vdacFlagRegion
= 0x0000;
1848 __VIWriteI2CRegister8(0x01, _SHIFTL(dtvstatus
,5,3)|(vdacFlagRegion
&0x1f));
1851 static void __VISetFilterEURGB60(u8 enable
)
1853 __VIWriteI2CRegister8(0x6e, enable
);
1857 static void __VISetTiming(u8 timing
)
1861 val
= (_SHIFTL(0x00,8,8)|timing
);
1862 __VISendI2CData(0xe0,&val
,sizeof(u16
));
1866 static void __VISet3in1Output(u8 enable
)
1870 val
= (_SHIFTL(0x04,8,8)|enable
);
1871 __VISendI2CData(0xe0,&val
,sizeof(u16
));
1876 static void __VISetupEncoder(void)
1881 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00,
1882 0x10, 0x00, 0x10, 0x00, 0x10, 0x20, 0x40, 0x60,
1883 0x80, 0xa0, 0xeb, 0x10, 0x00, 0x20, 0x00, 0x40,
1884 0x00, 0x60, 0x00, 0x80, 0x00, 0xa0, 0x00, 0xeb,
1890 tv
= VIDEO_GetCurrentTvMode();
1891 dtv
= (_viReg
[55]&0x01);
1894 // SetRevolutionModeSimple
1896 memset(macrobuf
, 0, 0x1a);
1898 __VIWriteI2CRegister8(0x6a, 1);
1899 __VIWriteI2CRegister8(0x65, 1);
1901 __VIWriteI2CRegister8(0x00, 0);
1902 __VIWriteI2CRegister16(0x71, 0x8e8e);
1903 __VIWriteI2CRegister8(0x02, 7);
1904 __VIWriteI2CRegister16(0x05, 0x0000);
1905 __VIWriteI2CRegister16(0x08, 0x0000);
1906 __VIWriteI2CRegister32(0x7A, 0x00000000);
1909 __VIWriteI2CRegisterBuf(0x40, sizeof(macrobuf
), macrobuf
);
1911 // Sometimes 1 in RGB mode? (reg 1 == 3)
1912 __VIWriteI2CRegister8(0x0A, 0);
1914 __VIWriteI2CRegister8(0x03, 1);
1916 __VIWriteI2CRegisterBuf(0x10, sizeof(gamma
), gamma
);
1918 __VIWriteI2CRegister8(0x04, 1);
1919 __VIWriteI2CRegister32(0x7A, 0x00000000);
1920 __VIWriteI2CRegister16(0x08, 0x0000);
1921 __VIWriteI2CRegister8(0x03, 1);
1923 if(tv
==VI_EURGB60
) __VISetFilterEURGB60(1);
1924 else __VISetFilterEURGB60(0);
1930 static inline void __getCurrentDisplayPosition(u32
*px
,u32
*py
)
1936 vpos
= (_viReg
[22]&0x7ff);
1939 hpos
= (_viReg
[23]&0x7ff);
1940 vpos
= (_viReg
[22]&0x7ff);
1941 } while(vpos_old
!=vpos
);
1946 static inline u32
__getCurrentHalfLine()
1951 __getCurrentDisplayPosition(&hpos
,&vpos
);
1957 return vpos
+(hpos
/currTiming
->hlw
);
1960 static inline u32
__getCurrentFieldEvenOdd()
1964 hline
= __getCurrentHalfLine();
1965 if(hline
<currTiming
->nhlines
) return 1;
1970 static inline u32
__VISetRegs()
1975 if(shdw_changeMode
==1){
1976 if(!__getCurrentFieldEvenOdd()) return 0;
1979 while(shdw_changed
) {
1980 val
= cntlzd(shdw_changed
);
1981 _viReg
[val
] = shdw_regs
[val
];
1982 mask
= VI_REGCHANGE(val
);
1983 shdw_changed
&= ~mask
;
1985 shdw_changeMode
= 0;
1986 currTiming
= HorVer
.timing
;
1987 currTvMode
= HorVer
.tv
;
1994 static void __VIDisplayPositionToXY(s32 xpos
,s32 ypos
,s32
*px
,s32
*py
)
2001 hline
= ((vpos
<<1)+(hpos
/currTiming
->hlw
));
2004 if(HorVer
.nonInter
==0x0000) {
2005 if(hline
<currTiming
->nhlines
) {
2006 val
= currTiming
->prbOdd
+(currTiming
->equ
*3);
2008 val
= (currTiming
->nhlines
-currTiming
->psbOdd
);
2010 *py
= (s32
)(((hline
-(currTiming
->equ
*3))-currTiming
->prbOdd
)&~0x01);
2016 hline
-= currTiming
->psbOdd
;
2017 val
= (currTiming
->prbEven
+(currTiming
->equ
*3));
2019 val
= (currTiming
->nhlines
-currTiming
->psbEven
);
2021 *py
= (s32
)((((hline
-(currTiming
->equ
*3))-currTiming
->prbEven
)&~0x01)+1);
2027 } else if(HorVer
.nonInter
==0x0001) {
2028 if(hline
>=currTiming
->nhlines
) hline
-= currTiming
->nhlines
;
2030 val
= (currTiming
->prbOdd
+(currTiming
->equ
*3));
2032 val
= (currTiming
->nhlines
-currTiming
->psbOdd
);
2034 *py
= (s32
)(((hline
-(currTiming
->equ
*3))-currTiming
->prbOdd
)&~0x01);
2039 } else if(HorVer
.nonInter
==0x0002) {
2040 if(hline
<currTiming
->nhlines
) {
2041 val
= currTiming
->prbOdd
+(currTiming
->equ
*3);
2043 val
= (currTiming
->nhlines
-currTiming
->psbOdd
);
2045 *py
= (s32
)((hline
-(currTiming
->equ
*3))-currTiming
->prbOdd
);
2051 hline
-= currTiming
->psbOdd
;
2052 val
= (currTiming
->prbEven
+(currTiming
->equ
*3));
2054 val
= (currTiming
->nhlines
-currTiming
->psbEven
);
2056 *py
= (s32
)(((hline
-(currTiming
->equ
*3))-currTiming
->prbEven
)&~0x01);
2065 static inline void __VIGetCurrentPosition(s32
*px
,s32
*py
)
2069 __getCurrentDisplayPosition((u32
*)&xpos
,(u32
*)&ypos
);
2070 __VIDisplayPositionToXY(xpos
,ypos
,px
,py
);
2073 static void __VIRetraceHandler(u32 nIrq
,void *pCtx
)
2084 _viReg
[24] = intr
&~0x8000;
2090 _viReg
[26] = intr
&~0x8000;
2096 _viReg
[28] = intr
&~0x8000;
2102 _viReg
[30] = intr
&~0x8000;
2107 if(ret
&0x04 || ret
&0x08) {
2108 if(positionCB
!=NULL
) {
2109 __VIGetCurrentPosition(&xpos
,&ypos
);
2110 positionCB(xpos
,ypos
);
2116 preRetraceCB(retraceCount
);
2121 SI_RefreshSamplingRate();
2125 tv
= VIDEO_GetCurrentTvMode();
2126 dtv
= (_viReg
[55]&0x01);
2127 if(dtv
!=oldDtvStatus
|| tv
!=oldTvStatus
) __VISetYUVSEL(dtv
);
2130 if(tv
!=oldTvStatus
) {
2131 if(tv
==VI_EURGB60
) __VISetFilterEURGB60(1);
2132 else __VISetFilterEURGB60(0);
2137 postRetraceCB(retraceCount
);
2139 LWP_ThreadBroadcast(video_queue
);
2142 void* VIDEO_GetNextFramebuffer()
2147 void* VIDEO_GetCurrentFramebuffer()
2154 u32 level
,vimode
= 0;
2156 _CPU_ISR_Disable(level
);
2158 if(!(_viReg
[1]&0x0001))
2159 __VIInit(VI_TVMODE_NTSC_INT
);
2164 shdw_changeMode
= 0;
2168 _viReg
[38] = ((taps
[1]>>6)|(taps
[2]<<4));
2169 _viReg
[39] = (taps
[0]|_SHIFTL(taps
[1],10,6));
2170 _viReg
[40] = ((taps
[4]>>6)|(taps
[5]<<4));
2171 _viReg
[41] = (taps
[3]|_SHIFTL(taps
[4],10,6));
2172 _viReg
[42] = ((taps
[7]>>6)|(taps
[8]<<4));
2173 _viReg
[43] = (taps
[6]|_SHIFTL(taps
[7],10,6));
2174 _viReg
[44] = (taps
[11]|(taps
[12]<<8));
2175 _viReg
[45] = (taps
[9]|(taps
[10]<<8));
2176 _viReg
[46] = (taps
[15]|(taps
[16]<<8));
2177 _viReg
[47] = (taps
[13]|(taps
[14]<<8));
2178 _viReg
[48] = (taps
[19]|(taps
[20]<<8));
2179 _viReg
[49] = (taps
[17]|(taps
[18]<<8));
2180 _viReg
[50] = (taps
[23]|(taps
[24]<<8));
2181 _viReg
[51] = (taps
[21]|(taps
[22]<<8));
2184 __importAdjustingValues();
2186 HorVer
.nonInter
= _SHIFTR(_viReg
[1],2,1);
2187 HorVer
.tv
= _SHIFTR(_viReg
[1],8,2);
2189 vimode
= HorVer
.nonInter
;
2190 if(HorVer
.tv
!=VI_DEBUG
) vimode
+= (HorVer
.tv
<<2);
2191 currTiming
= __gettiming(vimode
);
2192 currTvMode
= HorVer
.tv
;
2194 regs
[1] = _viReg
[1];
2195 HorVer
.timing
= currTiming
;
2196 HorVer
.dispSizeX
= 640;
2197 HorVer
.dispSizeY
= currTiming
->acv
<<1;
2198 HorVer
.dispPosX
= (VI_MAX_WIDTH_NTSC
-HorVer
.dispSizeX
)/2;
2199 HorVer
.dispPosY
= 0;
2201 __adjustPosition(currTiming
->acv
);
2203 HorVer
.fbSizeX
= 640;
2204 HorVer
.fbSizeY
= currTiming
->acv
<<1;
2207 HorVer
.panSizeX
= 640;
2208 HorVer
.panSizeY
= currTiming
->acv
<<1;
2209 HorVer
.fbMode
= VI_XFBMODE_SF
;
2210 HorVer
.wordPerLine
= 40;
2221 _viReg
[24] &= ~0x8000;
2222 _viReg
[26] &= ~0x8000;
2224 preRetraceCB
= NULL
;
2225 postRetraceCB
= NULL
;
2227 LWP_InitQueue(&video_queue
);
2229 IRQ_Request(IRQ_PI_VI
,__VIRetraceHandler
,NULL
);
2230 __UnmaskIrq(IRQMASK(IRQ_PI_VI
));
2234 _CPU_ISR_Restore(level
);
2237 void VIDEO_Configure(GXRModeObj
*rmode
)
2240 u32 nonint
,vimode
,level
;
2241 const struct _timing
*curtiming
;
2243 if(rmode
->viHeight
&0x0001) printf("VIDEO_Configure(): Odd number(%d) is specified to viHeight\n",rmode
->viHeight
);
2244 if((rmode
->xfbMode
==VI_XFBMODE_DF
|| rmode
->viTVMode
==VI_TVMODE_NTSC_PROG
|| rmode
->viTVMode
==VI_TVMODE_NTSC_PROG_DS
)
2245 && rmode
->xfbHeight
!=rmode
->viHeight
) printf("VIDEO_Configure(): xfbHeight(%d) is not equal to viHeight(%d) when DF XFB mode or progressive mode is specified\n",rmode
->xfbHeight
,rmode
->viHeight
);
2246 if(rmode
->xfbMode
==VI_XFBMODE_SF
&& !(rmode
->viTVMode
==VI_TVMODE_NTSC_PROG
|| rmode
->viTVMode
==VI_TVMODE_NTSC_PROG_DS
)
2247 && (rmode
->xfbHeight
<<1)!=rmode
->viHeight
) printf("VIDEO_Configure(): xfbHeight(%d) is not as twice as viHeight(%d) when SF XFB mode is specified\n",rmode
->xfbHeight
,rmode
->viHeight
);
2249 _CPU_ISR_Disable(level
);
2250 nonint
= (rmode
->viTVMode
&0x0003);
2251 if(nonint
!=HorVer
.nonInter
) {
2253 HorVer
.nonInter
= nonint
;
2255 HorVer
.tv
= _SHIFTR(rmode
->viTVMode
,2,3);
2256 HorVer
.dispPosX
= rmode
->viXOrigin
;
2257 HorVer
.dispPosY
= rmode
->viYOrigin
;
2258 if(HorVer
.nonInter
==VI_NON_INTERLACE
) HorVer
.dispPosY
= HorVer
.dispPosY
<<1;
2260 HorVer
.dispSizeX
= rmode
->viWidth
;
2261 HorVer
.fbSizeX
= rmode
->fbWidth
;
2262 HorVer
.fbSizeY
= rmode
->xfbHeight
;
2263 HorVer
.fbMode
= rmode
->xfbMode
;
2264 HorVer
.panSizeX
= HorVer
.fbSizeX
;
2265 HorVer
.panSizeY
= HorVer
.fbSizeY
;
2269 if(HorVer
.nonInter
==VI_PROGRESSIVE
|| HorVer
.nonInter
==(VI_NON_INTERLACE
|VI_PROGRESSIVE
)) HorVer
.dispSizeY
= HorVer
.panSizeY
;
2270 else if(HorVer
.fbMode
==VI_XFBMODE_SF
) HorVer
.dispSizeY
= HorVer
.panSizeY
<<1;
2271 else HorVer
.dispSizeY
= HorVer
.panSizeY
;
2273 if(HorVer
.nonInter
==(VI_NON_INTERLACE
|VI_PROGRESSIVE
)) HorVer
.threeD
= 1;
2274 else HorVer
.threeD
= 0;
2276 vimode
= VI_TVMODE(HorVer
.tv
,HorVer
.nonInter
);
2277 curtiming
= __gettiming(vimode
);
2278 HorVer
.timing
= curtiming
;
2280 __adjustPosition(curtiming
->acv
);
2282 if(rmode
->viXOrigin
>((curtiming
->hlw
+40)-curtiming
->hbe640
)) printf("VIDEO_Configure(): viXOrigin(%d) cannot be greater than %d in this TV mode\n",rmode
->viXOrigin
,((curtiming
->hlw
+40)-curtiming
->hbe640
));
2283 if((rmode
->viXOrigin
+rmode
->viWidth
)<(680-curtiming
->hbs640
)) printf("VIDEO_Configure(): viXOrigin + viWidth(%d) cannot be less than %d in this TV mode\n",(rmode
->viXOrigin
+rmode
->viWidth
),(680-curtiming
->hbs640
));
2285 if(!encoderType
) HorVer
.tv
= VI_DEBUG
;
2287 __setInterruptRegs(curtiming
);
2289 dcr
= regs
[1]&~0x030c;
2290 dcr
|= _SHIFTL(HorVer
.threeD
,3,1);
2291 if(HorVer
.nonInter
==VI_PROGRESSIVE
|| HorVer
.nonInter
==(VI_NON_INTERLACE
|VI_PROGRESSIVE
)) dcr
|= 0x0004;
2292 else dcr
|= _SHIFTL(HorVer
.nonInter
,2,1);
2293 if(!(HorVer
.tv
==VI_DEBUG_PAL
|| HorVer
.tv
==VI_EURGB60
)) dcr
|= _SHIFTL(HorVer
.tv
,8,2);
2295 changed
|= VI_REGCHANGE(1);
2297 regs
[54] &= ~0x0001;
2298 if(rmode
->viTVMode
==VI_TVMODE_NTSC_PROG
|| rmode
->viTVMode
==VI_TVMODE_NTSC_PROG_DS
) regs
[54] |= 0x0001;
2299 changed
|= VI_REGCHANGE(54);
2301 __setScalingRegs(HorVer
.panSizeX
,HorVer
.dispSizeX
,HorVer
.threeD
);
2302 __setHorizontalRegs(curtiming
,HorVer
.adjustedDispPosX
,HorVer
.dispSizeX
);
2303 __setBBIntervalRegs(curtiming
);
2304 __setPicConfig(HorVer
.fbSizeX
,HorVer
.fbMode
,HorVer
.panPosX
,HorVer
.panSizeX
,&HorVer
.wordPerLine
,&HorVer
.std
,&HorVer
.wpl
,&HorVer
.xof
);
2306 if(fbSet
) __setFbbRegs(&HorVer
,&HorVer
.tfbb
,&HorVer
.bfbb
,&HorVer
.rtfbb
,&HorVer
.rbfbb
);
2308 __setVerticalRegs(HorVer
.adjustedDispPosY
,HorVer
.adjustedDispSizeY
,curtiming
->equ
,curtiming
->acv
,curtiming
->prbOdd
,curtiming
->prbEven
,curtiming
->psbOdd
,curtiming
->psbEven
,HorVer
.black
);
2310 printDebugCalculations();
2312 _CPU_ISR_Restore(level
);
2315 void VIDEO_WaitVSync(void)
2320 _CPU_ISR_Disable(level
);
2321 retcnt
= retraceCount
;
2323 LWP_ThreadSleep(video_queue
);
2324 } while(retraceCount
==retcnt
);
2325 _CPU_ISR_Restore(level
);
2328 void VIDEO_SetFramebuffer(void *fb
)
2332 _CPU_ISR_Disable(level
);
2334 HorVer
.bufAddr
= fb
;
2335 __setFbbRegs(&HorVer
,&HorVer
.tfbb
,&HorVer
.bfbb
,&HorVer
.rtfbb
,&HorVer
.rbfbb
);
2336 _viReg
[14] = regs
[14];
2337 _viReg
[15] = regs
[15];
2339 _viReg
[18] = regs
[18];
2340 _viReg
[19] = regs
[19];
2343 _viReg
[16] = regs
[16];
2344 _viReg
[17] = regs
[17];
2346 _viReg
[20] = regs
[20];
2347 _viReg
[21] = regs
[21];
2349 _CPU_ISR_Restore(level
);
2352 void VIDEO_SetNextFramebuffer(void *fb
)
2356 if((u32
)fb
&0x1f) printf("VIDEO_SetNextFramebuffer(): Frame buffer address (%p) is not 32byte aligned\n",fb
);
2358 _CPU_ISR_Disable(level
);
2360 HorVer
.bufAddr
= fb
;
2361 __setFbbRegs(&HorVer
,&HorVer
.tfbb
,&HorVer
.bfbb
,&HorVer
.rtfbb
,&HorVer
.rbfbb
);
2362 _CPU_ISR_Restore(level
);
2365 void VIDEO_SetNextRightFramebuffer(void *fb
)
2369 _CPU_ISR_Disable(level
);
2371 HorVer
.rbufAddr
= fb
;
2372 __setFbbRegs(&HorVer
,&HorVer
.tfbb
,&HorVer
.bfbb
,&HorVer
.rtfbb
,&HorVer
.rbfbb
);
2373 _CPU_ISR_Restore(level
);
2382 _CPU_ISR_Disable(level
);
2383 shdw_changeMode
|= changeMode
;
2386 shdw_changed
|= changed
;
2388 val
= cntlzd(changed
);
2389 shdw_regs
[val
] = regs
[val
];
2390 mask
= VI_REGCHANGE(val
);
2397 nextFb
= HorVer
.bufAddr
;
2398 _CPU_ISR_Restore(level
);
2401 void VIDEO_SetBlack(boolean black
)
2404 const struct _timing
*curtiming
;
2406 _CPU_ISR_Disable(level
);
2407 HorVer
.black
= black
;
2408 curtiming
= HorVer
.timing
;
2409 __setVerticalRegs(HorVer
.adjustedDispPosY
,HorVer
.dispSizeY
,curtiming
->equ
,curtiming
->acv
,curtiming
->prbOdd
,curtiming
->prbEven
,curtiming
->psbOdd
,curtiming
->psbEven
,HorVer
.black
);
2410 _CPU_ISR_Restore(level
);
2413 u32
VIDEO_GetNextField()
2415 u32 level
,nextfield
;
2417 _CPU_ISR_Disable(level
);
2418 nextfield
= __getCurrentFieldEvenOdd()^1; //we've to swap the result because it shows us only the current field,so we've the next field either even or odd
2419 _CPU_ISR_Restore(level
);
2421 return nextfield
^(HorVer
.adjustedDispPosY
&0x0001); //if the YOrigin is at an odd position we've to swap it again, since the Fb registers are set swapped if this rule applies
2424 u32
VIDEO_GetCurrentTvMode()
2430 _CPU_ISR_Disable(level
);
2433 if(mode
==VI_DEBUG
) tv
= VI_NTSC
;
2434 else if(mode
==VI_EURGB60
) tv
= mode
;
2435 else if(mode
==VI_MPAL
) tv
= VI_MPAL
;
2436 else if(mode
==VI_NTSC
) tv
= VI_NTSC
;
2438 _CPU_ISR_Restore(level
);
2443 GXRModeObj
* VIDEO_GetPreferredMode(GXRModeObj
*mode
)
2450 if ( CONF_GetProgressiveScan() > 0 && VIDEO_HaveComponentCable() ) {
2451 rmode
= &TVNtsc480Prog
;
2454 u32 tvmode
= CONF_GetVideo();
2457 case CONF_VIDEO_NTSC
:
2458 rmode
= &TVNtsc480IntDf
;
2460 case CONF_VIDEO_PAL
:
2461 if ( CONF_GetEuRGB60() > 0 ) {
2462 rmode
= &TVEurgb60Hz480Int
;
2464 rmode
= &TVPal528IntDf
;
2467 case CONF_VIDEO_MPAL
:
2468 rmode
= &TVMpal480IntDf
;
2471 rmode
= &TVNtsc480IntDf
;
2475 u32 tvmode
= VIDEO_GetCurrentTvMode();
2479 rmode
= &TVNtsc480IntDf
;
2482 rmode
= &TVPal528IntDf
;
2485 rmode
= &TVMpal480IntDf
;
2488 rmode
= &TVNtsc480IntDf
;
2493 if ( NULL
!= mode
) {
2494 memcpy( mode
, rmode
, sizeof(GXRModeObj
));
2505 u32
VIDEO_GetCurrentLine()
2507 u32 level
,curr_hl
= 0;
2509 _CPU_ISR_Disable(level
);
2510 curr_hl
= __getCurrentHalfLine();
2511 _CPU_ISR_Restore(level
);
2513 if(curr_hl
>=currTiming
->nhlines
) curr_hl
-=currTiming
->nhlines
;
2519 VIRetraceCallback
VIDEO_SetPreRetraceCallback(VIRetraceCallback callback
)
2522 VIRetraceCallback ret
= preRetraceCB
;
2523 _CPU_ISR_Disable(level
);
2524 preRetraceCB
= callback
;
2525 _CPU_ISR_Restore(level
);
2529 VIRetraceCallback
VIDEO_SetPostRetraceCallback(VIRetraceCallback callback
)
2532 VIRetraceCallback ret
= postRetraceCB
;
2533 _CPU_ISR_Disable(level
);
2534 postRetraceCB
= callback
;
2535 _CPU_ISR_Restore(level
);
2539 void VIDEO_ClearFrameBuffer(GXRModeObj
*rmode
,void *fb
,u32 color
)
2541 u32 size
= VIDEO_PadFramebufferWidth(rmode
->fbWidth
)*rmode
->xfbHeight
*VI_DISPLAY_PIX_SZ
;
2542 __VIClearFramebuffer(fb
,size
,color
);
2545 u32
VIDEO_HaveComponentCable(void)
2547 return (_viReg
[55]&0x01);