~ubuntu-branches/debian/experimental/mednafen/experimental

« back to all changes in this revision

Viewing changes to src/psx/gte.cpp

  • Committer: Package Import Robot
  • Author(s): Stephen Kitt
  • Date: 2012-01-31 07:21:35 UTC
  • mfrom: (1.2.8)
  • Revision ID: package-import@ubuntu.com-20120131072135-es3dj12y00xcnrsk
Tags: 0.9.19-1
* New upstream WIP version.
* Update copyright information.
* Refresh use-system-tremor.patch and remove psx-big-endian-only.patch.
* Add spelling-fixes.patch based on Lintian's recommendations.
* Build-depend on debhelper 9 or later and remove corresponding Lintian
  override.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* Mednafen - Multi-system Emulator
 
2
 *
 
3
 * This program is free software; you can redistribute it and/or modify
 
4
 * it under the terms of the GNU General Public License as published by
 
5
 * the Free Software Foundation; either version 2 of the License, or
 
6
 * (at your option) any later version.
 
7
 *
 
8
 * This program is distributed in the hope that it will be useful,
 
9
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
10
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
11
 * GNU General Public License for more details.
 
12
 *
 
13
 * You should have received a copy of the GNU General Public License
 
14
 * along with this program; if not, write to the Free Software
 
15
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
16
 */
1
17
 
2
18
#ifndef PSXDEV_GTE_TESTING
3
19
#include "psx.h"
4
20
#include "gte.h"
5
21
#endif
6
22
 
 
23
static uint32 ReciprocalTable[0x8000] =
 
24
{
 
25
 #include "gte_divrecip.inc"
 
26
};
 
27
 
