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