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 TVMpal480IntAa
=
472 VI_TVMODE_MPAL_INT
, // viDisplayMode
476 (VI_MAX_WIDTH_MPAL
- 640)/2, // viXOrigin
477 (VI_MAX_HEIGHT_MPAL
- 480)/2, // viYOrigin
480 VI_XFBMODE_DF
, // xFBmode
481 GX_FALSE
, // field_rendering
484 // sample points arranged in increasing Y order
486 {3,2},{9,6},{3,10}, // pix 0, 3 sample points, 1/12 units, 4 bits each
487 {3,2},{9,6},{3,10}, // pix 1
488 {9,2},{3,6},{9,10}, // pix 2
489 {9,2},{3,6},{9,10} // pix 3
492 // vertical filter[7], 1/64 units, 6 bits each
504 GXRModeObj TVMpal240Ds
=
506 VI_TVMODE_MPAL_DS
, // viDisplayMode
510 (VI_MAX_WIDTH_MPAL
- 640)/2, // viXOrigin
511 (VI_MAX_HEIGHT_MPAL
- 480)/2, // viYOrigin
514 VI_XFBMODE_SF
, // xFBmode
515 GX_FALSE
, // field_rendering
518 // sample points arranged in increasing Y order
520 {6,6},{6,6},{6,6}, // pix 0, 3 sample points, 1/12 units, 4 bits each
521 {6,6},{6,6},{6,6}, // pix 1
522 {6,6},{6,6},{6,6}, // pix 2
523 {6,6},{6,6},{6,6} // pix 3
526 // vertical filter[7], 1/64 units, 6 bits each
538 GXRModeObj TVMpal240DsAa
=
540 VI_TVMODE_MPAL_DS
, // viDisplayMode
544 (VI_MAX_WIDTH_MPAL
- 640)/2, // viXOrigin
545 (VI_MAX_HEIGHT_MPAL
- 480)/2, // viYOrigin
548 VI_XFBMODE_SF
, // xFBmode
549 GX_FALSE
, // field_rendering
552 // sample points arranged in increasing Y order
554 {3,2},{9,6},{3,10}, // pix 0, 3 sample points, 1/12 units, 4 bits each
555 {3,2},{9,6},{3,10}, // pix 1
556 {9,2},{3,6},{9,10}, // pix 2
557 {9,2},{3,6},{9,10} // pix 3
560 // vertical filter[7], 1/64 units, 6 bits each
572 GXRModeObj TVPal264Ds
=
574 VI_TVMODE_PAL_DS
, // viDisplayMode
578 (VI_MAX_WIDTH_PAL
- 640)/2, // viXOrigin
579 (VI_MAX_HEIGHT_PAL
- 528)/2, // viYOrigin
582 VI_XFBMODE_SF
, // xFBmode
583 GX_FALSE
, // field_rendering
586 // sample points arranged in increasing Y order
588 {6,6},{6,6},{6,6}, // pix 0, 3 sample points, 1/12 units, 4 bits each
589 {6,6},{6,6},{6,6}, // pix 1
590 {6,6},{6,6},{6,6}, // pix 2
591 {6,6},{6,6},{6,6} // pix 3
594 // vertical filter[7], 1/64 units, 6 bits each
606 GXRModeObj TVPal264DsAa
=
608 VI_TVMODE_PAL_DS
, // viDisplayMode
612 (VI_MAX_WIDTH_PAL
- 640)/2, // viXOrigin
613 (VI_MAX_HEIGHT_PAL
- 528)/2, // viYOrigin
616 VI_XFBMODE_SF
, // xFBmode
617 GX_FALSE
, // field_rendering
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 TVPal264Int
=
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_SF
, // xFBmode
651 GX_TRUE
, // 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 TVPal264IntAa
=
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_SF
, // xFBmode
685 GX_TRUE
, // field_rendering
688 // sample points arranged in increasing Y order
690 {3,2},{9,6},{3,10}, // pix 0, 3 sample points, 1/12 units, 4 bits each
691 {3,2},{9,6},{3,10}, // pix 1
692 {9,2},{3,6},{9,10}, // pix 2
693 {9,2},{3,6},{9,10} // pix 3
696 // vertical filter[7], 1/64 units, 6 bits each
708 GXRModeObj TVPal524IntAa
=
714 (VI_MAX_WIDTH_PAL
-640)/2,
715 (VI_MAX_HEIGHT_PAL
-528)/2,
722 // sample points arranged in increasing Y order
724 {3,2},{9,6},{3,10}, // pix 0, 3 sample points, 1/12 units, 4 bits each
725 {3,2},{9,6},{3,10}, // pix 1
726 {9,2},{3,6},{9,10}, // pix 2
727 {9,2},{3,6},{9,10} // pix 3
730 // vertical filter[7], 1/64 units, 6 bits each
742 GXRModeObj TVPal528Int
=
744 VI_TVMODE_PAL_INT
, // viDisplayMode
748 (VI_MAX_WIDTH_PAL
- 640)/2, // viXOrigin
749 (VI_MAX_HEIGHT_PAL
- 528)/2, // viYOrigin
752 VI_XFBMODE_DF
, // xFBmode
753 GX_FALSE
, // field_rendering
756 // sample points arranged in increasing Y order
758 {6,6},{6,6},{6,6}, // pix 0, 3 sample points, 1/12 units, 4 bits each
759 {6,6},{6,6},{6,6}, // pix 1
760 {6,6},{6,6},{6,6}, // pix 2
761 {6,6},{6,6},{6,6} // pix 3
764 // vertical filter[7], 1/64 units, 6 bits each
776 GXRModeObj TVPal528IntDf
=
778 VI_TVMODE_PAL_INT
, // viDisplayMode
782 (VI_MAX_WIDTH_PAL
- 640)/2, // viXOrigin
783 (VI_MAX_HEIGHT_PAL
- 528)/2, // viYOrigin
786 VI_XFBMODE_DF
, // xFBmode
787 GX_FALSE
, // field_rendering
790 // sample points arranged in increasing Y order
792 {6,6},{6,6},{6,6}, // pix 0, 3 sample points, 1/12 units, 4 bits each
793 {6,6},{6,6},{6,6}, // pix 1
794 {6,6},{6,6},{6,6}, // pix 2
795 {6,6},{6,6},{6,6} // pix 3
797 // vertical filter[7], 1/64 units, 6 bits each
809 GXRModeObj TVPal574IntDfScale
=
811 VI_TVMODE_PAL_INT
, // viDisplayMode
815 (VI_MAX_WIDTH_PAL
- 640)/2, // viXOrigin
816 (VI_MAX_HEIGHT_PAL
- 574)/2, // viYOrigin
819 VI_XFBMODE_DF
, // xFBmode
820 GX_FALSE
, // field_rendering
823 // sample points arranged in increasing Y order
825 {6,6},{6,6},{6,6}, // pix 0, 3 sample points, 1/12 units, 4 bits each
826 {6,6},{6,6},{6,6}, // pix 1
827 {6,6},{6,6},{6,6}, // pix 2
828 {6,6},{6,6},{6,6} // pix 3
830 // vertical filter[7], 1/64 units, 6 bits each
842 GXRModeObj TVEurgb60Hz240Ds
=
844 VI_TVMODE_EURGB60_DS
, // viDisplayMode
848 (VI_MAX_WIDTH_EURGB60
- 640)/2, // viXOrigin
849 (VI_MAX_HEIGHT_EURGB60
- 480)/2, // viYOrigin
852 VI_XFBMODE_SF
, // xFBmode
853 GX_FALSE
, // field_rendering
856 // sample points arranged in increasing Y order
858 {6,6},{6,6},{6,6}, // pix 0, 3 sample points, 1/12 units, 4 bits each
859 {6,6},{6,6},{6,6}, // pix 1
860 {6,6},{6,6},{6,6}, // pix 2
861 {6,6},{6,6},{6,6} // pix 3
863 // vertical filter[7], 1/64 units, 6 bits each
875 GXRModeObj TVEurgb60Hz240DsAa
=
877 VI_TVMODE_EURGB60_DS
, // viDisplayMode
881 (VI_MAX_WIDTH_EURGB60
- 640)/2, // viXOrigin
882 (VI_MAX_HEIGHT_EURGB60
- 480)/2, // viYOrigin
885 VI_XFBMODE_SF
, // xFBmode
886 GX_FALSE
, // field_rendering
889 // sample points arranged in increasing Y order
891 {3,2},{9,6},{3,10}, // pix 0, 3 sample points, 1/12 units, 4 bits each
892 {3,2},{9,6},{3,10}, // pix 1
893 {9,2},{3,6},{9,10}, // pix 2
894 {9,2},{3,6},{9,10} // pix 3
896 // vertical filter[7], 1/64 units, 6 bits each
908 GXRModeObj TVEurgb60Hz240Int
=
910 VI_TVMODE_EURGB60_INT
, // viDisplayMode
914 (VI_MAX_WIDTH_EURGB60
- 640)/2, // viXOrigin
915 (VI_MAX_HEIGHT_EURGB60
- 480)/2, // viYOrigin
918 VI_XFBMODE_SF
, // xFBmode
919 GX_TRUE
, // field_rendering
922 // sample points arranged in increasing Y order
924 {6,6},{6,6},{6,6}, // pix 0, 3 sample points, 1/12 units, 4 bits each
925 {6,6},{6,6},{6,6}, // pix 1
926 {6,6},{6,6},{6,6}, // pix 2
927 {6,6},{6,6},{6,6} // pix 3
929 // vertical filter[7], 1/64 units, 6 bits each
941 GXRModeObj TVEurgb60Hz240IntAa
=
943 VI_TVMODE_EURGB60_INT
, // viDisplayMode
947 (VI_MAX_WIDTH_EURGB60
- 640)/2, // viXOrigin
948 (VI_MAX_HEIGHT_EURGB60
- 480)/2, // viYOrigin
951 VI_XFBMODE_SF
, // xFBmode
952 GX_TRUE
, // field_rendering
955 // sample points arranged in increasing Y order
957 {3,2},{9,6},{3,10}, // pix 0, 3 sample points, 1/12 units, 4 bits each
958 {3,2},{9,6},{3,10}, // pix 1
959 {9,2},{3,6},{9,10}, // pix 2
960 {9,2},{3,6},{9,10} // pix 3
962 // vertical filter[7], 1/64 units, 6 bits each
974 GXRModeObj TVEurgb60Hz480Int
=
976 VI_TVMODE_EURGB60_INT
, // viDisplayMode
980 (VI_MAX_WIDTH_EURGB60
- 640)/2, // viXOrigin
981 (VI_MAX_HEIGHT_EURGB60
- 480)/2, // viYOrigin
984 VI_XFBMODE_DF
, // xFBmode
985 GX_FALSE
, // field_rendering
988 // sample points arranged in increasing Y order
990 {6,6},{6,6},{6,6}, // pix 0, 3 sample points, 1/12 units, 4 bits each
991 {6,6},{6,6},{6,6}, // pix 1
992 {6,6},{6,6},{6,6}, // pix 2
993 {6,6},{6,6},{6,6} // pix 3
995 // vertical filter[7], 1/64 units, 6 bits each
1007 GXRModeObj TVEurgb60Hz480IntDf
=
1009 VI_TVMODE_EURGB60_INT
, // viDisplayMode
1013 (VI_MAX_WIDTH_EURGB60
- 640)/2, // viXOrigin
1014 (VI_MAX_HEIGHT_EURGB60
- 480)/2, // viYOrigin
1017 VI_XFBMODE_DF
, // xFBmode
1018 GX_FALSE
, // field_rendering
1021 // sample points arranged in increasing Y order
1023 {6,6},{6,6},{6,6}, // pix 0, 3 sample points, 1/12 units, 4 bits each
1024 {6,6},{6,6},{6,6}, // pix 1
1025 {6,6},{6,6},{6,6}, // pix 2
1026 {6,6},{6,6},{6,6} // pix 3
1028 // vertical filter[7], 1/64 units, 6 bits each
1040 GXRModeObj TVEurgb60Hz480IntAa
=
1042 VI_TVMODE_EURGB60_INT
, // viDisplayMode
1046 (VI_MAX_WIDTH_EURGB60
- 640)/2, // viXOrigin
1047 (VI_MAX_HEIGHT_EURGB60
- 480)/2, // viYOrigin
1050 VI_XFBMODE_DF
, // xFBmode
1051 GX_FALSE
, // field_rendering
1054 // sample points arranged in increasing Y order
1056 {3,2},{9,6},{3,10}, // pix 0, 3 sample points, 1/12 units, 4 bits each
1057 {3,2},{9,6},{3,10}, // pix 1
1058 {9,2},{3,6},{9,10}, // pix 2
1059 {9,2},{3,6},{9,10} // pix 3
1061 // vertical filter[7], 1/64 units, 6 bits each
1073 GXRModeObj TVEurgb60Hz480Prog
=
1075 VI_TVMODE_EURGB60_PROG
, // viDisplayMode
1079 (VI_MAX_WIDTH_EURGB60
- 640)/2, // viXOrigin
1080 (VI_MAX_HEIGHT_EURGB60
- 480)/2, // viYOrigin
1083 VI_XFBMODE_SF
, // xFBmode
1084 GX_FALSE
, // field_rendering
1087 // sample points arranged in increasing Y order
1089 {6,6},{6,6},{6,6}, // pix 0, 3 sample points, 1/12 units, 4 bits each
1090 {6,6},{6,6},{6,6}, // pix 1
1091 {6,6},{6,6},{6,6}, // pix 2
1092 {6,6},{6,6},{6,6} // pix 3
1094 // vertical filter[7], 1/64 units, 6 bits each
1106 GXRModeObj TVEurgb60Hz480ProgSoft
=
1108 VI_TVMODE_EURGB60_PROG
, // viDisplayMode
1112 (VI_MAX_WIDTH_EURGB60
- 640)/2, // viXOrigin
1113 (VI_MAX_HEIGHT_EURGB60
- 480)/2, // viYOrigin
1116 VI_XFBMODE_SF
, // xFBmode
1117 GX_FALSE
, // field_rendering
1120 // sample points arranged in increasing Y order
1122 {3,2},{9,6},{3,10}, // pix 0, 3 sample points, 1/12 units, 4 bits each
1123 {3,2},{9,6},{3,10}, // pix 1
1124 {9,2},{3,6},{9,10}, // pix 2
1125 {9,2},{3,6},{9,10} // pix 3
1127 // vertical filter[7], 1/64 units, 6 bits each
1139 GXRModeObj TVEurgb60Hz480ProgAa
=
1141 VI_TVMODE_EURGB60_PROG
, // viDisplayMode
1145 (VI_MAX_WIDTH_EURGB60
- 640)/2, // viXOrigin
1146 (VI_MAX_HEIGHT_EURGB60
- 480)/2, // viYOrigin
1149 VI_XFBMODE_SF
, // xFBmode
1150 GX_FALSE
, // field_rendering
1153 // sample points arranged in increasing Y order
1155 {6,6},{6,6},{6,6}, // pix 0, 3 sample points, 1/12 units, 4 bits each
1156 {6,6},{6,6},{6,6}, // pix 1
1157 {6,6},{6,6},{6,6}, // pix 2
1158 {6,6},{6,6},{6,6} // pix 3
1160 // vertical filter[7], 1/64 units, 6 bits each
1173 static const u16 taps
[26] = {
1174 0x01F0,0x01DC,0x01AE,0x0174,0x0129,0x00DB,
1175 0x008E,0x0046,0x000C,0x00E2,0x00CB,0x00C0,
1176 0x00C4,0x00CF,0x00DE,0x00EC,0x00FC,0x0008,
1177 0x000F,0x0013,0x0013,0x000F,0x000C,0x0008,
1181 static const struct _timing
{
1187 u16 be1
,be2
,be3
,be4
;
1189 u8 hsy
,hcs
,hce
,hbe640
;
1193 } video_timing
[] = {
1196 0x0018,0x0019,0x0003,0x0002,
1197 0x0C,0x0D,0x0C,0x0D,
1198 0x0208,0x0207,0x0208,0x0207,
1200 0x40,0x47,0x69,0xA2,
1206 0x0018,0x0018,0x0004,0x0004,
1207 0x0C,0x0C,0x0C,0x0C,
1208 0x0208,0x0208,0x0208,0x0208,
1210 0x40,0x47,0x69,0xA2,
1216 0x0023,0x0024,0x0001,0x0000,
1217 0x0D,0x0C,0x0B,0x0A,
1218 0x026B,0x026A,0x0269,0x026C,
1220 0x40,0x4B,0x6A,0xAC,
1226 0x0021,0x0021,0x0002,0x0002,
1227 0x0D,0x0B,0x0D,0x0B,
1228 0x026B,0x026D,0x026B,0x026D,
1230 0x40,0x4B,0x6A,0xAC,
1236 0x0018,0x0019,0x0003,0x0002,
1237 0x10,0x0F,0x0E,0x0D,
1238 0x0206,0x0205,0x0204,0x0207,
1240 0x40,0x4E,0x70,0xA2,
1246 0x0018,0x0018,0x0004,0x0004,
1247 0x10,0x0E,0x10,0x0E,
1248 0x0206,0x0208,0x0206,0x0208,
1250 0x40,0x4E,0x70,0xA2,
1256 0x0030,0x0030,0x0006,0x0006,
1257 0x18,0x18,0x18,0x18,
1258 0x040e,0x040e,0x040e,0x040e,
1260 0x40,0x47,0x69,0xa2,
1266 0x002c,0x002c,0x000a,0x000a,
1267 0x18,0x18,0x18,0x18,
1268 0x040e,0x040e,0x040e,0x040e,
1270 0x40,0x47,0x69,0xa8,
1276 0x0018,0x0019,0x0001,0x0000,
1277 0x0C,0x0D,0x0C,0x0D,
1278 0x0208,0x0207,0x0208,0x0207,
1280 0x40,0x47,0x69,0x9F,
1286 0x0030,0x0030,0x0006,0x0006,
1287 0x18,0x18,0x18,0x18,
1288 0x040E,0x040E,0x040E,0x040E,
1290 0x40,0x47,0x69,0xB4,
1297 static u32 vdacFlagRegion
;
1298 static u32 i2cIdentFirst
= 0;
1299 static u32 i2cIdentFlag
= 1;
1300 static u32 oldTvStatus
= 0x03e7;
1301 static u32 oldDtvStatus
= 0x03e7;
1302 static vu32
* const _i2cReg
= (u32
*)0xCD800000;
1305 static u16 regs
[60];
1306 static u16 shdw_regs
[60];
1307 static u32 encoderType
,fbSet
= 0;
1308 static s16 displayOffsetH
;
1309 static s16 displayOffsetV
;
1310 static u32 currTvMode
,changeMode
;
1311 static u32 shdw_changeMode
,flushFlag
;
1312 static u64 changed
,shdw_changed
;
1313 static vu32 retraceCount
;
1314 static const struct _timing
*currTiming
;
1315 static lwpq_t video_queue
;
1316 static horVer HorVer
;
1317 static void *currentFb
= NULL
;
1318 static void *nextFb
= NULL
;
1319 static VIRetraceCallback preRetraceCB
= NULL
;
1320 static VIRetraceCallback postRetraceCB
= NULL
;
1321 static VIPositionCallback positionCB
= NULL
;
1323 static vu16
* const _viReg
= (u16
*)0xCC002000;
1325 extern syssram
* __SYS_LockSram();
1326 extern u32
__SYS_UnlockSram(u32 write
);
1328 extern void __VIClearFramebuffer(void*,u32
,u32
);
1330 extern void udelay(int us
);
1333 static u32 messages$
128 = 0;
1334 static u32 printregs
= 1;
1336 static void printRegs()
1339 printf("displayOffsetH = %d\ndisplayOffsetV = %d\n",displayOffsetH
,displayOffsetV
);
1340 printf("%08x%08x\n",(u32
)(shdw_changed
>>32),(u32
)shdw_changed
);
1342 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]);
1343 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]);
1344 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]);
1345 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]);
1346 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]);
1347 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]);
1348 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]);
1349 printf("%04x %04x %04x %04x\n\n",shdw_regs
[56],shdw_regs
[57],shdw_regs
[58],shdw_regs
[59]);
1351 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]);
1352 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]);
1353 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]);
1354 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]);
1355 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]);
1356 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]);
1357 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]);
1358 printf("%04x %04x %04x %04x\n",_viReg
[56],_viReg
[57],_viReg
[58],_viReg
[59]);
1363 static void printDebugCalculations()
1367 printf("HorVer.dispPosX = %d\n",HorVer
.dispPosX
);
1368 printf("HorVer.dispPosY = %d\n",HorVer
.dispPosY
);
1369 printf("HorVer.dispSizeX = %d\n",HorVer
.dispSizeX
);
1370 printf("HorVer.dispSizeY = %d\n",HorVer
.dispSizeY
);
1371 printf("HorVer.adjustedDispPosX = %d\n",HorVer
.adjustedDispPosX
);
1372 printf("HorVer.adjustedDispPosY = %d\n",HorVer
.adjustedDispPosY
);
1373 printf("HorVer.adjustedDispSizeY = %d\n",HorVer
.adjustedDispSizeY
);
1374 printf("HorVer.adjustedPanPosY = %d\n",HorVer
.adjustedPanPosY
);
1375 printf("HorVer.adjustedPanSizeY = %d\n",HorVer
.adjustedPanSizeY
);
1376 printf("HorVer.fbSizeX = %d\n",HorVer
.fbSizeX
);
1377 printf("HorVer.fbSizeY = %d\n",HorVer
.fbSizeY
);
1378 printf("HorVer.panPosX = %d\n",HorVer
.panPosX
);
1379 printf("HorVer.panPosY = %d\n",HorVer
.panPosY
);
1380 printf("HorVer.panSizeX = %d\n",HorVer
.panSizeX
);
1381 printf("HorVer.panSizeY = %d\n",HorVer
.panSizeY
);
1382 printf("HorVer.fbMode = %d\n",HorVer
.fbMode
);
1383 printf("HorVer.nonInter = %d\n",HorVer
.nonInter
);
1384 printf("HorVer.tv = %d\n",HorVer
.tv
);
1385 printf("HorVer.wordPerLine = %d\n",HorVer
.wordPerLine
);
1386 printf("HorVer.wpl = %d\n",HorVer
.wpl
);
1387 printf("HorVer.std = %d\n",HorVer
.std
);
1388 printf("HorVer.xof = %d\n",HorVer
.xof
);
1389 printf("HorVer.bufAddr = %p\n",HorVer
.bufAddr
);
1390 printf("HorVer.tfbb = 0x%08x\n",HorVer
.tfbb
);
1391 printf("HorVer.bfbb = 0x%08x\n",HorVer
.bfbb
);
1392 printf("HorVer.rbufAddr = %p\n",HorVer
.rbufAddr
);
1393 printf("HorVer.rtfbb = 0x%08x\n",HorVer
.rtfbb
);
1394 printf("HorVer.rbfbb = 0x%08x\n",HorVer
.rbfbb
);
1395 printf("HorVer.black = %d\n",HorVer
.black
);
1396 printf("HorVer.threeD = %d\n",HorVer
.threeD
);
1401 static __inline__ u32
cntlzd(u64 bit
)
1403 u32 hi
,lo
,value
= 0;
1405 hi
= (u32
)(bit
>>32);
1409 if(value
>=32) value
+= cntlzw(lo
);
1414 static const struct _timing
* __gettiming(u32 vimode
)
1416 if(vimode
>0x1e) return NULL
;
1419 case VI_TVMODE_NTSC_INT
:
1420 return &video_timing
[0];
1422 case VI_TVMODE_NTSC_DS
:
1423 return &video_timing
[1];
1425 case VI_TVMODE_PAL_INT
:
1426 return &video_timing
[2];
1428 case VI_TVMODE_PAL_DS
:
1429 return &video_timing
[3];
1431 case VI_TVMODE_EURGB60_INT
:
1432 return &video_timing
[0];
1434 case VI_TVMODE_EURGB60_DS
:
1435 return &video_timing
[1];
1437 case VI_TVMODE_MPAL_INT
:
1438 return &video_timing
[4];
1440 case VI_TVMODE_MPAL_DS
:
1441 return &video_timing
[5];
1443 case VI_TVMODE_NTSC_PROG
:
1444 return &video_timing
[6];
1446 case VI_TVMODE_NTSC_PROG_DS
:
1447 return &video_timing
[7];
1449 case VI_TVMODE_DEBUG_PAL_INT
:
1450 return &video_timing
[2];
1452 case VI_TVMODE_DEBUG_PAL_DS
:
1453 return &video_timing
[3];
1462 static inline void __viOpenI2C(u32 channel
)
1464 u32 val
= ((_i2cReg
[49]&~0x8000)|0x4000);
1465 val
|= _SHIFTL(channel
,15,1);
1469 static inline u32
__viSetSCL(u32 channel
)
1471 u32 val
= (_i2cReg
[48]&~0x4000);
1472 val
|= _SHIFTL(channel
,14,1);
1476 static inline u32
__viSetSDA(u32 channel
)
1478 u32 val
= (_i2cReg
[48]&~0x8000);
1479 val
|= _SHIFTL(channel
,15,1);
1484 static inline u32
__viGetSDA()
1486 return _SHIFTR(_i2cReg
[50],15,1);
1489 static inline void __viCheckI2C()
1495 if(__viGetSDA()!=0) i2cIdentFlag
= 1;
1498 static u32
__sendSlaveAddress(u8 addr
)
1502 __viSetSDA(i2cIdentFlag
^1);
1507 if(addr
&0x80) __viSetSDA(i2cIdentFlag
);
1508 else __viSetSDA(i2cIdentFlag
^1);
1524 if(i2cIdentFlag
==1 && __viGetSDA()!=0) return 0;
1526 __viSetSDA(i2cIdentFlag
^1);
1534 static inline void __setInterruptRegs(const struct _timing
*tm
)
1539 if(tm
->nhlines
%2) hlw
= tm
->hlw
;
1540 regs
[24] = 0x1000|((tm
->nhlines
/2)+1);
1542 changed
|= VI_REGCHANGE(24);
1543 changed
|= VI_REGCHANGE(25);
1546 static inline void __setPicConfig(u16 fbSizeX
,u32 xfbMode
,u16 panPosX
,u16 panSizeX
,u8
*wordPerLine
,u8
*std
,u8
*wpl
,u8
*xof
)
1548 *wordPerLine
= (fbSizeX
+15)/16;
1549 *std
= *wordPerLine
;
1550 if(xfbMode
==VI_XFBMODE_DF
) *std
<<= 1;
1553 *wpl
= (*xof
+(panSizeX
+15))/16;
1554 regs
[36] = (*wpl
<<8)|*std
;
1555 changed
|= VI_REGCHANGE(36);
1558 static inline void __setBBIntervalRegs(const struct _timing
*tm
)
1560 regs
[10] = (tm
->be3
<<5)|tm
->bs3
;
1561 regs
[11] = (tm
->be1
<<5)|tm
->bs1
;
1562 changed
|= VI_REGCHANGE(10);
1563 changed
|= VI_REGCHANGE(11);
1565 regs
[12] = (tm
->be4
<<5)|tm
->bs4
;
1566 regs
[13] = (tm
->be2
<<5)|tm
->bs2
;
1567 changed
|= VI_REGCHANGE(12);
1568 changed
|= VI_REGCHANGE(13);
1571 static void __setScalingRegs(u16 panSizeX
,u16 dispSizeX
,s32 threeD
)
1573 if(threeD
) panSizeX
= _SHIFTL(panSizeX
,1,16);
1574 if(panSizeX
<dispSizeX
) {
1575 regs
[37] = 0x1000|((dispSizeX
+(_SHIFTL(panSizeX
,8,16)-1))/dispSizeX
);
1576 regs
[56] = panSizeX
;
1577 changed
|= VI_REGCHANGE(37);
1578 changed
|= VI_REGCHANGE(56);
1581 changed
|= VI_REGCHANGE(37);
1585 static inline void __calcFbbs(u32 bufAddr
,u16 panPosX
,u16 panPosY
,u8 wordperline
,u32 xfbMode
,u16 dispPosY
,u32
*tfbb
,u32
*bfbb
)
1587 u32 bytesPerLine
,tmp
;
1590 bytesPerLine
= (wordperline
<<5)&0x1fe0;
1591 *tfbb
= bufAddr
+((panPosX
<<5)+(panPosY
*bytesPerLine
));
1593 if(xfbMode
==VI_XFBMODE_DF
) *bfbb
= *tfbb
+bytesPerLine
;
1601 *tfbb
= MEM_VIRTUAL_TO_PHYSICAL(*tfbb
);
1602 *bfbb
= MEM_VIRTUAL_TO_PHYSICAL(*bfbb
);
1605 static inline void __setFbbRegs(struct _horVer
*horVer
,u32
*tfbb
,u32
*bfbb
,u32
*rtfbb
,u32
*rbfbb
)
1608 __calcFbbs((u32
)horVer
->bufAddr
,horVer
->panPosX
,horVer
->adjustedPanPosY
,horVer
->wordPerLine
,horVer
->fbMode
,horVer
->adjustedDispPosY
,tfbb
,bfbb
);
1609 if(horVer
->threeD
) __calcFbbs((u32
)horVer
->rbufAddr
,horVer
->panPosX
,horVer
->adjustedPanPosY
,horVer
->wordPerLine
,horVer
->fbMode
,horVer
->adjustedDispPosY
,rtfbb
,rbfbb
);
1612 if((*tfbb
)<0x01000000 && (*bfbb
)<0x01000000
1613 && (*rtfbb
)<0x01000000 && (*rbfbb
)<0x01000000) flag
= 0;
1622 regs
[14] = _SHIFTL(flag
,12,1)|_SHIFTL(horVer
->xof
,8,4)|_SHIFTR(*tfbb
,16,8);
1623 regs
[15] = *tfbb
&0xffff;
1624 changed
|= VI_REGCHANGE(14);
1625 changed
|= VI_REGCHANGE(15);
1627 regs
[18] = _SHIFTR(*bfbb
,16,8);
1628 regs
[19] = *bfbb
&0xffff;
1629 changed
|= VI_REGCHANGE(18);
1630 changed
|= VI_REGCHANGE(19);
1632 if(horVer
->threeD
) {
1633 regs
[16] = _SHIFTR(*rtfbb
,16,8);
1634 regs
[17] = *rtfbb
&0xffff;
1635 changed
|= VI_REGCHANGE(16);
1636 changed
|= VI_REGCHANGE(17);
1638 regs
[20] = _SHIFTR(*rbfbb
,16,8);
1639 regs
[21] = *rbfbb
&0xffff;
1640 changed
|= VI_REGCHANGE(20);
1641 changed
|= VI_REGCHANGE(21);
1645 static inline void __setHorizontalRegs(const struct _timing
*tm
,u16 dispPosX
,u16 dispSizeX
)
1649 regs
[2] = (tm
->hcs
<<8)|tm
->hce
;
1651 changed
|= VI_REGCHANGE(2);
1652 changed
|= VI_REGCHANGE(3);
1654 val1
= (tm
->hbe640
+dispPosX
-40)&0x01ff;
1655 val2
= (tm
->hbs640
+dispPosX
+40)-(720-dispSizeX
);
1656 regs
[4] = (val1
>>9)|(val2
<<1);
1657 regs
[5] = (val1
<<7)|tm
->hsy
;
1658 changed
|= VI_REGCHANGE(4);
1659 changed
|= VI_REGCHANGE(5);
1662 static inline void __setVerticalRegs(u16 dispPosY
,u16 dispSizeY
,u8 equ
,u16 acv
,u16 prbOdd
,u16 prbEven
,u16 psbOdd
,u16 psbEven
,s32 black
)
1668 u32 psbeven
,prbeven
;
1677 prb
= div2
*dispPosY
;
1678 psb
= div2
*(((acv
*div1
)-dispSizeY
)-dispPosY
);
1680 prbodd
= prbEven
+prb
;
1681 psbodd
= psbEven
+psb
;
1682 prbeven
= prbOdd
+prb
;
1683 psbeven
= psbOdd
+psb
;
1685 prbodd
= prbOdd
+prb
;
1686 psbodd
= psbOdd
+psb
;
1687 prbeven
= prbEven
+prb
;
1688 psbeven
= psbEven
+psb
;
1691 tmp
= dispSizeY
/div1
;
1693 prbodd
+= ((tmp
<<1)-2);
1694 prbeven
+= ((tmp
<<1)-2);
1700 regs
[0] = ((tmp
<<4)&~0x0f)|equ
;
1701 changed
|= VI_REGCHANGE(0);
1705 changed
|= VI_REGCHANGE(6);
1706 changed
|= VI_REGCHANGE(7);
1710 changed
|= VI_REGCHANGE(8);
1711 changed
|= VI_REGCHANGE(9);
1714 static inline void __adjustPosition(u16 acv
)
1717 s16 dispPosX
,dispPosY
;
1718 s16 dispSizeY
,maxDispSizeY
;
1720 dispPosX
= (HorVer
.dispPosX
+displayOffsetH
);
1721 if(dispPosX
<=(720-HorVer
.dispSizeX
)) {
1722 if(dispPosX
>=0) HorVer
.adjustedDispPosX
= dispPosX
;
1723 else HorVer
.adjustedDispPosX
= 0;
1724 } else HorVer
.adjustedDispPosX
= (720-HorVer
.dispSizeX
);
1727 if(HorVer
.fbMode
==VI_XFBMODE_SF
) fact
= 2;
1729 field
= HorVer
.dispPosY
&0x0001;
1730 dispPosY
= HorVer
.dispPosY
+displayOffsetV
;
1731 if(dispPosY
>field
) HorVer
.adjustedDispPosY
= dispPosY
;
1732 else HorVer
.adjustedDispPosY
= field
;
1734 dispSizeY
= HorVer
.dispPosY
+HorVer
.dispSizeY
+displayOffsetV
;
1735 maxDispSizeY
= ((acv
<<1)-field
);
1736 if(dispSizeY
>maxDispSizeY
) dispSizeY
-= (acv
<<1)-field
;
1739 dispPosY
= HorVer
.dispPosY
+displayOffsetV
;
1740 if(dispPosY
<field
) dispPosY
-= field
;
1742 HorVer
.adjustedDispSizeY
= HorVer
.dispSizeY
+dispPosY
-dispSizeY
;
1744 dispPosY
= HorVer
.dispPosY
+displayOffsetV
;
1745 if(dispPosY
<field
) dispPosY
-= field
;
1747 HorVer
.adjustedPanPosY
= HorVer
.panPosY
-(dispPosY
/fact
);
1749 dispSizeY
= HorVer
.dispPosY
+HorVer
.dispSizeY
+displayOffsetV
;
1750 if(dispSizeY
>maxDispSizeY
) dispSizeY
-= maxDispSizeY
;
1753 dispPosY
= HorVer
.dispPosY
+displayOffsetV
;
1754 if(dispPosY
<field
) dispPosY
-= field
;
1756 HorVer
.adjustedPanSizeY
= HorVer
.panSizeY
+(dispPosY
/fact
)-(dispSizeY
/fact
);
1759 static inline void __importAdjustingValues()
1764 sram
= __SYS_LockSram();
1765 displayOffsetH
= sram
->display_offsetH
;
1766 __SYS_UnlockSram(0);
1769 if ( CONF_GetDisplayOffsetH(&offset
) == 0 ) {
1770 displayOffsetH
= offset
;
1778 static void __VIInit(u32 vimode
)
1781 u32 vi_mode
,interlace
,progressive
;
1782 const struct _timing
*cur_timing
= NULL
;
1784 vi_mode
= ((vimode
>>2)&0x07);
1785 interlace
= (vimode
&0x01);
1786 progressive
= (vimode
&0x02);
1788 cur_timing
= __gettiming(vimode
);
1790 //reset the interface
1793 while(cnt
<1000) cnt
++;
1796 // now begin to setup the interface
1797 _viReg
[2] = ((cur_timing
->hcs
<<8)|cur_timing
->hce
); //set HCS & HCE
1798 _viReg
[3] = cur_timing
->hlw
; //set Half Line Width
1800 _viReg
[4] = (cur_timing
->hbs640
<<1); //set HBS640
1801 _viReg
[5] = ((cur_timing
->hbe640
<<7)|cur_timing
->hsy
); //set HBE640 & HSY
1803 _viReg
[0] = cur_timing
->equ
;
1805 _viReg
[6] = (cur_timing
->psbOdd
+2); //set PSB odd field
1806 _viReg
[7] = (cur_timing
->prbOdd
+((cur_timing
->acv
<<1)-2)); //set PRB odd field
1808 _viReg
[8] = (cur_timing
->psbEven
+2); //set PSB even field
1809 _viReg
[9] = (cur_timing
->prbEven
+((cur_timing
->acv
<<1)-2)); //set PRB even field
1811 _viReg
[10] = ((cur_timing
->be3
<<5)|cur_timing
->bs3
); //set BE3 & BS3
1812 _viReg
[11] = ((cur_timing
->be1
<<5)|cur_timing
->bs1
); //set BE1 & BS1
1814 _viReg
[12] = ((cur_timing
->be4
<<5)|cur_timing
->bs4
); //set BE4 & BS4
1815 _viReg
[13] = ((cur_timing
->be2
<<5)|cur_timing
->bs2
); //set BE2 & BS2
1817 _viReg
[24] = (0x1000|((cur_timing
->nhlines
/2)+1));
1818 _viReg
[25] = (cur_timing
->hlw
+1);
1820 _viReg
[26] = 0x1001; //set DI1
1821 _viReg
[27] = 0x0001; //set DI1
1822 _viReg
[36] = 0x2828; //set HSR
1824 if(vi_mode
<VI_PAL
&& vi_mode
>=VI_DEBUG_PAL
) vi_mode
= VI_NTSC
;
1826 _viReg
[1] = ((vi_mode
<<8)|0x0005); //set MODE & INT & enable
1827 _viReg
[54] = 0x0001;
1829 _viReg
[1] = ((vi_mode
<<8)|(interlace
<<2)|0x0001);
1830 _viReg
[54] = 0x0000;
1835 static u32
__VISendI2CData(u8 addr
,void *val
,u32 len
)
1841 if(i2cIdentFirst
==0) {
1846 _CPU_ISR_Disable(level
);
1851 __viSetSDA(i2cIdentFlag
);
1854 ret
= __sendSlaveAddress(addr
);
1856 _CPU_ISR_Restore(level
);
1861 for(i
=0;i
<len
;i
++) {
1864 if(c
&0x80) __viSetSDA(i2cIdentFlag
);
1865 else __viSetSDA(i2cIdentFlag
^1);
1879 if(i2cIdentFlag
==1 && __viGetSDA()!=0) {
1880 _CPU_ISR_Restore(level
);
1884 __viSetSDA(i2cIdentFlag
^1);
1890 __viSetSDA(i2cIdentFlag
^1);
1892 __viSetSDA(i2cIdentFlag
);
1894 _CPU_ISR_Restore(level
);
1898 static void __VIWriteI2CRegister8(u8 reg
, u8 data
)
1903 __VISendI2CData(0xe0,buf
,2);
1907 static void __VIWriteI2CRegister16(u8 reg
, u16 data
)
1912 buf
[2] = data
& 0xFF;
1913 __VISendI2CData(0xe0,buf
,3);
1917 static void __VIWriteI2CRegister32(u8 reg
, u32 data
)
1921 buf
[1] = data
>> 24;
1922 buf
[2] = (data
>> 16) & 0xFF;
1923 buf
[3] = (data
>> 8) & 0xFF;
1924 buf
[4] = data
& 0xFF;
1925 __VISendI2CData(0xe0,buf
,5);
1929 static void __VIWriteI2CRegisterBuf(u8 reg
, int size
, u8
*data
)
1933 memcpy(&buf
[1], data
, size
);
1934 __VISendI2CData(0xe0,buf
,size
+1);
1939 static void __VISetYUVSEL(u8 dtvstatus
)
1941 if(currTvMode
==VI_NTSC
) vdacFlagRegion
= 0x0000;
1942 else if(currTvMode
==VI_PAL
|| currTvMode
==VI_EURGB60
) vdacFlagRegion
= 0x0002;
1943 /* FIXME: setting this to 1 causes monochrome output on PAL systems*/
1944 else if(currTvMode
==VI_MPAL
) vdacFlagRegion
= 0x0002;
1945 else vdacFlagRegion
= 0x0000;
1947 __VIWriteI2CRegister8(0x01, _SHIFTL(dtvstatus
,5,3)|(vdacFlagRegion
&0x1f));
1950 static void __VISetFilterEURGB60(u8 enable
)
1952 __VIWriteI2CRegister8(0x6e, enable
);
1956 static void __VISetTiming(u8 timing
)
1960 val
= (_SHIFTL(0x00,8,8)|timing
);
1961 __VISendI2CData(0xe0,&val
,sizeof(u16
));
1965 static void __VISet3in1Output(u8 enable
)
1969 val
= (_SHIFTL(0x04,8,8)|enable
);
1970 __VISendI2CData(0xe0,&val
,sizeof(u16
));
1975 static void __VISetupEncoder(void)
1980 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00,
1981 0x10, 0x00, 0x10, 0x00, 0x10, 0x20, 0x40, 0x60,
1982 0x80, 0xa0, 0xeb, 0x10, 0x00, 0x20, 0x00, 0x40,
1983 0x00, 0x60, 0x00, 0x80, 0x00, 0xa0, 0x00, 0xeb,
1989 tv
= VIDEO_GetCurrentTvMode();
1990 dtv
= (_viReg
[55]&0x01);
1993 // SetRevolutionModeSimple
1995 memset(macrobuf
, 0, 0x1a);
1997 __VIWriteI2CRegister8(0x6a, 1);
1998 __VIWriteI2CRegister8(0x65, 1);
2000 __VIWriteI2CRegister8(0x00, 0);
2001 __VIWriteI2CRegister16(0x71, 0x8e8e);
2002 __VIWriteI2CRegister8(0x02, 7);
2003 __VIWriteI2CRegister16(0x05, 0x0000);
2004 __VIWriteI2CRegister16(0x08, 0x0000);
2005 __VIWriteI2CRegister32(0x7A, 0x00000000);
2008 __VIWriteI2CRegisterBuf(0x40, sizeof(macrobuf
), macrobuf
);
2010 // Sometimes 1 in RGB mode? (reg 1 == 3)
2011 __VIWriteI2CRegister8(0x0A, 0);
2013 __VIWriteI2CRegister8(0x03, 1);
2015 __VIWriteI2CRegisterBuf(0x10, sizeof(gamma
), gamma
);
2017 __VIWriteI2CRegister8(0x04, 1);
2018 __VIWriteI2CRegister32(0x7A, 0x00000000);
2019 __VIWriteI2CRegister16(0x08, 0x0000);
2020 __VIWriteI2CRegister8(0x03, 1);
2022 if(tv
==VI_EURGB60
) __VISetFilterEURGB60(1);
2023 else __VISetFilterEURGB60(0);
2029 static inline void __getCurrentDisplayPosition(u32
*px
,u32
*py
)
2035 vpos
= (_viReg
[22]&0x7ff);
2038 hpos
= (_viReg
[23]&0x7ff);
2039 vpos
= (_viReg
[22]&0x7ff);
2040 } while(vpos_old
!=vpos
);
2045 static inline u32
__getCurrentHalfLine()
2050 __getCurrentDisplayPosition(&hpos
,&vpos
);
2056 return vpos
+(hpos
/currTiming
->hlw
);
2059 static inline u32
__getCurrentFieldEvenOdd()
2063 hline
= __getCurrentHalfLine();
2064 if(hline
<currTiming
->nhlines
) return 1;
2069 static inline u32
__VISetRegs()
2074 if(shdw_changeMode
==1){
2075 if(!__getCurrentFieldEvenOdd()) return 0;
2078 while(shdw_changed
) {
2079 val
= cntlzd(shdw_changed
);
2080 _viReg
[val
] = shdw_regs
[val
];
2081 mask
= VI_REGCHANGE(val
);
2082 shdw_changed
&= ~mask
;
2084 shdw_changeMode
= 0;
2085 currTiming
= HorVer
.timing
;
2086 currTvMode
= HorVer
.tv
;
2093 static void __VIDisplayPositionToXY(s32 xpos
,s32 ypos
,s32
*px
,s32
*py
)
2100 hline
= ((vpos
<<1)+(hpos
/currTiming
->hlw
));
2103 if(HorVer
.nonInter
==0x0000) {
2104 if(hline
<currTiming
->nhlines
) {
2105 val
= currTiming
->prbOdd
+(currTiming
->equ
*3);
2107 val
= (currTiming
->nhlines
-currTiming
->psbOdd
);
2109 *py
= (s32
)(((hline
-(currTiming
->equ
*3))-currTiming
->prbOdd
)&~0x01);
2115 hline
-= currTiming
->psbOdd
;
2116 val
= (currTiming
->prbEven
+(currTiming
->equ
*3));
2118 val
= (currTiming
->nhlines
-currTiming
->psbEven
);
2120 *py
= (s32
)((((hline
-(currTiming
->equ
*3))-currTiming
->prbEven
)&~0x01)+1);
2126 } else if(HorVer
.nonInter
==0x0001) {
2127 if(hline
>=currTiming
->nhlines
) hline
-= currTiming
->nhlines
;
2129 val
= (currTiming
->prbOdd
+(currTiming
->equ
*3));
2131 val
= (currTiming
->nhlines
-currTiming
->psbOdd
);
2133 *py
= (s32
)(((hline
-(currTiming
->equ
*3))-currTiming
->prbOdd
)&~0x01);
2138 } else if(HorVer
.nonInter
==0x0002) {
2139 if(hline
<currTiming
->nhlines
) {
2140 val
= currTiming
->prbOdd
+(currTiming
->equ
*3);
2142 val
= (currTiming
->nhlines
-currTiming
->psbOdd
);
2144 *py
= (s32
)((hline
-(currTiming
->equ
*3))-currTiming
->prbOdd
);
2150 hline
-= currTiming
->psbOdd
;
2151 val
= (currTiming
->prbEven
+(currTiming
->equ
*3));
2153 val
= (currTiming
->nhlines
-currTiming
->psbEven
);
2155 *py
= (s32
)(((hline
-(currTiming
->equ
*3))-currTiming
->prbEven
)&~0x01);
2164 static inline void __VIGetCurrentPosition(s32
*px
,s32
*py
)
2168 __getCurrentDisplayPosition((u32
*)&xpos
,(u32
*)&ypos
);
2169 __VIDisplayPositionToXY(xpos
,ypos
,px
,py
);
2172 static void __VIRetraceHandler(u32 nIrq
,void *pCtx
)
2183 _viReg
[24] = intr
&~0x8000;
2189 _viReg
[26] = intr
&~0x8000;
2195 _viReg
[28] = intr
&~0x8000;
2201 _viReg
[30] = intr
&~0x8000;
2206 if(ret
&0x04 || ret
&0x08) {
2207 if(positionCB
!=NULL
) {
2208 __VIGetCurrentPosition(&xpos
,&ypos
);
2209 positionCB(xpos
,ypos
);
2215 preRetraceCB(retraceCount
);
2220 SI_RefreshSamplingRate();
2224 tv
= VIDEO_GetCurrentTvMode();
2225 dtv
= (_viReg
[55]&0x01);
2226 if(dtv
!=oldDtvStatus
|| tv
!=oldTvStatus
) __VISetYUVSEL(dtv
);
2229 if(tv
!=oldTvStatus
) {
2230 if(tv
==VI_EURGB60
) __VISetFilterEURGB60(1);
2231 else __VISetFilterEURGB60(0);
2236 postRetraceCB(retraceCount
);
2238 LWP_ThreadBroadcast(video_queue
);
2241 void* VIDEO_GetNextFramebuffer()
2246 void* VIDEO_GetCurrentFramebuffer()
2253 u32 level
,vimode
= 0;
2255 _CPU_ISR_Disable(level
);
2257 if(!(_viReg
[1]&0x0001))
2258 __VIInit(VI_TVMODE_NTSC_INT
);
2263 shdw_changeMode
= 0;
2267 _viReg
[38] = ((taps
[1]>>6)|(taps
[2]<<4));
2268 _viReg
[39] = (taps
[0]|_SHIFTL(taps
[1],10,6));
2269 _viReg
[40] = ((taps
[4]>>6)|(taps
[5]<<4));
2270 _viReg
[41] = (taps
[3]|_SHIFTL(taps
[4],10,6));
2271 _viReg
[42] = ((taps
[7]>>6)|(taps
[8]<<4));
2272 _viReg
[43] = (taps
[6]|_SHIFTL(taps
[7],10,6));
2273 _viReg
[44] = (taps
[11]|(taps
[12]<<8));
2274 _viReg
[45] = (taps
[9]|(taps
[10]<<8));
2275 _viReg
[46] = (taps
[15]|(taps
[16]<<8));
2276 _viReg
[47] = (taps
[13]|(taps
[14]<<8));
2277 _viReg
[48] = (taps
[19]|(taps
[20]<<8));
2278 _viReg
[49] = (taps
[17]|(taps
[18]<<8));
2279 _viReg
[50] = (taps
[23]|(taps
[24]<<8));
2280 _viReg
[51] = (taps
[21]|(taps
[22]<<8));
2283 __importAdjustingValues();
2285 HorVer
.nonInter
= _SHIFTR(_viReg
[1],2,1);
2286 HorVer
.tv
= _SHIFTR(_viReg
[1],8,2);
2288 vimode
= HorVer
.nonInter
;
2289 if(HorVer
.tv
!=VI_DEBUG
) vimode
+= (HorVer
.tv
<<2);
2290 currTiming
= __gettiming(vimode
);
2291 currTvMode
= HorVer
.tv
;
2293 regs
[1] = _viReg
[1];
2294 HorVer
.timing
= currTiming
;
2295 HorVer
.dispSizeX
= 640;
2296 HorVer
.dispSizeY
= currTiming
->acv
<<1;
2297 HorVer
.dispPosX
= (VI_MAX_WIDTH_NTSC
-HorVer
.dispSizeX
)/2;
2298 HorVer
.dispPosY
= 0;
2300 __adjustPosition(currTiming
->acv
);
2302 HorVer
.fbSizeX
= 640;
2303 HorVer
.fbSizeY
= currTiming
->acv
<<1;
2306 HorVer
.panSizeX
= 640;
2307 HorVer
.panSizeY
= currTiming
->acv
<<1;
2308 HorVer
.fbMode
= VI_XFBMODE_SF
;
2309 HorVer
.wordPerLine
= 40;
2320 _viReg
[24] &= ~0x8000;
2321 _viReg
[26] &= ~0x8000;
2323 preRetraceCB
= NULL
;
2324 postRetraceCB
= NULL
;
2326 LWP_InitQueue(&video_queue
);
2328 IRQ_Request(IRQ_PI_VI
,__VIRetraceHandler
,NULL
);
2329 __UnmaskIrq(IRQMASK(IRQ_PI_VI
));
2333 _CPU_ISR_Restore(level
);
2336 void VIDEO_Configure(GXRModeObj
*rmode
)
2339 u32 nonint
,vimode
,level
;
2340 const struct _timing
*curtiming
;
2342 if(rmode
->viHeight
&0x0001) printf("VIDEO_Configure(): Odd number(%d) is specified to viHeight\n",rmode
->viHeight
);
2343 if((rmode
->xfbMode
==VI_XFBMODE_DF
|| rmode
->viTVMode
==VI_TVMODE_NTSC_PROG
|| rmode
->viTVMode
==VI_TVMODE_NTSC_PROG_DS
)
2344 && 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
);
2345 if(rmode
->xfbMode
==VI_XFBMODE_SF
&& !(rmode
->viTVMode
==VI_TVMODE_NTSC_PROG
|| rmode
->viTVMode
==VI_TVMODE_NTSC_PROG_DS
)
2346 && (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
);
2348 _CPU_ISR_Disable(level
);
2349 nonint
= (rmode
->viTVMode
&0x0003);
2350 if(nonint
!=HorVer
.nonInter
) {
2352 HorVer
.nonInter
= nonint
;
2354 HorVer
.tv
= _SHIFTR(rmode
->viTVMode
,2,3);
2355 HorVer
.dispPosX
= rmode
->viXOrigin
;
2356 HorVer
.dispPosY
= rmode
->viYOrigin
;
2357 if(HorVer
.nonInter
==VI_NON_INTERLACE
) HorVer
.dispPosY
= HorVer
.dispPosY
<<1;
2359 HorVer
.dispSizeX
= rmode
->viWidth
;
2360 HorVer
.fbSizeX
= rmode
->fbWidth
;
2361 HorVer
.fbSizeY
= rmode
->xfbHeight
;
2362 HorVer
.fbMode
= rmode
->xfbMode
;
2363 HorVer
.panSizeX
= HorVer
.fbSizeX
;
2364 HorVer
.panSizeY
= HorVer
.fbSizeY
;
2368 if(HorVer
.nonInter
==VI_PROGRESSIVE
|| HorVer
.nonInter
==(VI_NON_INTERLACE
|VI_PROGRESSIVE
)) HorVer
.dispSizeY
= HorVer
.panSizeY
;
2369 else if(HorVer
.fbMode
==VI_XFBMODE_SF
) HorVer
.dispSizeY
= HorVer
.panSizeY
<<1;
2370 else HorVer
.dispSizeY
= HorVer
.panSizeY
;
2372 if(HorVer
.nonInter
==(VI_NON_INTERLACE
|VI_PROGRESSIVE
)) HorVer
.threeD
= 1;
2373 else HorVer
.threeD
= 0;
2375 vimode
= VI_TVMODE(HorVer
.tv
,HorVer
.nonInter
);
2376 curtiming
= __gettiming(vimode
);
2377 HorVer
.timing
= curtiming
;
2379 __adjustPosition(curtiming
->acv
);
2381 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
));
2382 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
));
2384 if(!encoderType
) HorVer
.tv
= VI_DEBUG
;
2386 __setInterruptRegs(curtiming
);
2388 dcr
= regs
[1]&~0x030c;
2389 dcr
|= _SHIFTL(HorVer
.threeD
,3,1);
2390 if(HorVer
.nonInter
==VI_PROGRESSIVE
|| HorVer
.nonInter
==(VI_NON_INTERLACE
|VI_PROGRESSIVE
)) dcr
|= 0x0004;
2391 else dcr
|= _SHIFTL(HorVer
.nonInter
,2,1);
2392 if(!(HorVer
.tv
==VI_DEBUG_PAL
|| HorVer
.tv
==VI_EURGB60
)) dcr
|= _SHIFTL(HorVer
.tv
,8,2);
2394 changed
|= VI_REGCHANGE(1);
2396 regs
[54] &= ~0x0001;
2397 if(rmode
->viTVMode
==VI_TVMODE_NTSC_PROG
|| rmode
->viTVMode
==VI_TVMODE_NTSC_PROG_DS
) regs
[54] |= 0x0001;
2398 changed
|= VI_REGCHANGE(54);
2400 __setScalingRegs(HorVer
.panSizeX
,HorVer
.dispSizeX
,HorVer
.threeD
);
2401 __setHorizontalRegs(curtiming
,HorVer
.adjustedDispPosX
,HorVer
.dispSizeX
);
2402 __setBBIntervalRegs(curtiming
);
2403 __setPicConfig(HorVer
.fbSizeX
,HorVer
.fbMode
,HorVer
.panPosX
,HorVer
.panSizeX
,&HorVer
.wordPerLine
,&HorVer
.std
,&HorVer
.wpl
,&HorVer
.xof
);
2405 if(fbSet
) __setFbbRegs(&HorVer
,&HorVer
.tfbb
,&HorVer
.bfbb
,&HorVer
.rtfbb
,&HorVer
.rbfbb
);
2407 __setVerticalRegs(HorVer
.adjustedDispPosY
,HorVer
.adjustedDispSizeY
,curtiming
->equ
,curtiming
->acv
,curtiming
->prbOdd
,curtiming
->prbEven
,curtiming
->psbOdd
,curtiming
->psbEven
,HorVer
.black
);
2409 printDebugCalculations();
2411 _CPU_ISR_Restore(level
);
2414 void VIDEO_WaitVSync(void)
2419 _CPU_ISR_Disable(level
);
2420 retcnt
= retraceCount
;
2422 LWP_ThreadSleep(video_queue
);
2423 } while(retraceCount
==retcnt
);
2424 _CPU_ISR_Restore(level
);
2427 void VIDEO_SetFramebuffer(void *fb
)
2431 _CPU_ISR_Disable(level
);
2433 HorVer
.bufAddr
= fb
;
2434 __setFbbRegs(&HorVer
,&HorVer
.tfbb
,&HorVer
.bfbb
,&HorVer
.rtfbb
,&HorVer
.rbfbb
);
2435 _viReg
[14] = regs
[14];
2436 _viReg
[15] = regs
[15];
2438 _viReg
[18] = regs
[18];
2439 _viReg
[19] = regs
[19];
2442 _viReg
[16] = regs
[16];
2443 _viReg
[17] = regs
[17];
2445 _viReg
[20] = regs
[20];
2446 _viReg
[21] = regs
[21];
2448 _CPU_ISR_Restore(level
);
2451 void VIDEO_SetNextFramebuffer(void *fb
)
2455 if((u32
)fb
&0x1f) printf("VIDEO_SetNextFramebuffer(): Frame buffer address (%p) is not 32byte aligned\n",fb
);
2457 _CPU_ISR_Disable(level
);
2459 HorVer
.bufAddr
= fb
;
2460 __setFbbRegs(&HorVer
,&HorVer
.tfbb
,&HorVer
.bfbb
,&HorVer
.rtfbb
,&HorVer
.rbfbb
);
2461 _CPU_ISR_Restore(level
);
2464 void VIDEO_SetNextRightFramebuffer(void *fb
)
2468 _CPU_ISR_Disable(level
);
2470 HorVer
.rbufAddr
= fb
;
2471 __setFbbRegs(&HorVer
,&HorVer
.tfbb
,&HorVer
.bfbb
,&HorVer
.rtfbb
,&HorVer
.rbfbb
);
2472 _CPU_ISR_Restore(level
);
2481 _CPU_ISR_Disable(level
);
2482 shdw_changeMode
|= changeMode
;
2485 shdw_changed
|= changed
;
2487 val
= cntlzd(changed
);
2488 shdw_regs
[val
] = regs
[val
];
2489 mask
= VI_REGCHANGE(val
);
2496 nextFb
= HorVer
.bufAddr
;
2497 _CPU_ISR_Restore(level
);
2500 void VIDEO_SetBlack(boolean black
)
2503 const struct _timing
*curtiming
;
2505 _CPU_ISR_Disable(level
);
2506 HorVer
.black
= black
;
2507 curtiming
= HorVer
.timing
;
2508 __setVerticalRegs(HorVer
.adjustedDispPosY
,HorVer
.dispSizeY
,curtiming
->equ
,curtiming
->acv
,curtiming
->prbOdd
,curtiming
->prbEven
,curtiming
->psbOdd
,curtiming
->psbEven
,HorVer
.black
);
2509 _CPU_ISR_Restore(level
);
2512 u32
VIDEO_GetNextField()
2514 u32 level
,nextfield
;
2516 _CPU_ISR_Disable(level
);
2517 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
2518 _CPU_ISR_Restore(level
);
2520 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
2523 u32
VIDEO_GetCurrentTvMode()
2529 _CPU_ISR_Disable(level
);
2532 if(mode
==VI_DEBUG
) tv
= VI_NTSC
;
2533 else if(mode
==VI_EURGB60
) tv
= mode
;
2534 else if(mode
==VI_MPAL
) tv
= VI_MPAL
;
2535 else if(mode
==VI_NTSC
) tv
= VI_NTSC
;
2537 _CPU_ISR_Restore(level
);
2542 GXRModeObj
* VIDEO_GetPreferredMode(GXRModeObj
*mode
)
2549 if ( CONF_GetProgressiveScan() > 0 && VIDEO_HaveComponentCable() ) {
2550 rmode
= &TVNtsc480Prog
;
2553 u32 tvmode
= CONF_GetVideo();
2556 case CONF_VIDEO_NTSC
:
2557 rmode
= &TVNtsc480IntDf
;
2559 case CONF_VIDEO_PAL
:
2560 if ( CONF_GetEuRGB60() > 0 ) {
2561 rmode
= &TVEurgb60Hz480IntDf
;
2563 rmode
= &TVPal528IntDf
;
2566 case CONF_VIDEO_MPAL
:
2567 rmode
= &TVMpal480IntDf
;
2570 rmode
= &TVNtsc480IntDf
;
2574 u32 tvmode
= VIDEO_GetCurrentTvMode();
2578 rmode
= &TVNtsc480IntDf
;
2581 rmode
= &TVPal528IntDf
;
2584 rmode
= &TVMpal480IntDf
;
2587 rmode
= &TVNtsc480IntDf
;
2592 if ( NULL
!= mode
) {
2593 memcpy( mode
, rmode
, sizeof(GXRModeObj
));
2604 u32
VIDEO_GetCurrentLine()
2606 u32 level
,curr_hl
= 0;
2608 _CPU_ISR_Disable(level
);
2609 curr_hl
= __getCurrentHalfLine();
2610 _CPU_ISR_Restore(level
);
2612 if(curr_hl
>=currTiming
->nhlines
) curr_hl
-=currTiming
->nhlines
;
2618 VIRetraceCallback
VIDEO_SetPreRetraceCallback(VIRetraceCallback callback
)
2621 VIRetraceCallback ret
= preRetraceCB
;
2622 _CPU_ISR_Disable(level
);
2623 preRetraceCB
= callback
;
2624 _CPU_ISR_Restore(level
);
2628 VIRetraceCallback
VIDEO_SetPostRetraceCallback(VIRetraceCallback callback
)
2631 VIRetraceCallback ret
= postRetraceCB
;
2632 _CPU_ISR_Disable(level
);
2633 postRetraceCB
= callback
;
2634 _CPU_ISR_Restore(level
);
2638 u32
VIDEO_GetFrameBufferSize(GXRModeObj
*rmode
) {
2641 w
= VIDEO_PadFramebufferWidth(rmode
->fbWidth
);
2642 h
= rmode
->xfbHeight
;
2647 return w
* h
* VI_DISPLAY_PIX_SZ
;
2650 void VIDEO_ClearFrameBuffer(GXRModeObj
*rmode
,void *fb
,u32 color
)
2652 __VIClearFramebuffer(fb
, VIDEO_GetFrameBufferSize(rmode
), color
);
2655 u32
VIDEO_HaveComponentCable(void)
2657 return (_viReg
[55]&0x01);