7
28
/* Notes:
8
29
 
9
30
 AVSZ3/AVSZ4:
49
70
 int16 Y;
50
71
} gtexy;
51
72
 
52
 
int32 A(unsigned int which, int64 value);
53
73
int16 Lm_B(unsigned int which, int32 value, int lm);
54
74
uint8 Lm_C(unsigned int which, int32 value);
55
75
 
56
 
int32 Lm_D(int32 value);
57
76
 
58
 
int32 F(int64 value);
59
77
 
60
78
int32 Lm_G(unsigned int which, int32 value);
61
79
int32 Lm_H(int32 value);
77
95
  gtematrix Rot;
78
96
  gtematrix Light;
79
97
  gtematrix Color;
80
 
  gtematrix Null;       // Might not be correct.
 
98
  gtematrix AbbyNormal;
81
99
 };
82
100
} Matrices_t;
83
101
 
110
128
static int16 Vectors[3][4];
111
129
static gtergb RGB;
112
130
static uint16 OTZ;
113
 
static int16 IR0;
114
 
static int16 IR1;
115
 
static int16 IR2;
116
 
static int16 IR3;
 
131
 
 
132
static int16 IR[4];
 
133
 
 
134
#define IR0 IR[0]
 
135
#define IR1 IR[1]
 
136
#define IR2 IR[2]
 
137
#define IR3 IR[3]
 
138
 
117
139
static gtexy XY_FIFO[4];
118
140
static uint16 Z_FIFO[4];
119
141
static gtergb RGB_FIFO[3];
120
142
static int32 MAC[4];
121
 
static uint32 IRGB;
122
143
static uint32 LZCS;
123
144
static uint32 LZCR;
124
145
 
125
146
static uint32 Reg23;
126
147
// end DR
127
148
 
128
 
void PTransform(uint32 sf, int lm, unsigned int v);
129
 
 
130
149
int32 RTPS(uint32 instr);
131
150
int32 RTPT(uint32 instr);
132
151
 
201
220
 memset(Z_FIFO, 0, sizeof(Z_FIFO));
202
221
 memset(RGB_FIFO, 0, sizeof(RGB_FIFO));
203
222
 memset(MAC, 0, sizeof(MAC));
204
 
 IRGB = 0;
205
223
 LZCS = 0;
206
224
 LZCR = 0;
207
225
 
397
415
  case 14:
398
416
        XY_FIFO[2].X = value;
399
417
        XY_FIFO[2].Y = value >> 16;
 
418
        XY_FIFO[3].X = value;
 
419
        XY_FIFO[3].Y = value >> 16;
400
420
        break;
401
421
 
402
422
  case 15:
466
486
        break;
467
487
 
468
488
  case 28:
469
 
        IRGB = value & 0x7FFF;
470
489
        IR1 = ((value >> 0) & 0x1F) << 7;
471
490
        IR2 = ((value >> 5) & 0x1F) << 7;
472
491
        IR3 = ((value >> 10) & 0x1F) << 7;
476
495
        break;
477
496
 
478
497
  case 30:
479
 
        // FIXME
480
498
        LZCS = value;
481
499
        {
482
500
         uint32 test = value & 0x80000000;
614
632
        break;
615
633
 
616
634
  case 28:
617
 
        ret = IRGB;
618
 
        break;
619
 
 
620
635
  case 29:
621
636
        ret = Sat5(IR1 >> 7) | (Sat5(IR2 >> 7) << 5) | (Sat5(IR3 >> 7) << 10);
622
637
        break;
632
647
 return(ret);
633
648
}
634
649
 
635
 
INLINE int32 A(unsigned int which, int64 value)
 
650
#define sign_x_to_s64(_bits, _value) (((int64)((uint64)(_value) << (64 - _bits))) >> (64 - _bits))
 
651
INLINE int64 A_MV(unsigned which, int64 value)
636
652
{
637
 
 // Done for an issue with NCCS, at least.  See if this masking-out is applicable in all cases, and for other registers.
638
 
 //
639
 
 FLAGS &= ~(1 << (27 - which));
640
 
 FLAGS &= ~(1 << (30 - which));
641
 
 //
642
 
 //
 
653
 if(value >= (1LL << 43))
 
654
  FLAGS |= 1 << (30 - which);
643
655
 
644
 
 if(value < -2147483648LL)
645
 
 {
646
 
  // flag set here
 
656
 if(value < -(1LL << 43))
647
657
  FLAGS |= 1 << (27 - which);
648
 
 }
649
658
 
650
 
 if(value > 2147483647LL)
651
 
 {
652
 
  // flag set here
653
 
  FLAGS |= 1 << (30 - which);
654
 
 }
655
 
 return(value);
 
659
 return sign_x_to_s64(44, value);
656
660
}
657
661
 
658
 
INLINE int32 F(int64 value)
 
662
INLINE int64 F(int64 value)
659
663
{
660
664
 if(value < -2147483648LL)
661
665
 {
693
697
 return(value);
694
698
}
695
699
 
 
700
 
 
701
INLINE int16 Lm_B_PTZ(unsigned int which, int32 value, int32 ftv_value, int lm)
 
702
{
 
703
 int32 tmp = lm << 15;
 
704
 
 
705
 if(ftv_value < -32768)
 
706
 {
 
707
  FLAGS |= 1 << (24 - which);
 
708
 }
 
709
 
 
710
 if(ftv_value > 32767)
 
711
 {
 
712
  FLAGS |= 1 << (24 - which);
 
713
 }
 
714
 
 
715
 if(value < (-32768 + tmp))
 
716
 {
 
717
  value = -32768 + tmp;
 
718
 }
 
719
 
 
720
 if(value > 32767)
 
721
 {
 
722
  value = 32767;
 
723
 }
 
724
 
 
725
 return(value);
 
726
}
 
727
 
696
728
INLINE uint8 Lm_C(unsigned int which, int32 value)
697
729
{
698
730
 if(value & ~0xFF)
710
742
 return(value);
711
743
}
712
744
 
713
 
INLINE int32 Lm_D(int32 value)
 
745
INLINE int32 Lm_D(int32 value, int unchained)
714
746
{
715
747
 // Not sure if we should have it as int64, or just chain on to and special case when the F flags are set.
716
 
 if(FLAGS & (1 << 15))
 
748
 if(!unchained)
717
749
 {
718
 
  FLAGS |= 1 << 18;
719
 
  return(0);
720
 
 }
 
750
  if(FLAGS & (1 << 15))
 
751
  {
 
752
   FLAGS |= 1 << 18;
 
753
   return(0);
 
754
  }
721
755
 
722
 
 if(FLAGS & (1 << 16))
723
 
 {
724
 
  FLAGS |= 1 << 18;
725
 
  return(0xFFFF);
 
756
  if(FLAGS & (1 << 16))
 
757
  {
 
758
   FLAGS |= 1 << 18;
 
759
   return(0xFFFF);
 
760
  }
726
761
 }
727
762
 
728
763
 if(value < 0)
760
795
 return(value);
761
796
}
762
797
 
 
798
// limit to 4096, not 4095
763
799
INLINE int32 Lm_H(int32 value)
764
800
{
 
801
#if 0
 
802
 if(FLAGS & (1 << 15))
 
803
 {
 
804
  value = 0;
 
805
  FLAGS |= 1 << 12;
 
806
  return value;
 
807
 }
 
808
 
 
809
 if(FLAGS & (1 << 16))
 
810
 {
 
811
  value = 4096;
 
812
  FLAGS |= 1 << 12;
 
813
  return value;
 
814
 }
 
815
#endif
 
816
 
765
817
 if(value < 0)
766
818
 {
767
 
  // Set flag here
768
819
  value = 0;
769
820
  FLAGS |= 1 << 12;
770
821
 }
771
822
 
772
 
 if(value > 4096)       // Yes, six.
 
823
 if(value > 4096)
773
824
 {
774
 
  // Set flag here
775
825
  value = 4096;
776
826
  FLAGS |= 1 << 12;
777
827
 }
797
847
 IR3 = Lm_B(2, MAC[3], lm);
798
848
}
799
849
 
800
 
// NOTES:
801
 
// << 12 for translation vector with MVMA when sf is 0.
802
 
// FIXME: far color vector is borked
803
850
INLINE void MultiplyMatrixByVector(const gtematrix *matrix, const int16 *v, const int32 *crv, uint32 sf, int lm)
804
851
{
805
 
#if 0
806
 
 MAC[1] = A(0, ((int64)crv[0] << 12) + (((int64)(matrix.MX[0][0] * v[0]) + (matrix.MX[0][1] * v[1]) + (matrix.MX[0][2] * v[2])) >> sf));
807
 
 MAC[2] = A(1, ((int64)crv[1] << 12) + (((int64)(matrix.MX[1][0] * v[0]) + (matrix.MX[1][1] * v[1]) + (matrix.MX[1][2] * v[2])) >> sf));
808
 
 MAC[3] = A(2, ((int64)crv[2] << 12) + (((int64)(matrix.MX[2][0] * v[0]) + (matrix.MX[2][1] * v[1]) + (matrix.MX[2][2] * v[2])) >> sf));
809
 
#endif
810
 
 
811
 
 assert(crv != CRVectors.FC);
812
 
 
813
 
#if 0
814
 
 if(0 && crv == CRVectors.FC)
815
 
 {
816
 
  MAC[1] = A(0, ((((int64)crv[0] << 8) + (int64)(matrix->MX[0][0] * v[0]) + (matrix->MX[0][1] * v[1]) + (matrix->MX[0][2] * v[2])) >> sf));
817
 
  MAC[2] = A(1, ((((int64)crv[1] << 8) + (int64)(matrix->MX[1][0] * v[0]) + (matrix->MX[1][1] * v[1]) + (matrix->MX[1][2] * v[2])) >> sf));
818
 
  MAC[3] = A(2, ((((int64)crv[2] << 8) + (int64)(matrix->MX[2][0] * v[0]) + (matrix->MX[2][1] * v[1]) + (matrix->MX[2][2] * v[2])) >> sf));
819
 
 }
820
 
 else
821
 
#endif
822
 
 {
823
 
  MAC[1] = A(0, ((((int64)crv[0] << 12) + (int64)(matrix->MX[0][0] * v[0]) + (matrix->MX[0][1] * v[1]) + (matrix->MX[0][2] * v[2])) >> sf));
824
 
  MAC[2] = A(1, ((((int64)crv[1] << 12) + (int64)(matrix->MX[1][0] * v[0]) + (matrix->MX[1][1] * v[1]) + (matrix->MX[1][2] * v[2])) >> sf));
825
 
  MAC[3] = A(2, ((((int64)crv[2] << 12) + (int64)(matrix->MX[2][0] * v[0]) + (matrix->MX[2][1] * v[1]) + (matrix->MX[2][2] * v[2])) >> sf));
826
 
 }
 
852
 unsigned i;
 
853
 
 
854
 for(i = 0; i < 3; i++)
 
855
 {
 
856
  int64 tmp;
 
857
  int32 mulr[3];
 
858
 
 
859
  tmp = (int64)crv[i] << 12;
 
860
 
 
861
  if(matrix == &Matrices.AbbyNormal)
 
862
  {
 
863
   if(i == 0)
 
864
   {
 
865
    mulr[0] = -((RGB.R << 4) * v[0]);
 
866
    mulr[1] = (RGB.R << 4) * v[1];
 
867
    mulr[2] = IR0 * v[2];
 
868
   }
 
869
   else
 
870
   {
 
871
    mulr[0] = (int16)CR[i] * v[0];
 
872
    mulr[1] = (int16)CR[i] * v[1];
 
873
    mulr[2] = (int16)CR[i] * v[2];
 
874
   }
 
875
  }
 
876
  else
 
877
  {
 
878
   mulr[0] = matrix->MX[i][0] * v[0];
 
879
   mulr[1] = matrix->MX[i][1] * v[1];
 
880
   mulr[2] = matrix->MX[i][2] * v[2];
 
881
  }
 
882
 
 
883
  tmp = A_MV(i, tmp + mulr[0]);
 
884
  if(crv == CRVectors.FC)
 
885
  {
 
886
   Lm_B(i, tmp >> sf, FALSE);
 
887
   tmp = 0;
 
888
  }
 
889
 
 
890
  tmp = A_MV(i, tmp + mulr[1]);
 
891
  tmp = A_MV(i, tmp + mulr[2]);
 
892
 
 
893
  MAC[1 + i] = tmp >> sf;
 
894
 }
 
895
 
827
896
 
828
897
 MAC_to_IR(lm);
829
898
}
830
899
 
831
900
 
 
901
INLINE void MultiplyMatrixByVector_PT(const gtematrix *matrix, const int16 *v, const int32 *crv, uint32 sf, int lm)
 
902
{
 
903
 int64 tmp[3];
 
904
 unsigned i;
 
905
 
 
906
 for(i = 0; i < 3; i++)
 
907
 {
 
908
  int32 mulr[3];
 
909
 
 
910
  tmp[i] = (int64)crv[i] << 12;
 
911
 
 
912
  mulr[0] = matrix->MX[i][0] * v[0];
 
913
  mulr[1] = matrix->MX[i][1] * v[1];
 
914
  mulr[2] = matrix->MX[i][2] * v[2];
 
915
 
 
916
  tmp[i] = A_MV(i, tmp[i] + mulr[0]);
 
917
  tmp[i] = A_MV(i, tmp[i] + mulr[1]);
 
918
  tmp[i] = A_MV(i, tmp[i] + mulr[2]);
 
919
 
 
920
  MAC[1 + i] = tmp[i] >> sf;
 
921
 }
 
922
 
 
923
 IR1 = Lm_B(0, MAC[1], lm);
 
924
 IR2 = Lm_B(1, MAC[2], lm);
 
925
 //printf("FTV: %08x %08x\n", crv[2], (uint32)(tmp[2] >> 12));
 
926
 IR3 = Lm_B_PTZ(2, MAC[3], tmp[2] >> 12, lm);
 
927
 
 
928
 Z_FIFO[0] = Z_FIFO[1];
 
929
 Z_FIFO[1] = Z_FIFO[2];
 
930
 Z_FIFO[2] = Z_FIFO[3];
 
931
 Z_FIFO[3] = Lm_D(tmp[2] >> 12, TRUE);
 
932
}
 
933
 
 
934
 
832
935
#define VAR_UNUSED __attribute__((unused))
833
936
 
834
937
#define DECODE_FIELDS                                                   \
856
959
{
857
960
 DECODE_FIELDS;
858
961
 
859
 
 // Typecast to int64 shouldn't be necessary here (might be able to remove call to A()...
860
 
 MAC[1] = A(0, ((IR1 * IR1) >> sf));
861
 
 MAC[2] = A(1, ((IR2 * IR2) >> sf));
862
 
 MAC[3] = A(2, ((IR3 * IR3) >> sf));
 
962
 MAC[1] = ((IR1 * IR1) >> sf);
 
963
 MAC[2] = ((IR2 * IR2) >> sf);
 
964
 MAC[3] = ((IR3 * IR3) >> sf);
863
965
 
864
966
 MAC_to_IR(lm);
865
967
 
876
978
 return(8);
877
979
}
878
980
 
879
 
 
880
 
INLINE void PTransform(uint32 sf, int lm, unsigned int v)
881
 
{
882
 
 int64 h_div_sz;
883
 
 
884
 
 MultiplyMatrixByVector(&Matrices.Rot, Vectors[v], CRVectors.T, sf, lm);
885
 
 
886
 
 Z_FIFO[0] = Z_FIFO[1];
887
 
 Z_FIFO[1] = Z_FIFO[2];
888
 
 Z_FIFO[2] = Z_FIFO[3];
889
 
 Z_FIFO[3] = Lm_D(MAC[3]);
890
 
 
891
 
 // FIXME: division
892
 
 if(H < (Z_FIFO[3] * 2))
893
 
  h_div_sz = (((int64)H << 16)) / Z_FIFO[3];
 
981
static INLINE unsigned CountLeadingZeroU16(uint16 val)
 
982
{
 
983
 unsigned ret = 0;
 
984
 
 
985
 while(!(val & 0x8000) && ret < 16)
 
986
 {
 
987
  val <<= 1;
 
988
  ret++;
 
989
 }
 
990
 
 
991
 return ret;
 
992
}
 
993
 
 
994
static INLINE uint32 Divide(uint32 dividend, uint32 divisor)
 
995
{
 
996
 //if((Z_FIFO[3] * 2) > H)
 
997
 if((divisor * 2) > dividend)
 
998
 {
 
999
  unsigned shift_bias = CountLeadingZeroU16(divisor);
 
1000
 
 
1001
  dividend <<= shift_bias;
 
1002
  divisor <<= shift_bias;
 
1003
 
 
1004
  return ((int64)dividend * ReciprocalTable[divisor & 0x7FFF] + 32768) >> 16;
 
1005
 }
894
1006
 else
895
1007
 {
896
 
  h_div_sz = 0x1FFFF;
897
1008
  FLAGS |= 1 << 17;
 
1009
  return 0x1FFFF;
898
1010
 }
 
1011
}
899
1012
 
900
 
 MAC[0] = F(((int64)OFX + IR1 * h_div_sz + 32768) >> 16);
 
1013
static INLINE void TransformXY(int64 h_div_sz)
 
1014
{
 
1015
 MAC[0] = F((int64)OFX + IR1 * h_div_sz) >> 16;
901
1016
 XY_FIFO[3].X = Lm_G(0, MAC[0]);
902
1017
 
903
 
 MAC[0] = F(((int64)OFY + IR2 * h_div_sz + 32768) >> 16);
 
1018
 MAC[0] = F((int64)OFY + IR2 * h_div_sz) >> 16;
904
1019
 XY_FIFO[3].Y = Lm_G(1, MAC[0]);
905
1020
 
906
1021
 XY_FIFO[0] = XY_FIFO[1];
907
1022
 XY_FIFO[1] = XY_FIFO[2];
908
1023
 XY_FIFO[2] = XY_FIFO[3];
909
 
 
910
 
// MAC[0] = F((DQB + ((DQA * h_div_sz + 32768) >> 16)) >> 8 );
911
 
// IR0 = Lm_H(MAC[0]);
912
 
 
913
 
// printf("MOO: %d %d %16lld\n", DQB, DQA, (long long)h_div_sz);
914
 
 
 
1024
}
 
1025
 
 
1026
static INLINE void TransformDQ(int64 h_div_sz)
 
1027
{
915
1028
 MAC[0] = F((int64)DQB + DQA * h_div_sz);
916
 
 IR0 = Lm_H(MAC[0] >> sf);
 
1029
 IR0 = Lm_H(((int64)DQB + DQA * h_div_sz) >> 12);
917
1030
}
918
1031
 
919
1032
int32 RTPS(uint32 instr)
920
1033
{
921
1034
 DECODE_FIELDS;
922
 
 
923
 
 PTransform(sf, lm, 0);
 
1035
 int64 h_div_sz;
 
1036
 
 
1037
 MultiplyMatrixByVector_PT(&Matrices.Rot, Vectors[0], CRVectors.T, sf, lm);
 
1038
 h_div_sz = Divide(H, Z_FIFO[3]);
 
1039
 
 
1040
 TransformXY(h_div_sz);
 
1041
 TransformDQ(h_div_sz);
924
1042
 
925
1043
 return(15);
926
1044
}
931
1049
 int i;
932
1050
 
933
1051
 for(i = 0; i < 3; i++)
934
 
  PTransform(sf, lm, i);
 
1052
 {
 
1053
  int64 h_div_sz;
 
1054
 
 
1055
  MultiplyMatrixByVector_PT(&Matrices.Rot, Vectors[i], CRVectors.T, sf, lm);
 
1056
  h_div_sz = Divide(H, Z_FIFO[3]);
 
1057
 
 
1058
  TransformXY(h_div_sz);
 
1059
 
 
1060
  if(i == 2)
 
1061
   TransformDQ(h_div_sz);
 
1062
 }
935
1063
 
936
1064
 return(23);
937
1065
}
977
1105
 tmp_vector[0] = IR1; tmp_vector[1] = IR2; tmp_vector[2] = IR3;
978
1106
 MultiplyMatrixByVector(&Matrices.Color, tmp_vector, CRVectors.B, sf, lm);
979
1107
 
980
 
 MAC[1] = A(0, ((RGB.R << 4) * IR1) >> sf);
981
 
 MAC[2] = A(1, ((RGB.G << 4) * IR2) >> sf);
982
 
 MAC[3] = A(2, ((RGB.B << 4) * IR3) >> sf);
 
1108
 MAC[1] = ((RGB.R << 4) * IR1) >> sf;
 
1109
 MAC[2] = ((RGB.G << 4) * IR2) >> sf;
 
1110
 MAC[3] = ((RGB.B << 4) * IR3) >> sf;
983
1111
 
984
1112
 MAC_to_IR(lm);
985
1113
 
1008
1136
 
1009
1137
INLINE void DepthCue(int mult_IR123, int RGB_from_FIFO, uint32 sf, int lm)
1010
1138
{
1011
 
 int32 R_temp, G_temp, B_temp;
 
1139
 int32 RGB_temp[3];
 
1140
 int32 IR_temp[3] = { IR1, IR2, IR3 };
 
1141
 int i;
1012
1142
 
1013
1143
 //assert(sf);
1014
1144
 
1015
1145
 if(RGB_from_FIFO)
1016
1146
 {
1017
 
  R_temp = RGB_FIFO[0].R << 4;
1018
 
  G_temp = RGB_FIFO[0].G << 4;
1019
 
  B_temp = RGB_FIFO[0].B << 4;
 
1147
  RGB_temp[0] = RGB_FIFO[0].R << 4;
 
1148
  RGB_temp[1] = RGB_FIFO[0].G << 4;
 
1149
  RGB_temp[2] = RGB_FIFO[0].B << 4;
1020
1150
 }
1021
1151
 else
1022
1152
 {
1023
 
  R_temp = RGB.R << 4;
1024
 
  G_temp = RGB.G << 4;
1025
 
  B_temp = RGB.B << 4;
 
1153
  RGB_temp[0] = RGB.R << 4;
 
1154
  RGB_temp[1] = RGB.G << 4;
 
1155
  RGB_temp[2] = RGB.B << 4;
1026
1156
 }
1027
1157
 
1028
1158
 if(mult_IR123)
1029
1159
 {
1030
 
  // Note: Do not put A() here!  We might just want to change this to local temporaries.
1031
 
  MAC[1] = (((int64)CRVectors.FC[0] << 12) - R_temp * IR1) >> sf;
1032
 
  MAC[2] = (((int64)CRVectors.FC[1] << 12) - G_temp * IR2) >> sf;
1033
 
  MAC[3] = (((int64)CRVectors.FC[2] << 12) - B_temp * IR3) >> sf;
1034
 
 
1035
 
  MAC[1] = A(0, (R_temp * IR1 + IR0 * Lm_B(0, MAC[1], FALSE)) >> sf);
1036
 
  MAC[2] = A(1, (G_temp * IR2 + IR0 * Lm_B(1, MAC[2], FALSE)) >> sf);
1037
 
  MAC[3] = A(2, (B_temp * IR3 + IR0 * Lm_B(2, MAC[3], FALSE)) >> sf);
1038
 
 
1039
 
/*
1040
 
  MAC[1] = A(0, (int64)((R_temp * IR1) >> sf) + IR0 * Lm_B(0, (int64)CRVectors.FC[0] - ((R_temp * IR1) >> sf), FALSE) );
1041
 
  MAC[2] = A(1, (int64)((G_temp * IR2) >> sf) + IR0 * Lm_B(1, (int64)CRVectors.FC[1] - ((G_temp * IR2) >> sf), FALSE) );
1042
 
  MAC[3] = A(2, (int64)((B_temp * IR3) >> sf) + IR0 * Lm_B(2, (int64)CRVectors.FC[2] - ((B_temp * IR3) >> sf), FALSE) );
1043
 
*/
 
