1 /******************************************************************************/
2 /* Mednafen NEC PC-FX Emulation Module                                        */
3 /******************************************************************************/
4 /* huc6273.cpp - Unfinished emulation of the HuC6273, 3D chip in the PC-FXGA
5 **  Copyright (C) 2007-2016 Mednafen Team
6 **
7 ** This program is free software; you can redistribute it and/or
8 ** modify it under the terms of the GNU General Public License
9 ** as published by the Free Software Foundation; either version 2
10 ** of the License, or (at your option) any later version.
11 **
12 ** This program is distributed in the hope that it will be useful,
13 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
14 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 ** GNU General Public License for more details.
16 **
17 ** You should have received a copy of the GNU General Public License
18 ** along with this program; if not, write to the Free Software Foundation, Inc.,
19 ** 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
20 */
21 
22 /* Definitions:
23 	CMT = Command Macro Table
24 */
25 
26 #include "pcfx.h"
27 #include "huc6273.h"
28 
29 namespace MDFN_IEN_PCFX
30 {
31 
32 enum
33 {
34 	OP_NOP = 0x00,
35 	OP_TRIANGLE_STRIP = 0x01,
36 	OP_TRIANGLE_LIST = 0x02,
37 	OP_POLY_LINE = 0x03,
38 	OP_LINE_LIST = 0x04,
39 	OP_RESERVED0 = 0x05,
40 	OP_PUT_IMAGE = 0x06,
41 	OP_READ_PIXEL = 0x07,
42 	OP_WRITE_TE_REGISTERS = 0x08,
43 	OP_WRITE_PE_REGISTERS = 0x09,
44 	OP_MISC = 0x0A,
45 	OP_RESERVED1 = 0x0B,
46 	OP_READ_TE_REGISTERS = 0x0C,
47 	OP_READ_PE_REGISTERS = 0x0D,
48 	OP_WRITE_LUT = 0x0E,
49 	OP_READ_LUT = 0x0F,
50 };
51 
52 enum
53 {
54  INT_RHIT = 15,	// Raster Hit
55  INT_HBL = 14, // H blank
56  INT_VBL = 13, // V blank
57  INT_HSY = 12, // H sync
58  INT_VSY = 11, // V sync
59  INT_RBDONE = 10, // Read back done
60  INT_TESYNC = 9, // TE Sync
61  INT_SPDONE = 8, // Sprite done
62  INT_CMDONE = 7, // Command macro done
63  INT_PESYNC = 6, // PE sync
64  INT_AEMP = 5, // Almost empty
65  INT_CSE = 4, // Command sync error
66  INT_AFL = 3, // Almost full
67  INT_OVF = 2, // Overflow
68  INT_FSY = 1, // Frame sync
69 };
70 
71 static uint16 FIFO[0x20];
72 static uint8 InFIFO;
73 #define AFW (0x20 - InFIFO)
74 
75 #define AEMPWD ((FIFOControl >> 4) & 0xFF)
76 #define AFLWD (FIFOControl & 0xF)
77 static uint16 FIFOControl; // 0x00004
78 
79 static uint8 CMTBankSelect;
80 static uint16 CMTStartAddress;
81 static uint16 CMTByteCount;
82 
83 static uint16 InterruptMask;
84 static uint16 InterruptStatus;
85 
86 static uint16 ReadBack;
87 
88 static uint16 HorizontalTiming, VerticalTiming;
89 
90 static uint16 SCTAddressHi;
91 static uint16 SpriteControl;
92 static uint16 CDResult[2];
93 static uint16 SPWindowX[2]; // left and right
94 static uint16 SPWindowY[2]; // top and bottom
95 static uint16 MiscStatus;
96 static uint16 ErrorStatus; // Read only!
97 static uint16 DisplayControl;
98 static uint16 StatusControl;
99 static uint16 Config;
100 
101 static uint16 RasterHit;
102 
103 
104 static uint16 Results[0x10];
105 
CheckIRQ(void)106 static void CheckIRQ(void)
107 {
108  //uint16 MaskedResults = InterruptStatus & InterruptMask;
109 
110 
111 
112 }
113 
114 
ProcessFIFO(void)115 static void ProcessFIFO(void)
116 {
117  uint8 length = FIFO[0] & 0xFF;
118 
119  if(length > 0x20)
120  {
121   length = 0x20;
122   puts("Length too long");
123  }
124 
125  if(InFIFO >= length)
126  {
127   int opcode = FIFO[0] >> 12;
128   int option = (FIFO[0] >> 8) & 0x0F;
129 
130   printf("Op: %02x, option: %02x\n", opcode, option);
131 
132   InFIFO -= length;
133   for(int i = 0; i < InFIFO; i++)
134    FIFO[i] = FIFO[length + i];
135  }
136 }
137 
138 
StoreInFIFO(uint16 V)139 static void StoreInFIFO(uint16 V)
140 {
141  if(AFW > 0)
142  {
143   FIFO[InFIFO] = V;
144   InFIFO++;
145 
146   ProcessFIFO();
147  }
148 }
149 
HuC6273_Read8(uint32 A)150 uint8 HuC6273_Read8(uint32 A)
151 {
152  puts("73 Read8");
153  return(0);
154 }
155 
HuC6273_Read16(uint32 A)156 uint16 HuC6273_Read16(uint32 A)
157 {
158  A &= 0xfffff;
159 
160  printf("HuC6273 Read: %04x\n", A);
161 
162  switch(A)
163  {
164   case 0x00000:
165   case 0x00002: return(AFW); // Command FIFO status
166 
167   case 0x00004: return(FIFOControl);
168   case 0x00006: return(CMTBankSelect);
169   case 0x00008: return(CMTStartAddress);
170   case 0x0000A: return(CMTByteCount);
171   case 0x0000C: return(InterruptMask);
172   case 0x0000E: return(0);
173   case 0x00010: return(InterruptStatus);
174   case 0x00012: return(ReadBack);
175   case 0x00014: return(HorizontalTiming);
176   case 0x00016: return(VerticalTiming);
177   case 0x00018: return(SCTAddressHi);
178   case 0x0001A: return(SpriteControl);
179   case 0x0001C: return(CDResult[0]);
180   case 0x0001E: return(CDResult[1]);
181   case 0x00020: return(SPWindowX[0]);
182   case 0x00022: return(SPWindowY[0]);
183   case 0x00024: return(SPWindowX[1]);
184   case 0x00026: return(SPWindowY[1]);
185   case 0x00028: return(MiscStatus);
186   case 0x0002A: return(ErrorStatus);
187   case 0x0002C: return(DisplayControl);
188   case 0x0002E: return(Config);
189  }
190  if(A >= 0x00060 && A <= 0x0007E)
191  {
192   return(Results[(A >> 1) & 0xF]);
193  }
194  return(0);
195 }
196 
197 
HuC6273_Write16(uint32 A,uint16 V)198 void HuC6273_Write16(uint32 A, uint16 V)
199 {
200  A &= 0xfffff;
201 
202  printf("HuC6273 Write: %04x:%04x\n", A, V);
203 
204  switch(A)
205  {
206   case 0x00000:
207   case 0x00002: StoreInFIFO(V); break;
208 
209   case 0x00004: FIFOControl = V; break;
210   case 0x00006: CMTBankSelect = V & 0x1F; break;
211   case 0x00008: CMTStartAddress = V & 0xFFFE; break;
212   case 0x0000A: CMTByteCount = V & 0xFFFE; break;
213   case 0x0000C: InterruptMask = V;
214 		CheckIRQ();
215 		break;
216   case 0x0000E: // Interrupt Clear
217 		CheckIRQ();
218 		break;
219   case 0x00010: InterruptStatus = V;
220 		CheckIRQ();
221 		break;
222   case 0x00012: ReadBack = V; break;
223   case 0x00014: HorizontalTiming = V; break;
224   case 0x00016: VerticalTiming = V; break;
225   case 0x00018: SCTAddressHi = V; break;
226   case 0x0001A: SpriteControl = V; break;
227   case 0x0001C: CDResult[0] = V; break;
228   case 0x0001E: CDResult[1] = V; break;
229   case 0x00020: SPWindowX[0] = V; break; // X Left
230   case 0x00022: SPWindowY[0] = V; break; // Y Top
231   case 0x00024: SPWindowX[1] = V; break; // X Right
232   case 0x00026: SPWindowY[1] = V; break; // Y Bottom
233   case 0x00028: MiscStatus = V; break;
234   case 0x0002C: DisplayControl = V; break;
235   case 0x0002E: StatusControl = V; break;
236 
237   case 0x0003C: RasterHit = V; break;
238  }
239 }
240 
HuC6273_Write8(uint32 A,uint8 V)241 void HuC6273_Write8(uint32 A, uint8 V)
242 {
243  puts("73 Write8");
244 }
245 
HuC6273_Reset(void)246 void HuC6273_Reset(void)
247 {
248  InFIFO = 0;
249  FIFOControl = 0x5 | (0x20 << 4);
250 }
251 
252 
253 
HuC6273_Init(void)254 bool HuC6273_Init(void)
255 {
256 
257  return(true);
258 }
259 
260 }
261