1160
  for(i = 0; i < 3; i++)
 
1161
  {
 
1162
   MAC[1 + i] = A_MV(i, (((int64)CRVectors.FC[i] << 12) - RGB_temp[i] * IR_temp[i])) >> sf;
 
1163
   MAC[1 + i] = A_MV(i, (RGB_temp[i] * IR_temp[i] + IR0 * Lm_B(i, MAC[1 + i], FALSE))) >> sf;
 
1164
  }
1044
1165
 }
1045
1166
 else
1046
1167
 {
1047
 
  // Note: Do not put A() here!  We might just want to change this to local temporaries.
1048
 
  MAC[1] = (((int64)CRVectors.FC[0] << 12) - (R_temp << 12)) >> sf;
1049
 
  MAC[2] = (((int64)CRVectors.FC[1] << 12) - (G_temp << 12)) >> sf;
1050
 
  MAC[3] = (((int64)CRVectors.FC[2] << 12) - (B_temp << 12)) >> sf;
1051
 
 
1052
 
  MAC[1] = A(0, (((int64)R_temp << 12) + IR0 * Lm_B(0, MAC[1], FALSE)) >> sf);
1053
 
  MAC[2] = A(1, (((int64)G_temp << 12) + IR0 * Lm_B(1, MAC[2], FALSE)) >> sf);
1054
 
  MAC[3] = A(2, (((int64)B_temp << 12) + IR0 * Lm_B(2, MAC[3], FALSE)) >> sf);
1055
 
 
1056
 
/*
1057
 
  MAC[1] = A(0, (int64)R_temp + ((IR0 * Lm_B(0, (int64)CRVectors.FC[0] - R_temp, FALSE)) >> sf) );
1058
 
  MAC[2] = A(1, (int64)G_temp + ((IR0 * Lm_B(1, (int64)CRVectors.FC[1] - G_temp, FALSE)) >> sf) );
1059
 
  MAC[3] = A(2, (int64)B_temp + ((IR0 * Lm_B(2, (int64)CRVectors.FC[2] - B_temp, FALSE)) >> sf) );
1060
 
*/
 
1168
  for(i = 0; i < 3; i++)
 
1169
  {
 
1170
   MAC[1 + i] = A_MV(i, (((int64)CRVectors.FC[i] << 12) - (RGB_temp[i] << 12))) >> sf;
 
1171
   MAC[1 + i] = A_MV(i, (((int64)RGB_temp[i] << 12) + IR0 * Lm_B(i, MAC[1 + i], FALSE))) >> sf;
 
1172
  }
1061
1173
 }
1062
1174
 
1063
1175
 MAC_to_IR(lm);
1098
1210
 return(17);
1099
1211
}
1100
1212
 
1101
 
// SF field *is* used(tested), but it's a bit...weird.
1102
1213
int32 INTPL(uint32 instr)
1103
1214
{
1104
1215
 DECODE_FIELDS;
1105
1216
 
1106
 
 //if(sf)
1107
 
 //{
1108
 
 // MAC[1] = A(0, (int64)IR1 + ((IR0 * Lm_B(0, (int64)CRVectors.FC[0] - IR1, FALSE)) >> 12) );
1109
 
 // MAC[2] = A(1, (int64)IR2 + ((IR0 * Lm_B(1, (int64)CRVectors.FC[1] - IR2, FALSE)) >> 12) );
1110
 
 // MAC[3] = A(2, (int64)IR3 + ((IR0 * Lm_B(2, (int64)CRVectors.FC[2] - IR3, FALSE)) >> 12) );
1111
 
 //}
1112
 
 //else
1113
 
 //{
1114
 
 
1115
 
 // Note: Do not put A() here!  We might just want to change this to local temporaries.
1116
 
 MAC[1] = (((int64)CRVectors.FC[0] << 12) - (IR1 << 12)) >> sf;
1117
 
 MAC[2] = (((int64)CRVectors.FC[1] << 12) - (IR2 << 12)) >> sf;
1118
 
 MAC[3] = (((int64)CRVectors.FC[2] << 12) - (IR3 << 12)) >> sf;
1119
 
 
1120
 
 MAC[1] = A(0, (((int64)IR1 << 12) + IR0 * Lm_B(0, MAC[1], FALSE)) >> sf);
1121
 
 MAC[2] = A(1, (((int64)IR2 << 12) + IR0 * Lm_B(1, MAC[2], FALSE)) >> sf);
1122
 
 MAC[3] = A(2, (((int64)IR3 << 12) + IR0 * Lm_B(2, MAC[3], FALSE)) >> sf);
1123
 
// }
 
1217
 MAC[1] = A_MV(0, (((int64)CRVectors.FC[0] << 12) - (IR1 << 12))) >> sf;
 
1218
 MAC[2] = A_MV(1, (((int64)CRVectors.FC[1] << 12) - (IR2 << 12))) >> sf;
 
1219
 MAC[3] = A_MV(2, (((int64)CRVectors.FC[2] << 12) - (IR3 << 12))) >> sf;
 
1220
 
 
1221
 MAC[1] = A_MV(0, (((int64)IR1 << 12) + IR0 * Lm_B(0, MAC[1], FALSE)) >> sf);
 
1222
 MAC[2] = A_MV(1, (((int64)IR2 << 12) + IR0 * Lm_B(1, MAC[2], FALSE)) >> sf);
 
1223
 MAC[3] = A_MV(2, (((int64)IR3 << 12) + IR0 * Lm_B(2, MAC[3], FALSE)) >> sf);
1124
1224
 
1125
1225
 MAC_to_IR(lm);
1126
1226
 
1157
1257
 DECODE_FIELDS;
1158
1258
 
1159
1259
 for(i = 0; i < 3; i++)
 
1260
 {
1160
1261
  NormColorDepthCue(i, sf, lm);
 
1262
 }
1161
1263
 
1162
1264
 return(44);
1163
1265
}
1164
1266
 
 
1267
int32 CC(uint32 instr)
 
1268
{
 
1269
 DECODE_FIELDS;
 
1270
 int16 tmp_vector[3];
 
1271
 
 
1272
 tmp_vector[0] = IR1; tmp_vector[1] = IR2; tmp_vector[2] = IR3;
 
1273
 MultiplyMatrixByVector(&Matrices.Color, tmp_vector, CRVectors.B, sf, lm);
 
1274
 
 
1275
 MAC[1] = ((RGB.R << 4) * IR1) >> sf;
 
1276
 MAC[2] = ((RGB.G << 4) * IR2) >> sf;
 
1277
 MAC[3] = ((RGB.B << 4) * IR3) >> sf;
 
1278
 
 
1279
 MAC_to_IR(lm);
 
1280
 
 
1281
 MAC_to_RGB_FIFO();
 
1282
 
 
1283
 return(11);
 
1284
}
 
1285
 
 
1286
int32 CDP(uint32 instr)
 
1287
{
 
1288
 DECODE_FIELDS;
 
1289
 int16 tmp_vector[3];
 
1290
 
 
1291
 tmp_vector[0] = IR1; tmp_vector[1] = IR2; tmp_vector[2] = IR3;
 
1292
 MultiplyMatrixByVector(&Matrices.Color, tmp_vector, CRVectors.B, sf, lm);
 
1293
 
 
1294
 DepthCue(TRUE, FALSE, sf, lm);
 
1295
 
 
1296
 return(13);
 
1297
}
 
1298
 
1165
1299
int32 NCLIP(uint32 instr)
1166
1300
{
1167
1301
 DECODE_FIELDS;
1172
1306
 return(8);
1173
1307
}
1174
1308
 
1175
 
// tested, SF field doesn't matter?
1176
1309
int32 AVSZ3(uint32 instr)
1177
1310
{
1178
1311
 DECODE_FIELDS;
1179
1312
 
1180
1313
 MAC[0] = F(((int64)ZSF3 * (Z_FIFO[1] + Z_FIFO[2] + Z_FIFO[3])));
1181
1314
 
1182
 
 OTZ = Lm_D(MAC[0] >> 12);
 
1315
 OTZ = Lm_D(MAC[0] >> 12, FALSE);
1183
1316
 
1184
1317
 return(5);
1185
1318
}
1190
1323
 
1191
1324
 MAC[0] = F(((int64)ZSF4 * (Z_FIFO[0] + Z_FIFO[1] + Z_FIFO[2] + Z_FIFO[3])));
1192
1325
 
1193
 
 OTZ = Lm_D(MAC[0] >> 12);
 
1326
 OTZ = Lm_D(MAC[0] >> 12, FALSE);
1194
1327
 
1195
1328
 return(5);
1196
1329
}
1197
1330
 
1198
1331
 
 
1332
// -32768 * -32768 - 32767 * -32768 = 2147450880
 
1333
// (2 ^ 31) - 1 =                     2147483647
1199
1334
int32 OP(uint32 instr)
1200
1335
{
1201
1336
 DECODE_FIELDS;
1202
1337
 
1203
 
 MAC[1] = A(0, ((int64)(Matrices.Rot.MX[1][1] * IR3) - (Matrices.Rot.MX[2][2] * IR2)) >> sf);
1204
 
 MAC[2] = A(1, ((int64)(Matrices.Rot.MX[2][2] * IR1) - (Matrices.Rot.MX[0][0] * IR3)) >> sf);
1205
 
 MAC[3] = A(2, ((int64)(Matrices.Rot.MX[0][0] * IR2) - (Matrices.Rot.MX[1][1] * IR1)) >> sf);
 
1338
 MAC[1] = ((Matrices.Rot.MX[1][1] * IR3) - (Matrices.Rot.MX[2][2] * IR2)) >> sf;
 
1339
 MAC[2] = ((Matrices.Rot.MX[2][2] * IR1) - (Matrices.Rot.MX[0][0] * IR3)) >> sf;
 
1340
 MAC[3] = ((Matrices.Rot.MX[0][0] * IR2) - (Matrices.Rot.MX[1][1] * IR1)) >> sf;
1206
1341
 
1207
1342
 MAC_to_IR(lm);
1208
1343
 
1213
1348
{
1214
1349
 DECODE_FIELDS;
1215
1350
 
1216
 
 MAC[1] = A(0, ((IR0 * IR1) >> sf));
1217
 
 MAC[2] = A(1, ((IR0 * IR2) >> sf));
1218
 
 MAC[3] = A(2, ((IR0 * IR3) >> sf));
 
1351
 MAC[1] = (IR0 * IR1) >> sf;
 
1352
 MAC[2] = (IR0 * IR2) >> sf;
 
1353
 MAC[3] = (IR0 * IR3) >> sf;
1219
1354
 
1220
1355
 MAC_to_IR(lm);
1221
1356
 
1228
1363
{
1229
1364
 DECODE_FIELDS;
1230
1365
 
1231
 
 
1232
 
 MAC[1] = A(0, ((int64)MAC[1] + ((IR0 * IR1) >> sf)));
1233
 
 MAC[2] = A(1, ((int64)MAC[2] + ((IR0 * IR2) >> sf)));
1234
 
 MAC[3] = A(2, ((int64)MAC[3] + ((IR0 * IR3) >> sf)));
 
1366
 MAC[1] = A_MV(0, ((int64)MAC[1] << sf) + (IR0 * IR1)) >> sf;
 
1367
 MAC[2] = A_MV(1, ((int64)MAC[2] << sf) + (IR0 * IR2)) >> sf;
 
1368
 MAC[3] = A_MV(2, ((int64)MAC[3] << sf) + (IR0 * IR3)) >> sf;
1235
1369
 
1236
1370
 MAC_to_IR(lm);
1237
1371
 
1240
1374
 return(5);
1241
1375
}
1242
1376
 
1243
 
 
1244
1377
/*
1245
 
 
1246
 
 
1247
 
24 23 22 21 20|19|18 17|16 15|14 13|12 11|10| 9  8| 7  6| 5  4  3  2  1  0
1248
 
              |sf| mx  |  v  |  cv |-----|lm|-----------|
1249
 
 
 
1378
 
 
1379
---------------------------------------------------------------------------------------------
 
1380
| 24 23 22 21 20 | 19 | 18 17 | 16 15 | 14 13 | 12  11 | 10 | 9  8  7  6 | 5  4  3  2  1  0 |
 
1381
|-------------------------------------------------------------------------------------------|
 
1382
|    (unused)    | sf |  mx   |   v   |   cv  |(unused)| lm |  (unused)  |     opcode       |
 
1383
---------------------------------------------------------------------------------------------
 
1384
 (unused) = unused, ignored
1250
1385
 
1251
1386
 sf = shift 12
1252
1387
 
1256
1391
 
1257
1392
 cv = add vector(translation/back/far color(bugged)/none)
1258
1393
 
 
1394
 (unused) = unused, ignored
 
1395
 
1259
1396
 lm = limit negative results to 0
1260
1397
 
 
1398
 (unused) = unused, ignored
 
1399
 
 
1400
 opcode = operation code 
1261
1401
*/
1262
1402
 
1263
1403
int32 GTE_Instruction(uint32 instr)
1264
1404
{
 
1405
 const unsigned code = instr & 0x3F;
1265
1406
 int32 ret = 1;
1266
1407
 
1267
 
 //PSX_WARNING("[GTE] Instruction 0x%08x", instr);
1268
 
 
1269
1408
 FLAGS = 0;
1270
1409
 
1271
 
 switch(instr & ((0x1F << 20) | 0x3F))
 
1410
 switch(code)
1272
1411
 {
1273
 
  default: //PSX_WARNING("[GTE] Unknown instruction: 0x%08x, 0x%08x", instr & ~(0x7F << 25), instr & ((0x1F << 20) | 0x3F));
 
1412
  default: 
 
1413
#ifndef PSXDEV_GTE_TESTING
 
1414
           PSX_WARNING("[GTE] Unknown instruction code: 0x%02x", code);
 
1415
#endif
1274
1416
           break;
1275
1417
 
1276
 
  case 0x0100001:
 
1418
  case 0x00:    // alternate?
 
1419
  case 0x01:
1277
1420
        ret = RTPS(instr);
1278
1421
        break;
1279
1422
 
1280
 
  case 0x0200030:
1281
 
        ret = RTPT(instr);
1282
 
        break;
1283
 
 
1284
 
  case 0x0400012:
1285
 
        ret = MVMVA(instr);
1286
 
        break;
1287
 
 
1288
 
  case 0x0600029:
1289
 
        ret = DCPL(instr);
1290
 
        break;
1291
 
 
1292
 
  case 0x0700010:       // RR
 
1423
/*
 
1424
  case 0x02:    // UNSTABLE?
 
1425
        break;
 
1426
 
 
1427
  case 0x03:    // UNSTABLE?
 
1428
        break;
 
1429
 
 
1430
  case 0x04:    // Probably simple with v,cv,sf,mx,lm ignored.  Same calculation as 0x3B?
 
1431
        break;
 
1432
 
 
1433
  case 0x05:    // UNSTABLE?
 
1434
        break;
 
1435
*/
 
1436
 
 
1437
  case 0x06:
 
1438
        ret = NCLIP(instr);
 
1439
        break;
 
1440
 
 
1441
/*
 
1442
  case 0x07:    // UNSTABLE?
 
1443
        break;
 
1444
 
 
1445
  case 0x08:    // UNSTABLE?
 
1446
        break;
 
1447
 
 
1448
  case 0x09:    // UNSTABLE?
 
1449
        break;
 
1450
 
 
1451
  case 0x0A:    // UNSTABLE?
 
1452
        break;
 
1453
 
 
1454
  case 0x0B:    // UNSTABLE?
 
1455
        break;
 
1456
 
 
1457
*/
 
1458
 
 
1459
  case 0x0C:
 
1460
        ret = OP(instr);
 
1461
        break;
 
1462
 
 
1463
/*
 
1464
  case 0x0D:    // UNSTABLE?
 
1465
        break;
 
1466
 
 
1467
  case 0x0E:    // UNSTABLE?
 
1468
        break;
 
1469
 
 
1470
  case 0x0F:    // UNSTABLE?
 
1471
        break;
 
1472
*/
 
1473
 
 
1474
  case 0x10:
1293
1475
        ret = DPCS(instr);
1294
1476
        break;
1295
1477
 
1296
 
  case 0x0900011:       // RR
 
1478
  case 0x11:
1297
1479
        ret = INTPL(instr);
1298
1480
        break;
1299
1481
 
1300
 
  case 0x0A00028:
1301
 
        ret = SQR(instr);
1302
 
        break;
1303
 
 
1304
 
  case 0x0c0001e:
 
1482
  case 0x12:
 
1483
        ret = MVMVA(instr);
 
1484
        break;
 
1485
 
 
1486
  case 0x13:
 
1487
        ret = NCDS(instr);
 
1488
        break;
 
1489
 
 
1490
  case 0x14:
 
1491
        ret = CDP(instr);
 
1492
        break;
 
1493
 
 
1494
 
 
1495
/*
 
1496
  case 0x15:    // does one push on RGB FIFO, what else...
 
1497
        break;
 
1498
*/
 
1499
 
 
1500
  case 0x16:
 
1501
        ret = NCDT(instr);
 
1502
        break;
 
1503
 
 
1504
/*
 
1505
  case 0x17:    // PARTIALLY UNSTABLE(depending on sf or v or cv or mx or lm???), similar behavior under some conditions to 0x16?
 
1506
        break;
 
1507
 
 
1508
  case 0x18:
 
1509
        break;
 
1510
 
 
1511
  case 0x19:
 
1512
        break;
 
1513
*/
 
1514
 
 
1515
  case 0x1A:    // Alternate for 0x29?
 
1516
        ret = DCPL(instr);
 
1517
        break;
 
1518
 
 
1519
  case 0x1B:
 
1520
        ret = NCCS(instr);
 
1521
        break;
 
1522
 
 
1523
  case 0x1C:
 
1524
        ret = CC(instr);
 
1525
        break;
 
1526
 
 
1527
/*
 
1528
  case 0x1D:
 
1529
        break;
 
1530
*/
 
1531
 
 
1532
  case 0x1E:
1305
1533
        ret = NCS(instr);
1306
1534
        break;
1307
1535
 
1308
 
  case 0x0d00020:
 
1536
/*
 
1537
  case 0x1F:
 
1538
        break;
 
1539
*/
 
1540
 
 
1541
  case 0x20:
1309
1542
        ret = NCT(instr);
1310
1543
        break;
1311
 
 
1312
 
  case 0x0e00013:
1313
 
        ret = NCDS(instr);
1314
 
        break;
1315
 
 
1316
 
  case 0x0f00016:
1317
 
        ret = NCDT(instr);
1318
 
        break;
1319
 
 
1320
 
  case 0x0F0002A:
 
1544
/*
 
1545
  case 0x21:
 
1546
        break;
 
1547
 
 
1548
  case 0x22:    // UNSTABLE?
 
1549
        break;
 
1550
 
 
1551
  case 0x23:
 
1552
        break;
 
1553
 
 
1554
  case 0x24:
 
1555
        break;
 
1556
 
 
1557
  case 0x25:
 
1558
        break;
 
1559
 
 
1560
  case 0x26:
 
1561
        break;
 
1562
 
 
1563
  case 0x27:
 
1564
        break;
 
1565
*/
 
1566
 
 
1567
  case 0x28:
 
1568
        ret = SQR(instr);
 
1569
        break;
 
1570
 
 
1571
  case 0x29:
 
1572
        ret = DCPL(instr);
 
1573
        break;
 
1574
 
 
1575
  case 0x2A:
1321
1576
        ret = DPCT(instr);
1322
1577
        break;
1323
1578
 
1324
 
  case 0x100001b:
1325
 
        ret = NCCS(instr);
1326
 
        break;
1327
 
 
1328
 
  case 0x110003f:
1329
 
        ret = NCCT(instr);
1330
 
        break;
1331
 
 
1332
 
  case 0x1400006:
1333
 
        ret = NCLIP(instr);
1334
 
        break;
1335
 
 
1336
 
  case 0x150002d:
 
1579
/*
 
1580
  case 0x2B:
 
1581
        break;
 
1582
 
 
1583
  case 0x2C:
 
1584
        break;
 
1585
*/
 
1586
 
 
1587
  case 0x2D:
1337
1588
        ret = AVSZ3(instr);
1338
1589
        break;
1339
1590
 
1340
 
  case 0x160002E:
 
1591
  case 0x2E:
1341
1592
        ret = AVSZ4(instr);
1342
1593
        break;
1343
1594
 
1344
 
  case 0x170000C:
1345
 
        ret = OP(instr);
1346
 
        break;
1347
 
 
1348
 
  case 0x190003D:
 
1595
/*
 
1596
  case 0x2F:    // UNSTABLE?
 
1597
        break;
 
1598
*/
 
1599
 
 
1600
  case 0x30:
 
1601
        ret = RTPT(instr);
 
1602
        break;
 
1603
 
 
1604
/*
 
1605
  case 0x31:    // UNSTABLE?
 
1606
        break;
 
1607
 
 
1608
  case 0x32:    // UNSTABLE?
 
1609
        break;
 
1610
 
 
1611
  case 0x33:    // UNSTABLE?
 
1612
        break;
 
1613
 
 
1614
  case 0x34:    // UNSTABLE?
 
1615
        break;
 
1616
 
 
1617
  case 0x35:    // UNSTABLE?
 
1618
        break;
 
1619
 
 
1620
  case 0x36:    // UNSTABLE?
 
1621
        break;
 
1622
 
 
1623
  case 0x37:    // UNSTABLE?
 
1624
        break;
 
1625
 
 
1626
  case 0x38:
 
1627
        break;
 
1628
 
 
1629
  case 0x39:    // Probably simple with v,cv,sf,mx,lm ignored.
 
1630
        break;
 
1631
 
 
1632
  case 0x3A:    // Probably simple with v,cv,sf,mx,lm ignored.
 
1633
        break;
 
1634
 
 
1635
  case 0x3B:    // Probably simple with v,cv,sf,mx,lm ignored.  Same calculation as 0x04?
 
1636
        break;
 
1637
 
 
1638
  case 0x3C:    // UNSTABLE?
 
1639
        break;
 
1640
*/
 
1641
 
 
1642
  case 0x3D:
1349
1643
        ret = GPF(instr);
1350
1644
        break;
1351
1645
 
1352
 
  case 0x1A0003E:
 
1646
  case 0x3E:
1353
1647
        ret = GPL(instr);
1354
1648
        break;
1355
1649
        
 
1650
  case 0x3F:
 
1651
        ret = NCCT(instr);
 
1652
        break;
1356
1653
 }
1357
1654
 
1358
1655
 if(FLAGS & 0x7f87e000)
1360
1657
 
1361
1658
 CR[31] = FLAGS;
1362
1659
 
1363
 
 //if(timestamp < ts_done)
1364
 
 // ret = ts_done - timestamp;
1365
 
 
1366
 
 // Execute instruction here, and set ts_done
1367
 
 // ts_done = timestamp + InstrMap[instr]();
1368
 
 
1369
1660
 return(ret - 1);
1370
1661
}
1371
1662