Previous 199869 Revisions Next

r33697 Thursday 4th December, 2014 at 18:57:06 UTC by Samuele Zannoli
Update
[hash]leapster.xml
[src/emu]luaengine.c luaengine.h
[src/emu/cpu/arc]arc.h
[src/emu/cpu/arcompact]arcompactdasm.c
[src/emu/cpu/pps4]pps4.c
[src/emu/video]poly.h
[src/lib/formats]victor9k_dsk.c victor9k_dsk.h
[src/mame]mame.mak
[src/mame/drivers]chihiro.c gts1.c naomi.c
[src/mame/includes]chihiro.h*
[src/mame/machine]mie.c naomim4.c
[src/mame/video]btime.c chihiro.c*
[src/mess]mess.lst
[src/mess/drivers]cnsector.c comp4.c gamate.c leapster.c megadriv.c merlin.c simon.c starwbc.c ticalc1x.c
[src/mess/layout]starwbc.lay

trunk/hash/leapster.xml
r242208r242209
177177      </part>
178178   </software>
179179
180
181   <software name="jedimath" supported="no">
182      <description>Star Wars - Jedi Math (US)</description>
183      <year>2003</year>
184      <publisher>LeapFrog</publisher>
185      <part name="cart" interface="leapster_cart">
186         <dataarea name="rom" size="0x800000">
187            <rom name="500-13306-a - star wars - jedi math (us).bin" size="0x800000" crc="27000674" sha1="a7e8e63ab74931ad9546aba20755714df572badb" offset="0x00000" />
188         </dataarea>
189      </part>
190   </software>
191
192   <software name="carssc" supported="no">
193      <description>Cars - Supercharged (US)</description>
194      <year>2003</year>
195      <publisher>LeapFrog</publisher>
196      <part name="cart" interface="leapster_cart">
197         <dataarea name="rom" size="0x800000">
198            <rom name="500-12712-a - cars - supercharged (us).bin" size="0x800000" crc="beca3909" sha1="8cda80251d6e45427dba6acbae5dff306eb84d34" offset="0x00000" />
199         </dataarea>
200      </part>
201   </software>
202
203   <software name="clifread" supported="no">
204      <description>Clifford - The big red dog - Reading (US)</description>
205      <year>2003</year>
206      <publisher>LeapFrog</publisher>
207      <part name="cart" interface="leapster_cart">
208         <dataarea name="rom" size="0x800000">
209            <rom name="500-12466-a - clifford - the big red dog - reading (us).bin" size="0x800000" crc="0134af49" sha1="29c3e2e9d56aeee09c752776bfd8c096e02b75c5" offset="0x00000" />
210         </dataarea>
211      </part>
212   </software>
213
214  <software name="digdino" supported="no">
215      <description>Digging for Dinosaurs (US)</description>
216      <year>2003</year>
217      <publisher>LeapFrog</publisher>
218      <part name="cart" interface="leapster_cart">
219         <dataarea name="rom" size="0x800000">
220            <rom name="500-13681-a - digging for dinosaurs (us).bin" size="0x800000" crc="822ca3da" sha1="ff0ac7f5fded346553e1a4697b45c27fc04ee3fe" offset="0x00000" />
221         </dataarea>
222      </part>
223   </software>
224
225   <software name="getpuzld" supported="no">
226      <description>Get Puzzled! (US)</description>
227      <year>2003</year>
228      <publisher>LeapFrog</publisher>
229      <part name="cart" interface="leapster_cart">
230         <dataarea name="rom" size="0x800000">
231            <rom name="500-12692-a - get puzzled! (us).bin" size="0x800000" crc="05b608f0" sha1="04b3181f39e88b6cd47e39a7efb50fa14618ff2c" offset="0x00000" />
232         </dataarea>
233      </part>
234   </software>
235
236   <software name="hugenose" supported="no">
237      <description>Reading with Phonics - Mole's Huge Nose (US)</description>
238      <year>2003</year>
239      <publisher>LeapFrog</publisher>
240      <part name="cart" interface="leapster_cart">
241         <dataarea name="rom" size="0x800000">
242            <rom name="500-10829-a - reading with phonics - mole's huge nose (us).bin" size="0x800000" crc="2c6e623e" sha1="c298181f00109b7f863fdb12b5bd462085c4ff4f" offset="0x00000" />
243         </dataarea>
244      </part>
245   </software>
246
247   <software name="imagfrnd" supported="no">
248      <description>Foster's Home for Imaginary Friends (US)</description>
249      <year>2003</year>
250      <publisher>LeapFrog</publisher>
251      <part name="cart" interface="leapster_cart">
252         <dataarea name="rom" size="0x800000">
253            <rom name="500-12715-a - foster's home for imaginary friends (us).bin" size="0x800000" crc="e62d1684" sha1="e43820efe9dbd8dddf6312493a7967c75a29431a" offset="0x00000" />
254         </dataarea>
255      </part>
256   </software>
257
258180</softwarelist>
trunk/src/emu/cpu/arc/arc.h
r242208r242209
5353   //     62 = Long Immediate Data Indicator
5454   //     63 = Short Immediate Data Indicator NOT Settings Flag
5555   UINT32 m_pc;
56   //UINT32 m_r[64];
56   UINT32 m_r[64];
5757
5858
5959   address_space *m_program;
trunk/src/emu/cpu/arcompact/arcompactdasm.c
r242208r242209
100100   /* 1f */ "0x1f Reserved"
101101};
102102
103static const char *table01_01_0x[0x10] =
104{
105   /* 00 */ "BREQ",
106   /* 01 */ "BRNE",
107   /* 02 */ "BRLT",
108   /* 03 */ "BRGE",
109   /* 04 */ "BRLO",
110   /* 05 */ "BRHS",
111   /* 06 */ "<reserved>",
112   /* 07 */ "<reserved>",
113   /* 08 */ "<reserved>",
114   /* 09 */ "<reserved>",
115   /* 0a */ "<reserved>",
116   /* 0b */ "<reserved>",
117   /* 0c */ "<reserved>",
118   /* 0d */ "<reserved>",
119   /* 0e */ "<BBIT0>",
120   /* 0f */ "<BBIT1>"
121};
122
123static const char *table18[0x8] =
124{
125   /* 00 */ "LD_S (SP)",
126   /* 01 */ "LDB_S (SP)",
127   /* 02 */ "ST_S (SP)",
128   /* 03 */ "STB_S (SP)",
129   /* 04 */ "ADD_S (SP)",
130   /* 05 */ "ADD_S/SUB_S (SP)",
131   /* 06 */ "POP_S (SP)",
132   /* 07 */ "PUSH_S (SP)",
133
134};
135
136static const char *table0f[0x20] =
137{
138   /* 00 */ "SOPs", // Sub Operation (another table..) ( table0f_00 )
139   /* 01 */ "0x01 <illegal>",
140   /* 02 */ "SUB_S",
141   /* 03 */ "0x03 <illegal>",
142   /* 04 */ "AND_S",
143   /* 05 */ "OR_S",
144   /* 06 */ "BIC_S",
145   /* 07 */ "XOR_S",
146   /* 08 */ "0x08 <illegal>",
147   /* 09 */ "0x09 <illegal>",
148   /* 0a */ "0x0a <illegal>",
149   /* 0b */ "TST_S",
150   /* 0c */ "MUL64_S",
151   /* 0d */ "SEXB_S",
152   /* 0e */ "SEXW_S",
153   /* 0f */ "EXTB_S",
154   /* 10 */ "EXTW_S",
155   /* 11 */ "ABS_S",
156   /* 12 */ "NOT_S",
157   /* 13 */ "NEG_S",
158   /* 14 */ "ADD1_S",
159   /* 15 */ "ADD2_S>",
160   /* 16 */ "ADD3_S",
161   /* 17 */ "0x17 <illegal>",
162   /* 18 */ "ASL_S (multiple)",
163   /* 19 */ "LSR_S (multiple)",
164   /* 1a */ "ASR_S (multiple)",
165   /* 1b */ "ASL_S (single)",
166   /* 1c */ "LSR_S (single)",
167   /* 1d */ "ASR_S (single)",
168   /* 1e */ "TRAP (not a5?)",
169   /* 1f */ "BRK_S" // 0x7fff only?
170};
171
172static const char *table0f_00[0x8] =
173{
174   /* 00 */ "J_S",
175   /* 01 */ "J_S.D",
176   /* 02 */ "JL_S",
177   /* 03 */ "JL_S.D",
178   /* 04 */ "0x04 <illegal>",
179   /* 05 */ "0x05 <illegal>",
180   /* 06 */ "SUB_S.NE",
181   /* 07 */ "ZOPs", // Sub Operations (yet another table..) ( table0f_00_07 )
182};
183
184static const char *table0f_00_07[0x8] =
185{
186   /* 00 */ "NOP_S",
187   /* 01 */ "UNIMP_S", // unimplemented (not a5?)
188   /* 02 */ "0x02 <illegal>",
189   /* 03 */ "0x03 <illegal>",
190   /* 04 */ "JEQ_S [BLINK]",
191   /* 05 */ "JNE_S [BLINK]",
192   /* 06 */ "J_S [BLINK]",
193   /* 07 */ "J_S.D [BLINK]",
194};
195
196103#define ARCOMPACT_OPERATION ((op & 0xf800) >> 11)
197104
198105CPU_DISASSEMBLE(arcompact)
199106{
200107   int size = 2;
201108
202   UINT32 op = oprom[2] | (oprom[3] << 8);
109   UINT32 op = oprom[0] | (oprom[1] << 8);
203110   output = buffer;
204111
205112   UINT8 instruction = ARCOMPACT_OPERATION;
r242208r242209
208115   {
209116      size = 4;
210117      op <<= 16;
211      op |= oprom[0] | (oprom[1] << 8);
118      op |= oprom[2] | (oprom[3] << 8);
212119
213120      switch (instruction)
214121      {
215122         case 0x00:
216123            if (op & 0x00010000)
217124            { // Branch Unconditionally Far
218              // 00000 ssssssssss 1  SSSSSSSSSS N R TTTT
219               INT32 address =   (op & 0x07fe0000) >> 17;
125              // 00000 ssssssssss 1  SSSSSSSSSS N 0 TTTT
126               UINT32 address =   (op & 0x07fe0000) >> 17;
220127               address |=        ((op & 0x0000ffc0) >> 6) << 10;
221128               address |=        ((op & 0x0000000f) >> 0) << 20;
222               if (address & 0x800000) address = -(address&0x7fffff);   
223129
224               print("B %08x (%08x)",  pc + (address *2) + 2, op & ~0xffffffcf );
130               print("B %08x (%08x)",  address<<1, op & ~0xffffffcf );
225131            }
226132            else
227133            { // Branch Conditionally
228134              // 00000 ssssssssss 0 SSSSSSSSSS N QQQQQ
229               INT32 address =   (op & 0x07fe0000) >> 17;
135               UINT32 address =   (op & 0x07fe0000) >> 17;
230136               address |=        ((op & 0x0000ffc0) >> 6) << 10;
231               if (address & 0x800000) address = -(address&0x7fffff);   
232137
233138               UINT8 condition = op & 0x0000001f;
234139
235               print("B(%s) %08x (%08x)", conditions[condition], pc + (address *2) + 2, op & ~0xffffffdf );
140               print("B(%s) %08x (%08x)", conditions[condition], address<<1, op & ~0xffffffdf );
236141
237142            }
238143
239144            break;
240145
241         case 0x01:
242            if (op & 0x00010000)
243            {
244               if (op & 0x00000010)
245               { // Branch on Compare / Bit Test - Register-Immediate
246                  // 00001 bbb sssssss 1 S BBB UUUUUU N 1 iiii
247                  UINT8 subinstr = op & 0x0000000f;
248                  INT32 address =    (op & 0x00fe0000) >> 17;
249                  address |=        ((op & 0x00008000) >> 15) << 7;
250                  if (address & 0x80) address = -(address&0x7f);   
251
252                 
253                  print("%s (reg-imm) %08x (%08x)", table01_01_0x[subinstr], pc + (address *2) + 4, op & ~0xf8fe800f);
254
255
256               }
257               else
258               {
259                  // Branch on Compare / Bit Test - Register-Register
260                  // 00001 bbb sssssss 1 S BBB CCCCCC N 0 iiii
261                  UINT8 subinstr = op & 0x0000000f;
262                  INT32 address =    (op & 0x00fe0000) >> 17;
263                  address |=        ((op & 0x00008000) >> 15) << 7;
264                  if (address & 0x80) address = -(address&0x7f);   
265
266                  print("%s (reg-reg) %08x (%08x)", table01_01_0x[subinstr], pc + (address *2) + 4, op & ~0xf8fe800f);
267
268               }
269
270            }
271            else
272            {
273               if (op & 0x00020000)
274               { // Branch and Link Unconditionally Far
275                 // 00001 sssssssss 10  SSSSSSSSSS N R TTTT
276                  INT32 address =   (op & 0x07fc0000) >> 17;
277                  address |=        ((op & 0x0000ffc0) >> 6) << 10;
278                  address |=        ((op & 0x0000000f) >> 0) << 20;
279                  if (address & 0x800000) address = -(address&0x7fffff);   
280
281                  print("BL %08x (%08x)",  pc + (address *2) + 2, op & ~0xffffffcf );
282               }
283               else
284               { // Branch and Link Conditionally
285                 // 00001 sssssssss 00 SSSSSSSSSS N QQQQQ
286                  INT32 address =   (op & 0x07fc0000) >> 17;
287                  address |=        ((op & 0x0000ffc0) >> 6) << 10;
288                  if (address & 0x800000) address = -(address&0x7fffff);   
289
290                  UINT8 condition = op & 0x0000001f;
291
292                  print("BL(%s) %08x (%08x)", conditions[condition], pc + (address *2) + 2, op & ~0xffffffdf );
293
294               }
295
296            }
297            break;
298
299146         default:
300147            print("%s (%08x)", basic[instruction], op & ~0xf8000000 );
301148            break;
r242208r242209
305152     
306153   }
307154   else
308   {   
155   {
309156      size = 2;
310
311      switch (instruction)
312      {
313         case 0x0f:
314         {
315            // General Register Instructions (16-bit)
316            // 01111 bbb ccc iiiii
317            UINT8 subinstr = (op & 0x01f) >> 0;
318            //print("%s (%04x)", table0f[subinstr], op & ~0xf81f);
319
320#if 1         
321            switch (subinstr)
322            {
323   
324               default:
325                  print("%s (%04x)", table0f[subinstr], op & ~0xf81f);
326                  break;
327
328               case 0x00:
329               {
330                  // General Operations w/ Register
331                  // 01111 bbb iii 00000
332                  UINT8 subinstr2 = (op & 0x00e0) >> 5;
333
334                  switch (subinstr2)
335                  {
336                     default:
337                        print("%s (%04x)", table0f_00[subinstr2], op & ~0xf8ff);
338                        break;
339
340                     case 0x7:
341                     {
342                        // General Operations w/o Register
343                        // 01111 iii 111 00000
344                        UINT8 subinstr3 = (op & 0x0700) >> 8;
345
346                        print("%s (%04x)", table0f_00_07[subinstr3], op & ~0xffff);
347
348                        break;
349                     }
350                  }
351               }
352            }
353#endif           
354         
355            break;
356
357         }
358
359
360         case 0x18:
361         {
362            // Stack Pointer Based Instructions (16-bit)
363            // 11000 bbb iii uuuuu
364            UINT8 subinstr = (op & 0x00e0) >> 5;
365            print("%s (%04x)", table18[subinstr], op & ~0xf8e0);
366            break;
367
368         }
369
370         default:
371            print("%s (%04x)", basic[instruction], op & ~0xf800);
372            break;
373      }
157      print("%s (%04x)", basic[instruction], op & ~0xf800 );
374158   }
375159
376160
trunk/src/emu/cpu/pps4/pps4.c
r242208r242209
2727 *
2828 *   Note: External clock should be divided by 18 (not implemented).
2929 *
30 *   Pinouts:
31 *              10660                               11660
32 *
33 *      +--------\  /--------+              +--------\  /--------+
34 *  1  [| DIB-3   ++  DIA-3  |]  42     1  [| DIO-4       DIO-3  |]  42
35 *  2 [-| DIA-2       DIB-4  |-] 41     2 [-| DIA-4       DIO-2  |-] 41
36 *  3  [| DIB-2       DIA-4  |]  40     3  [| DIA-3       DIO-1  |]  40
37 *  4 [-| DIA-1       NC     |-] 39     4 [-| DIA-2       Vdd    |-] 39
38 *  5  [| DIB-1       A/B-1  |]  38     5  [| DIA-1       A/B-1  |]  38
39 *  6 [-| Vdd         A/B-2  |-] 37     6 [-| I/O-5       A/B-2  |-] 37
40 *  7  [| I/D-5       A/B-3  |]  36     7  [| I/O-6       A/B-3  |]  36
41 *  8 [-| I/D-6       A/B-4  |-] 35     8 [-| I/O-7       A/B-4  |-] 35
42 *  9  [| I/D-7       A/B-5  |]  34     9  [| I/O-8       A/B-5  |]  34
43 * 10 [-| I/D-8       A/B-6  |-] 33    10 [-| I/O-1       A/B-6  |-] 33
44 * 11  [| I/D-1       A/B-7  |]  32    11  [| I/O-4       A/B-7  |]  32
45 * 12 [-| I/D-4       A/B-8  |-] 31    12 [-| I/O-2       A/B-8  |-] 31
46 * 13  [| I/D-2       A/B-9  |]  30    13  [| I/O-3       A/B-9  |]  30
47 * 14 [-| I/D-3       A/B-10 |-] 29    14 [-| W/IO        A/B-10 |-] 29
48 * 15  [| W/IO        A/B-11 |]  28    15  [| CLK ~B      A/B-11 |]  28
49 * 16 [-| CLK ~B      A/B-12 |-] 27    16 [-| CLK A       A/B-12 |-] 27
50 * 17  [| CLK A       NC     |]  26    17  [| VCLK        DO-4   |]  26
51 * 18 [-| PO          DO-3   |-] 25    18 [-| Xtal1       DO-3   |-] 25
52 * 19  [| SPO         DO-4   |]  24    19  [| Xtal2       DO-2   |]  24
53 * 20 [-| DO-2        NC     |-] 23    20 [-| Vss         DO-1   |-] 23
54 * 21  [| DO-1        Vss    |]  22    21  [| SPO         TC1-14 |]  22
55 *      +--------------------+              +--------------------+
56 *
5730 *****************************************************************************/
5831#include "emu.h"
5932#include "debugger.h"
6033#include "pps4.h"
6134
6235
63#define VERBOSE 0       //!< set to 1 to log certain instruction conditions
36#define VERBOSE 1       //!< set to 1 to log certain instruction conditions
6437
6538#if VERBOSE
6639#define LOG(x) logerror x
r242208r242209
246219 * @brief pps4_device::iADI Add immediate
247220 * OPCODE     cycles  mnemonic
248221 * -----------------------------
249 * 0110 xxxx  1 cyc   ADI x
222 * 0110 xxxx  1 cyc   ADI #x
250223 *
251224 * Symbolic equation
252225 * -----------------------------
r242208r242209
275248 * @brief pps4_device::iDC Decimal correction
276249 * OPCODE     cycles  mnemonic
277250 * -----------------------------
278 * 0110 0101  1 cyc   DC
251 * 0110 0110  1 cyc   DC
279252 *
280253 * Symbolic equation
281254 * -----------------------------
r242208r242209
364337 */
365338void pps4_device::iCOMP()
366339{
367    m_A = m_A ^ 15;
340    m_A = ~m_A & 15;
368341}
369342
370343/**
r242208r242209
422395 * @brief pps4_device::iRF1 Reset flip-flop FF1
423396 * OPCODE     cycles  mnemonic
424397 * -----------------------------
425 * 0010 0110  1 cyc   RF1
398 * 0010 0100  1 cyc   RF1
426399 *
427400 * Symbolic equation
428401 * -----------------------------
r242208r242209
490463 */
491464void pps4_device::iLD()
492465{
493    const UINT16 i3c = ~m_I & 7;
466    const UINT16 imm = ~m_I & 7;
494467    m_A = M();
495    m_B = m_B ^ (i3c << 4);
468    m_B = m_B ^ (imm << 4);
496469}
497470
498471/**
r242208r242209
513486 */
514487void pps4_device::iEX()
515488{
516    const UINT16 i3c = ~m_I & 7;
489    const UINT16 imm = ~m_I & 7;
517490    const UINT8 mem = M();
518491    W(m_A);
519492    m_A = mem;
520    m_B = m_B ^ (i3c << 4);
493    m_B = m_B ^ (imm << 4);
521494}
522495
523496/**
r242208r242209
542515 */
543516void pps4_device::iEXD()
544517{
545    const UINT8 i3c = ~m_I & 7;
518    const UINT8 imm = ~m_I & 7;
546519    const UINT8 mem = M();
547520    UINT8 bl = m_B & 15;
548521    W(m_A);
549522    m_A = mem;
550    m_B = m_B ^ (i3c << 4);
551    // if decrement BL wraps to 1111b
523    m_B = m_B ^ (imm << 4);
552524    if (0 == bl) {
525        // decrement BL wraps to 1111b
553526        bl = 15;
554527        m_Skip = 1;
555528    } else {
529        // decrement BL
556530        bl = bl - 1;
557531    }
558532    m_B = (m_B & ~15) | bl;
r242208r242209
609583 * @brief pps4_device::iLXA
610584 * OPCODE     cycles  mnemonic
611585 * -----------------------------
612 * 0001 1011  1 cyc   LXA
586 * 0001 1011  1 cyc   LAX
613587 *
614588 * Symbolic equation
615589 * -----------------------------
r242208r242209
663637 * @brief pps4_device::iLBUA
664638 * OPCODE     cycles  mnemonic
665639 * -----------------------------
666 * 0000 0100  1 cyc   LBUA
640 * 0001 0000  1 cyc   LBUA
667641 *
668642 * Symbolic equation
669643 * -----------------------------
r242208r242209
786760 */
787761void pps4_device::iCYS()
788762{
789    const UINT16 sa = (m_SA >> 4) | (m_A << 8);
763    const UINT16 sa = (m_SA >> 4) | (m_A << 12);
790764    m_A = m_SA & 15;
791765    m_SA = sa;
792766}
r242208r242209
867841 */
868842void pps4_device::iLBL()
869843{
870    const UINT8 i8 = ~ARG() & 255;
871844    // previous LB or LBL instruction?
872845    if (0xc0 == m_Ip || 0x00 == m_Ip) {
873846        LOG(("%s: skip prev:%02x op:%02x\n", __FUNCTION__, m_Ip, m_I));
874847        return;
875848    }
876    m_B = i8;
849    m_B = ~ARG() & 255;
877850}
878851
879852/**
r242208r242209
906879 * @brief pps4_device::iDECB
907880 * OPCODE     cycles  mnemonic
908881 * -----------------------------
909 * 0001 1111  1 cyc    DECB
882 * 0001 1111  1 cyc    DECq
910883 *
911884 * Symbolic equation
912885 * -----------------------------
r242208r242209
932905 * @brief pps4_device::iT Transfer
933906 * OPCODE     cycles  mnemonic
934907 * -----------------------------
935 * 10xx xxxx  1 cyc    T *xx
908 * 10xx xxxx  1 cyc    T *
936909 *
937910 * Symbolic equation
938911 * -----------------------------
r242208r242209
979952{
980953    m_SB = m_SA;
981954    m_SA = m_P;
982    m_P = (3 << 6) | (m_I & 63);
955    m_P = 3 << 6;
956    m_P = m_P | (m_I & 63);
983957    m_I2 = ARG();
984958    m_P = (1 << 8) | m_I2;
985959}
r242208r242209
1004978void pps4_device::iTL()
1005979{
1006980    m_I2 = ARG();
1007    m_P = ((m_I & 15) << 8) | m_I2;
981    m_P = (m_I & 15) << 8;
982    m_P = m_P | m_I2;
1008983}
1009984
1010985/**
r242208r242209
10651040 */
10661041void pps4_device::iSKZ()
10671042{
1068    m_Skip = (0 == m_A) ? 1 : 0;
1043    m_Skip = 0 == m_A ? 1 : 0;
10691044}
10701045
10711046/**
r242208r242209
10841059 */
10851060void pps4_device::iSKBI()
10861061{
1087    const UINT8 i4 = m_I & 15;
1062    const UINT8 imm = m_I & 15;
10881063    const UINT8 bl = m_B & 15;
1089    m_Skip = bl == i4 ? 1 : 0;
1064    m_Skip = bl == imm ? 1 : 0;
10901065}
10911066
10921067/**
r242208r242209
11231098 * @brief pps4_device::iRTN Return
11241099 * OPCODE     cycles  mnemonic
11251100 * -----------------------------
1126 * 0000 0101  1 cyc    RTN
1101 * 0000 0101  1 cyc    RET
11271102 *
11281103 * Symbolic equation
11291104 * -----------------------------
r242208r242209
11461121 * @brief pps4_device::iRTN Return
11471122 * OPCODE     cycles  mnemonic
11481123 * -----------------------------
1149 * 0000 0111  1 cyc    RTNSK
1124 * 0000 0111  1 cyc    RETSK
11501125 *
11511126 * Symbolic equation
11521127 * -----------------------------
r242208r242209
11631138    m_SA ^= m_SB;
11641139    m_SB ^= m_SA;
11651140    m_SA ^= m_SB;
1166    m_Skip = 1; // next opcode is ignored
1141    ROP();      // next opcode is ignored
1142    m_I = 0;    // avoid LB/LBL or LDI skipping due to m_Ip
11671143}
11681144
11691145/**
r242208r242209
11901166 */
11911167void pps4_device::iIOL()
11921168{
1193    const UINT8 ac = ~m_A & 15;
1169    const UINT8 a = ~m_A & 15;
11941170    m_I2 = ARG();
1195    m_io->write_byte(m_I2, ac);
1196    LOG(("%s: port:%02x <- %x\n", __FUNCTION__, m_I2, ac));
1171    m_io->write_byte(m_I2, a);
1172    LOG(("%s: port:%02x <- %x\n", __FUNCTION__, m_I2, a));
11971173    m_A = ~m_io->read_byte(m_I2) & 15;
11981174    LOG(("%s: port:%02x -> %x\n", __FUNCTION__, m_I2, m_A));
11991175}
r242208r242209
12131189 */
12141190void pps4_device::iDIA()
12151191{
1216    m_A = m_io->read_byte(PPS4_PORT_A) & 15;
1192    m_A = m_io->read_byte(PPS4_PORT_A);
12171193}
12181194
12191195/**
r242208r242209
12311207 */
12321208void pps4_device::iDIB()
12331209{
1234    m_A = m_io->read_byte(PPS4_PORT_B) & 15;
1210    m_A = m_io->read_byte(PPS4_PORT_B);
12351211}
12361212
12371213/**
1238 * @brief pps4_device::iDOA Discrete output
1214 * @brief pps4_device::iDIA Discrete input group A
12391215 * OPCODE     cycles  mnemonic
12401216 * -----------------------------
1241 * 0001 1101  1 cyc    DOA
1217 * 0010 1101  1 cyc    DOA
12421218 *
12431219 * Symbolic equation
12441220 * -----------------------------
trunk/src/emu/luaengine.c
r242208r242209
207207}
208208
209209//-------------------------------------------------
210//  emu_romname - returns rom base name
211//-------------------------------------------------
212
213int lua_engine::l_emu_romname(lua_State *L)
214{
215   lua_pushstring(L, luaThis->machine().basename());
216   return 1;
217}
218
219//-------------------------------------------------
220//  emu_pause/emu_unpause - pause/unpause game
221//-------------------------------------------------
222
223int lua_engine::l_emu_pause(lua_State *L)
224{
225   luaThis->machine().pause();
226   return 0;
227}
228
229int lua_engine::l_emu_unpause(lua_State *L)
230{
231   luaThis->machine().resume();
232   return 0;
233}
234
235//-------------------------------------------------
236210//  emu_keypost - post keys to natural keyboard
237211//-------------------------------------------------
238212
r242208r242209
522496   luabridge::getGlobalNamespace (m_lua_state)
523497      .beginNamespace ("emu")
524498         .addCFunction ("gamename",    l_emu_gamename )
525         .addCFunction ("romname",     l_emu_romname )
526499         .addCFunction ("keypost",     l_emu_keypost )
527500         .addCFunction ("hook_output", l_emu_hook_output )
528501         .addCFunction ("time",        l_emu_time )
r242208r242209
530503         .addCFunction ("after",       l_emu_after )
531504         .addCFunction ("exit",        l_emu_exit )
532505         .addCFunction ("start",       l_emu_start )
533         .addCFunction ("pause",       l_emu_pause )
534         .addCFunction ("unpause",     l_emu_unpause )
535506         .beginClass <machine_manager> ("manager")
536507            .addFunction ("machine", &machine_manager::machine)
537508            .addFunction ("options", &machine_manager::options)
trunk/src/emu/luaengine.h
r242208r242209
7979   static int l_emu_wait(lua_State *L);
8080   static int l_emu_time(lua_State *L);
8181   static int l_emu_gamename(lua_State *L);
82   static int l_emu_romname(lua_State *L);
8382   static int l_emu_keypost(lua_State *L);
8483   static int l_emu_hook_output(lua_State *L);
8584   static int l_emu_exit(lua_State *L);
8685   static int l_emu_start(lua_State *L);
87   static int l_emu_pause(lua_State *L);
88   static int l_emu_unpause(lua_State *L);
8986
9087   void resume(void *L, INT32 param);
9188   void report_errors(int status);
trunk/src/emu/video/poly.h
r242208r242209
226226   inline INT32 round_coordinate(_BaseType value)
227227   {
228228      INT32 result = poly_floor(value);
229
230      if ((value > 0) && (result < 0))
231         return INT_MAX-1;
229232      return result + (value - _BaseType(result) > _BaseType(0.5));
230233   }
231234
trunk/src/lib/formats/victor9k_dsk.c
r242208r242209
3939    Interleave factor 3
4040    cell 2.13 usec
4141
42
43   Boot Disc Label Format
44   Track 0 Sector 0
45
46   Byte
47   Offset         Name                Description
48
49   0              System disc ID      literally, ff,00h for a system
50                                      disc
51
52   2              Load address        paragraph   to   load   booted
53                                      program at. If zero then  boot
54                                      loads in high memory.
55
56   4              Length              paragraph count to load.
57
58   6              Entry offset        I.P.  value  for  transfer  of
59                                      control.
60
61   8              Entry segment       C.S.  value  for  transfer  of
62                                      control.
63
64   10             I.D.                disc identifier.
65
66   18             Part number         system identifier  - displayed
67                                      by early versions of boot.
68
69   26             Sector size         byte count for sectors.
70
71   28             Data start          first   data  sector  on  disc
72                                      (absolute sectors).
73
74   30             Boot start          first   absolute   sector   of
75                                      program  for boot to  load  at
76                                      'load  address'  for  'length'
77                                      paragraphs.
78
79   32             Flags               indicators:
80                                           bit  meaning
81                                          15-12 interleave    factor
82                                                (0-15)
83                                            0   0=single sided
84                                                1=double sided
85
86   34             Disc type           00 = CP/M
87                                      01 = MS-DOS
88
89   35             Reserved
90
91   38             Speed table         information  for speed control
92                                      proc.
93
94   56             Zone table          high track for each zone.
95
96   71             Sector/track        sectors  per  track  for  each
97                                      zone.
9842*/
9943
10044#include "emu.h"
r242208r242209
14084   return 0;
14185}
14286
143void victor9k_format::log_boot_sector(UINT8 *data)
144{
145   // System disc ID
146   logerror("System disc: %s\n", ((data[0] == 0xff) && (data[1] == 0x00)) ? "yes" : "no");
147
148   // Load address
149   logerror("Load address: %04x\n", (data[1] << 8) | data[2]);
150
151   // Length
152   logerror("Length: %04x\n", (data[3] << 8) | data[4]);
153
154   // Entry offset
155   logerror("Entry offset: %04x\n", (data[5] << 8) | data[6]);
156
157   // Entry segment
158   logerror("Entry segment: %04x\n", (data[7] << 8) | data[8]);
159
160   // I.D.
161   //logerror("I.D.: %s\n", data[10]);
162
163   // Part number
164   //logerror("Part number: %s\n", data[18]);
165
166   // Sector size
167   logerror("Sector size: %04x\n", (data[25] << 8) | data[26]);
168
169   // Data start
170   logerror("Data start: %04x\n", (data[27] << 8) | data[28]);
171
172   // Boot start
173   logerror("Boot start: %04x\n", (data[29] << 8) | data[30]);
174
175   // Flags
176   logerror("%s sided\n", BIT(data[33], 0) ? "Double" : "Single");
177   logerror("Interleave factor: %u\n", data[32] >> 4);
178
179   // Disc type
180   switch (data[34]) {
181   case 0x00: logerror("Disc type: CP/M\n"); break;
182   case 0x01: logerror("Disc type: MS-DOS\n"); break;
183   default: logerror("Disc type: unknown\n"); break;
184   }
185
186   // Speed table
187   logerror("Speed table:  ");
188   for (int i = 38; i < 56; i++) {
189      logerror("%02x ", data[i]);
190   }
191   logerror("\n");
192
193   // Zone table
194   logerror("Zone table:            ");
195   for (int i = 56; i < 71; i++) {
196      logerror("%02x ", data[i]);
197   }
198   logerror("\n");
199
200   // Sector/track
201   logerror("Sector/track:          ");
202   for (int i = 71; i < 86; i++) {
203      logerror("%02x ", data[i]);
204   }
205   logerror("\n");
206}
207
20887floppy_image_format_t::desc_e* victor9k_format::get_sector_desc(const format &f, int &current_size, int sector_count)
20988{
21089   static floppy_image_format_t::desc_e desc[] = {
r242208r242209
262141
263142   io_generic_read(io, img, 0, size);
264143
265   log_boot_sector(img);
266
267144   int track_offset = 0;
268145
269146   for (int head = 0; head < f.head_count; head++) {
r242208r242209
330207      18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18,
331208      17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
332209      16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
333      15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
334      14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
210      15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
211      14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
335212      13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
336213      12, 12, 12, 12, 12, 12, 12, 12, 12
337214   },
trunk/src/lib/formats/victor9k_dsk.h
r242208r242209
3333
3434   int find_size(io_generic *io, UINT32 form_factor);
3535   virtual int identify(io_generic *io, UINT32 form_factor);
36   void log_boot_sector(UINT8 *data);
3736   floppy_image_format_t::desc_e* get_sector_desc(const format &f, int &current_size, int sector_count);
3837   void build_sector_description(const format &f, UINT8 *sectdata, offs_t sect_offs, desc_s *sectors, int sector_count) const;
3938   virtual bool load(io_generic *io, UINT32 form_factor, floppy_image *image);
trunk/src/mame/drivers/chihiro.c
r242208r242209
370370#include "debug/debugcmd.h"
371371#include "debug/debugcpu.h"
372372#include "osdcore.h"
373#include "includes/chihiro.h"
373374
374375#define LOG_PCI
375376//#define LOG_OHCI
376//#define LOG_NV2A
377377//#define LOG_BASEBOARD
378378
379class nv2a_renderer; // forw. dec.
380struct nvidia_object_data
381{
382   nv2a_renderer *data;
383};
384
385379class chihiro_state : public driver_device
386380{
387381public:
r242208r242209
391385      debug_irq_active(false),
392386      m_maincpu(*this, "maincpu") { }
393387
394   DECLARE_READ32_MEMBER( geforce_r );
395   DECLARE_WRITE32_MEMBER( geforce_w );
396   DECLARE_READ32_MEMBER( usbctrl_r );
397   DECLARE_WRITE32_MEMBER( usbctrl_w );
398   DECLARE_READ32_MEMBER( smbus_r );
399   DECLARE_WRITE32_MEMBER( smbus_w );
400   DECLARE_READ32_MEMBER( mediaboard_r );
401   DECLARE_WRITE32_MEMBER( mediaboard_w );
402   DECLARE_READ32_MEMBER( audio_apu_r );
403   DECLARE_WRITE32_MEMBER( audio_apu_w );
404   DECLARE_READ32_MEMBER( audio_ac93_r );
405   DECLARE_WRITE32_MEMBER( audio_ac93_w );
406   DECLARE_READ32_MEMBER( dummy_r );
407   DECLARE_WRITE32_MEMBER( dummy_w );
388   DECLARE_READ32_MEMBER(geforce_r);
389   DECLARE_WRITE32_MEMBER(geforce_w);
390   DECLARE_READ32_MEMBER(usbctrl_r);
391   DECLARE_WRITE32_MEMBER(usbctrl_w);
392   DECLARE_READ32_MEMBER(smbus_r);
393   DECLARE_WRITE32_MEMBER(smbus_w);
394   DECLARE_READ32_MEMBER(mediaboard_r);
395   DECLARE_WRITE32_MEMBER(mediaboard_w);
396   DECLARE_READ32_MEMBER(audio_apu_r);
397   DECLARE_WRITE32_MEMBER(audio_apu_w);
398   DECLARE_READ32_MEMBER(audio_ac93_r);
399   DECLARE_WRITE32_MEMBER(audio_ac93_w);
400   DECLARE_READ32_MEMBER(dummy_r);
401   DECLARE_WRITE32_MEMBER(dummy_w);
408402
409   void smbus_register_device(int address,int (*handler)(chihiro_state &chs,int command,int rw,int data));
410   int smbus_pic16lc(int command,int rw,int data);
411   int smbus_cx25871(int command,int rw,int data);
412   int smbus_eeprom(int command,int rw,int data);
413   void baseboard_ide_event(int type,UINT8 *read,UINT8 *write);
403   void smbus_register_device(int address, int(*handler)(chihiro_state &chs, int command, int rw, int data));
404   int smbus_pic16lc(int command, int rw, int data);
405   int smbus_cx25871(int command, int rw, int data);
406   int smbus_eeprom(int command, int rw, int data);
407   void baseboard_ide_event(int type, UINT8 *read, UINT8 *write);
414408   UINT8 *baseboard_ide_dimmboard(UINT32 lba);
415   void dword_write_le(UINT8 *addr,UINT32 d);
416   void word_write_le(UINT8 *addr,UINT16 d);
417   void debug_generate_irq(int irq,bool active);
409   void dword_write_le(UINT8 *addr, UINT32 d);
410   void word_write_le(UINT8 *addr, UINT16 d);
411   void debug_generate_irq(int irq, bool active);
418412
419413   void vblank_callback(screen_device &screen, bool state);
420414   UINT32 screen_update_callback(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
r242208r242209
440434      int data;
441435      int command;
442436      int rw;
443      int (*devices[128])(chihiro_state &chs,int command,int rw,int data);
444      UINT32 words[256/4];
437      int(*devices[128])(chihiro_state &chs, int command, int rw, int data);
438      UINT32 words[256 / 4];
445439   } smbusst;
446440   struct apu_state {
447      UINT32 memory[0x60000/4];
441      UINT32 memory[0x60000 / 4];
448442      UINT32 gpdsp_sgaddress; // global processor scatter-gather
449443      UINT32 gpdsp_sgblocks;
450444      UINT32 gpdsp_address;
r242208r242209
465459      address_space *space;
466460   } apust;
467461   struct ac97_state {
468      UINT32 mixer_regs[0x80/4];
469      UINT32 controller_regs[0x38/4];
462      UINT32 mixer_regs[0x80 / 4];
463      UINT32 controller_regs[0x38 / 4];
470464   } ac97st;
471465   UINT8 pic16lc_buffer[0xff];
472466   nv2a_renderer *nvidia_nv2a;
r242208r242209
478472   required_device<cpu_device> m_maincpu;
479473};
480474
481/*
482 * geforce 3d (NV2A) vertex program disassembler
483 */
484class vertex_program_disassembler {
485   static const char *srctypes[];
486   static const char *scaops[];
487   static const int scapar2[];
488   static const char *vecops[];
489   static const int vecpar2[];
490   static const char *vecouts[];
491   static const char compchar[];
492   int o[6];
493   int state;
494
495   struct sourcefields
496   {
497      int Sign;
498      int SwizzleX;
499      int SwizzleY;
500      int SwizzleZ;
501      int SwizzleW;
502      int TempIndex;
503      int ParameterType;
504   };
505
506   struct fields
507   {
508      int ScaOperation;
509      int VecOperation;
510      int SourceConstantIndex;
511      int InputIndex;
512      sourcefields src[3];
513      int VecTempWriteMask;
514      int VecTempIndex;
515      int ScaTempWriteMask;
516      int OutputWriteMask;
517      int OutputSelect;
518      int OutputIndex;
519      int MultiplexerControl;
520      int Usea0x;
521      int EndOfProgram;
522   };
523   fields f;
524
525   void decodefields(unsigned int *dwords, int offset, fields &decoded);
526   int disassemble_mask(int mask, char *s);
527   int disassemble_swizzle(sourcefields f, char *s);
528   int disassemble_source(sourcefields f, fields fi, char *s);
529   int disassemble_output(fields f, char *s);
530   int output_types(fields f, int *o);
531public:
532   vertex_program_disassembler() { state = 0; }
533   int disassemble(unsigned int *instruction, char *line);
534};
535
536const char *vertex_program_disassembler::srctypes[] = { "??", "Rn", "Vn", "Cn" };
537const char *vertex_program_disassembler::scaops[] = { "NOP", "IMV", "RCP", "RCC", "RSQ", "EXP", "LOG", "LIT", "???", "???", "???", "???", "???", "???", "???", "???", "???" };
538const int vertex_program_disassembler::scapar2[] = { 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
539const char *vertex_program_disassembler::vecops[] = { "NOP", "MOV", "MUL", "ADD", "MAD", "DP3", "DPH", "DP4", "DST", "MIN", "MAX", "SLT", "SGE", "ARL", "???", "???", "???" };
540const int vertex_program_disassembler::vecpar2[] = { 0, 4, 6, 5, 7, 6, 6, 6, 6, 6, 6, 6, 6, 4, 0, 0, 0 };
541const char *vertex_program_disassembler::vecouts[] = { "oPos", "???", "???", "oD0", "oD1", "oFog", "oPts", "oB0", "oB1", "oT0", "oT1", "oT2", "oT3" };
542const char vertex_program_disassembler::compchar[] = { 'x', 'y', 'z', 'w' };
543
544/*
545Each vertex program instruction is a 128 bit word made of the fields:
546d         f
547w   b     i
548o   i     e
549r   t     l
550d   s     d
551+-+-----+-------
552|0|31-0 |not used
553+-+-----+-------
554| |31-29|not used
555| +-----+-------
556| |28-25|scalar operation
557| +-----+-------
558| |24-21|vectorial operation
559| +-----+-------
560| |20-13|index for source constant C[]
561| +-----+-------
562| |12-9 |input vector index
563| +-----+-------
564|1|  8  |parameter A:sign
565| +-----+-------
566| | 7-6 |parameter A:swizzle x
567| +-----+-------
568| | 5-4 |parameter A:swizzle y
569| +-----+-------
570| | 3-2 |parameter A:swizzle z
571| +-----+-------
572| | 1-0 |parameter A:swizzle w
573|-+-----+-------
574| |31-28|parameter A:parameter Rn index
575| +-----+-------
576| |27-26|parameter A:input type 1:Rn 2:Vn 3:C[n]
577| +-----+-------
578| | 25  |parameter B:sign
579| +-----+-------
580| |24-23|parameter B:swizzle x
581| +-----+-------
582| |22-21|parameter B:swizzle y
583| +-----+-------
584| |20-19|parameter B:swizzle z
585| +-----+-------
586|2|18-17|parameter B:swizzle w
587| +-----+-------
588| |16-13|parameter B:parameter Rn index
589| +-----+-------
590| |12-11|parameter B:input type 1:Rn 2:Vn 3:C[n]
591| +-----+-------
592| | 10  |parameter C:sign
593| +-----+-------
594| | 9-8 |parameter C:swizzle x
595| +-----+-------
596| | 7-6 |parameter C:swizzle y
597| +-----+-------
598| | 5-4 |parameter C:swizzle z
599| +-----+-------
600| | 3-2 |parameter C:swizzle w
601| +-----+-------
602| | 1-0 |
603|-+     |parameter C:parameter Rn index
604| |31-30|
605| +-----+-------
606| |29-28|parameter C:input type 1:Rn 2:Vn 3:C[n]
607| +-----+-------
608| |27-24|output Rn mask from vectorial operation
609| +-----+-------
610| |23-20|output Rn index from vectorial operation
611| +-----+-------
612| |19-16|output Rn mask from scalar operation
613| +-----+-------
614|3|15-12|output vector write mask
615| +-----+-------
616| | 11  |1:output is output vector 0:output is constant C[]
617| +-----+-------
618| |10-3 |output vector/constant index
619| +-----+-------
620| |  2  |0:output Rn from vectorial operation 1:output Rn from scalar operation
621| +-----+-------
622| |  1  |1:add a0x to index for source constant C[]
623| +-----+-------
624| |  0  |1:end of program
625+-+-----+-------
626Each vertex program instruction can generate up to three destination values using up to three source values.
627The first possible destination is to Rn from a vectorial operation.
628The second possible destination is to a vertex shader output or C[n] from a vectorial or scalar operation.
629The third possible destination is to Rn from a scalar operation.
630*/
631void vertex_program_disassembler::decodefields(unsigned int *dwords, int offset, fields &decoded)
632{
633   unsigned int srcbits[3];
634   int a;
635
636   srcbits[0] = ((dwords[1 + offset] & 0x1ff) << 6) | (dwords[2 + offset] >> 26);
637   srcbits[1] = (dwords[2 + offset] >> 11) & 0x7fff;
638   srcbits[2] = ((dwords[2 + offset] & 0x7ff) << 4) | (dwords[3 + offset] >> 28);
639   decoded.ScaOperation = (int)(dwords[1 + offset] >> 25) & 0xf;
640   decoded.VecOperation = (int)(dwords[1 + offset] >> 21) & 0xf;
641   decoded.SourceConstantIndex = (int)(dwords[1 + offset] >> 13) & 0xff;
642   decoded.InputIndex = (int)(dwords[1 + offset] >> 9) & 0xf;
643   for (a = 0; a < 3; a++)
644   {
645      decoded.src[a].Sign = (int)(srcbits[a] >> 14) & 1;
646      decoded.src[a].SwizzleX = (int)(srcbits[a] >> 12) & 3;
647      decoded.src[a].SwizzleY = (int)(srcbits[a] >> 10) & 3;
648      decoded.src[a].SwizzleZ = (int)(srcbits[a] >> 8) & 3;
649      decoded.src[a].SwizzleW = (int)(srcbits[a] >> 6) & 3;
650      decoded.src[a].TempIndex = (int)(srcbits[a] >> 2) & 0xf;
651      decoded.src[a].ParameterType = (int)(srcbits[a] >> 0) & 3;
652   }
653
654   decoded.VecTempWriteMask = (int)(dwords[3 + offset] >> 24) & 0xf;
655   decoded.VecTempIndex = (int)(dwords[3 + offset] >> 20) & 0xf;
656   decoded.ScaTempWriteMask = (int)(dwords[3 + offset] >> 16) & 0xf;
657   decoded.OutputWriteMask = (int)(dwords[3 + offset] >> 12) & 0xf;
658   decoded.OutputSelect = (int)(dwords[3 + offset] >> 11) & 0x1;
659   decoded.OutputIndex = (int)(dwords[3 + offset] >> 3) & 0xff;
660   decoded.MultiplexerControl = (int)(dwords[3 + offset] >> 2) & 0x1;
661   decoded.Usea0x = (int)(dwords[3 + offset] >> 1) & 0x1;
662   decoded.EndOfProgram = (int)(dwords[3 + offset] >> 0) & 0x1;
663}
664
665int vertex_program_disassembler::disassemble_mask(int mask, char *s)
666{
667   int l;
668
669   *s = 0;
670   if (mask == 15)
671      return 0;
672   s[0] = '.';
673   l = 1;
674   if ((mask & 8) != 0) {
675      s[l] = 'x';
676      l++;
677   }
678   if ((mask & 4) != 0){
679      s[l] = 'y';
680      l++;
681   }
682   if ((mask & 2) != 0){
683      s[l] = 'z';
684      l++;
685   }
686   if ((mask & 1) != 0){
687      s[l] = 'w';
688      l++;
689   }
690   s[l] = 0;
691   return l;
692}
693
694int vertex_program_disassembler::disassemble_swizzle(sourcefields f, char *s)
695{
696   int t, l;
697
698   t = 4;
699   if (f.SwizzleW == 3)
700   {
701      t = t - 1;
702      if (f.SwizzleZ == 2)
703      {
704         t = t - 1;
705         if (f.SwizzleY == 1)
706         {
707            t = t - 1;
708            if (f.SwizzleX == 0)
709            {
710               t = t - 1;
711            }
712         }
713      }
714   }
715   *s = 0;
716   if (t == 0)
717      return 0;
718   s[0] = '.';
719   l = 1;
720   if (t > 0)
721   {
722      s[l] = compchar[f.SwizzleX];
723      l++;
724   }
725   if (t > 1)
726   {
727      s[l] = compchar[f.SwizzleY];
728      l++;
729   }
730   if (t > 2)
731   {
732      s[l] = compchar[f.SwizzleZ];
733      l++;
734   }
735   if (t > 3)
736   {
737      s[l] = compchar[f.SwizzleW];
738      l++;
739   }
740   s[l] = 0;
741   return l;
742}
743
744int vertex_program_disassembler::disassemble_source(sourcefields f, fields fi, char *s)
745{
746   int l;
747
748   if (f.ParameterType == 0) {
749      strcpy(s, ",???");
750      return 4;
751   }
752   l = 0;
753   if (f.Sign != 0) {
754      s[l] = '-';
755      l++;
756   }
757   if (f.ParameterType == 1) {
758      s[l] = 'r';
759      l = l + 1 + sprintf(s + l + 1, "%d", f.TempIndex);
760   }
761   else if (f.ParameterType == 2){
762      s[l] = 'v';
763      l = l + 1 + sprintf(s + l + 1, "%d", fi.InputIndex);
764   }
765   else
766   {
767      if (fi.Usea0x != 0)
768      {
769         if (fi.SourceConstantIndex >= 96) {
770            strcpy(s + l, "c[");
771            l = l + 2;
772            l = l + sprintf(s + l, "%d", fi.SourceConstantIndex - 96);
773            strcpy(s + l, "+a0.x]");
774            l = l + 6;
775         }
776         else {
777            strcpy(s + l, "c[a0.x");
778            l = l + 6;
779            l = l + sprintf(s + l, "%d", fi.SourceConstantIndex - 96);
780            s[l] = ']';
781            l++;
782         }
783      }
784      else {
785         strcpy(s + l, "c[");
786         l = l + 2;
787         l = l + sprintf(s + l, "%d", fi.SourceConstantIndex - 96);
788         s[l] = ']';
789         l++;
790      }
791   }
792   l = l + disassemble_swizzle(f, s + l);
793   s[l] = 0;
794   return l;
795}
796
797int vertex_program_disassembler::disassemble_output(fields f, char *s)
798{
799   int l;
800
801   if (f.OutputSelect == 1) {
802      strcpy(s, vecouts[f.OutputIndex]);
803      return strlen(s);
804   }
805   else {
806      strcpy(s, "c[");
807      l = 2;
808      l = l + sprintf(s + l, "%d", f.OutputIndex - 96);
809      s[l] = ']';
810      l++;
811   }
812   s[l] = 0;
813   return l;
814}
815
816int vertex_program_disassembler::output_types(fields f, int *o)
817{
818   o[0] = o[1] = o[2] = o[3] = o[4] = o[5] = 0;
819   if ((f.VecOperation > 0) && (f.VecTempWriteMask != 0))
820      o[0] = 1;
821   if ((f.VecOperation > 0) && (f.OutputWriteMask != 0) && (f.MultiplexerControl == 0))
822      o[1] = 1;
823   if ((f.ScaOperation > 0) && (f.OutputWriteMask != 0) && (f.MultiplexerControl == 1))
824      o[2] = 1;
825   if ((f.ScaOperation > 0) && (f.ScaTempWriteMask != 0))
826      o[3] = 1;
827   if (f.VecOperation == 13)
828      o[4] = 1;
829   if (f.EndOfProgram == 1)
830      o[5] = 1;
831   return o[0] + o[1] + o[2] + o[3] + o[4] + o[5];
832}
833
834int vertex_program_disassembler::disassemble(unsigned int *instruction, char *line)
835{
836   int b, p;
837   char *c;
838
839   if (state == 0) {
840      decodefields(instruction, 0, f);
841      output_types(f, o);
842      state = 1;
843   }
844   if (o[0] != 0)
845   {
846      o[0] = 0;
847      c = line;
848      strcpy(c, vecops[f.VecOperation]);
849      c = c + strlen(c);
850      strcpy(c, " r");
851      c = c + 2;
852      c = c + sprintf(c, "%d", f.VecTempIndex);
853      c = c + disassemble_mask(f.VecTempWriteMask, c);
854      b = 0;
855      for (p = 4; p != 0; p = p >> 1)
856      {
857         if ((vecpar2[f.VecOperation] & p) != 0) {
858            c[0] = ',';
859            c++;
860            c = c + disassemble_source(f.src[b], f, c);
861         }
862         b++;
863      }
864      *c = 0;
865      return 1;
866   }
867   if (o[1] != 0)
868   {
869      o[1] = 0;
870      c = line;
871      strcpy(c, vecops[f.VecOperation]);
872      c = c + strlen(c);
873      *c = ' ';
874      c++;
875      c = c + disassemble_output(f, c);
876      c = c + disassemble_mask(f.OutputWriteMask, c);
877      b = 0;
878      for (p = 4; p != 0; p = p >> 1)
879      {
880         if ((vecpar2[f.VecOperation] & p) != 0) {
881            *c = ',';
882            c++;
883            c = c + disassemble_source(f.src[b], f, c);
884         }
885         b++;
886      }
887      *c = 0;
888      return 1;
889   }
890   if (o[2] != 0)
891   {
892      o[2] = 0;
893      c = line;
894      strcpy(c, scaops[f.ScaOperation]);
895      c = c + strlen(c);
896      *c = ' ';
897      c++;
898      c = c + disassemble_output(f, c);
899      c = c + disassemble_mask(f.OutputWriteMask, c);
900      b = 0;
901      for (p = 4; p != 0; p = p >> 1)
902      {
903         if ((scapar2[f.ScaOperation] & p) != 0) {
904            *c = ',';
905            c++;
906            c = c + disassemble_source(f.src[b], f, c);
907         }
908         b++;
909      }
910      *c = 0;
911      return 1;
912   }
913   if (o[3] != 0)
914   {
915      if (f.VecOperation > 0)
916         b = 1;
917      else
918         b = f.VecTempIndex;
919      o[3] = 0;
920      c = line;
921      strcpy(c, scaops[f.ScaOperation]);
922      c = c + strlen(c);
923      strcpy(c, " r");
924      c = c + 2;
925      c = c + sprintf(c, "%d", b);
926      c = c + disassemble_mask(f.ScaTempWriteMask, c);
927      b = 0;
928      for (p = 4; p != 0; p = p >> 1)
929      {
930         if ((scapar2[f.ScaOperation] & p) != 0) {
931            *c = ',';
932            c++;
933            c = c + disassemble_source(f.src[b], f, c);
934         }
935         b++;
936      }
937      *c = 0;
938      return 1;
939   }
940   if (o[4] != 0)
941   {
942      o[4] = 0;
943      c = line;
944      c = c + sprintf(c, "MOV a0.x,");
945      c = c + disassemble_source(f.src[0], f, c);
946      *c = 0;
947      return 1;
948   }
949   if (o[5] != 0)
950   {
951      o[5] = 0;
952      strcpy(line, "END");
953      return 1;
954   }
955   state = 0;
956   return 0;
957}
958
959/*
960 * geforce 3d (NV2A) accellerator
961 */
962/* very simplified view
963there is a set of context objects
964
965context objects are stored in RAMIN
966each context object is identified by an handle stored in RAMHT
967
968each context object can be assigned to a channel
969to assign you give to the channel an handle for the object
970
971offset in ramht=(((((handle >> 11) xor handle) >> 11) xor handle) & 0x7ff)*8
972offset in ramht contains the handle itself
973offset in ramht+4 contains in the lower 16 bits the offset in RAMIN divided by 16
974
975objects have methods used to do drawing
976most methods set parameters, others actually draw
977*/
978class nv2a_renderer : public poly_manager<float, nvidia_object_data, 12, 8192>
979{
980public:
981   nv2a_renderer(running_machine &machine) : poly_manager<float, nvidia_object_data, 12, 8192>(machine)
982   {
983      memset(channel,0,sizeof(channel));
984      memset(pfifo,0,sizeof(pfifo));
985      memset(pcrtc,0,sizeof(pcrtc));
986      memset(pmc,0,sizeof(pmc));
987      memset(ramin,0,sizeof(ramin));
988      computedilated();
989      fb.allocate(640,480);
990      objectdata=&(object_data_alloc());
991      objectdata->data=this;
992      combiner.used=0;
993      combiner.lock=osd_lock_alloc();
994      enabled_vertex_attributes=0;
995      indexesleft_count = 0;
996      vertex_pipeline = 4;
997      alpha_test_enabled = false;
998      alpha_reference = 0;
999      alpha_func = nv2a_renderer::ALWAYS;
1000      blending_enabled = false;
1001      blend_equation = nv2a_renderer::FUNC_ADD;
1002      blend_color = 0;
1003      blend_function_destination = nv2a_renderer::ZERO;
1004      blend_function_source = nv2a_renderer::ONE;
1005      logical_operation_enabled = false;
1006      logical_operation = nv2a_renderer::COPY;
1007      debug_grab_texttype = -1;
1008      debug_grab_textfile = NULL;
1009      memset(vertex_attribute_words, 0, sizeof(vertex_attribute_words));
1010      memset(vertex_attribute_offset, 0, sizeof(vertex_attribute_offset));
1011   }
1012   DECLARE_READ32_MEMBER( geforce_r );
1013   DECLARE_WRITE32_MEMBER( geforce_w );
1014   void vblank_callback(screen_device &screen, bool state);
1015   UINT32 screen_update_callback(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
1016
1017   void render_texture_simple(INT32 scanline, const extent_t &extent, const nvidia_object_data &extradata, int threadid);
1018   void render_color(INT32 scanline, const extent_t &extent, const nvidia_object_data &extradata, int threadid);
1019   void render_register_combiners(INT32 scanline, const extent_t &extent, const nvidia_object_data &objectdata, int threadid);
1020
1021   int geforce_commandkind(UINT32 word);
1022   UINT32 geforce_object_offset(UINT32 handle);
1023   void geforce_read_dma_object(UINT32 handle,UINT32 &offset,UINT32 &size);
1024   void geforce_exec_method(address_space &space,UINT32 channel,UINT32 subchannel,UINT32 method,UINT32 address,int &countlen);
1025   UINT32 texture_get_texel(int number,int x,int y);
1026   void write_pixel(int x, int y, UINT32 color);
1027   void combiner_initialize_registers(UINT32 argb8[6]);
1028   void combiner_initialize_stage(int stage_number);
1029   void combiner_initialize_final();
1030   void combiner_map_input(int stage_number); // map combiner registers to variables A..D
1031   void combiner_map_output(int stage_number); // map combiner calculation results to combiner registers
1032   void combiner_map_final_input(); // map final combiner registers to variables A..F
1033   void combiner_final_output(); // generate final combiner output
1034   float combiner_map_input_select(int code,int index); // get component index in register code
1035   float *combiner_map_input_select3(int code); // get pointer to register code
1036   float *combiner_map_output_select3(int code); // get pointer to register code for output
1037   float combiner_map_input_function(int code,float value); // apply input mapping function code to value
1038   void combiner_map_input_function3(int code,float *data); // apply input mapping function code to data
1039   void combiner_function_AB(float result[4]);
1040   void combiner_function_AdotB(float result[4]);
1041   void combiner_function_CD(float result[4]);
1042   void combiner_function_CdotD(float result[4]);
1043   void combiner_function_ABmuxCD(float result[4]);
1044   void combiner_function_ABsumCD(float result[4]);
1045   void combiner_compute_rgb_outputs(int index);
1046   void combiner_compute_a_outputs(int index);
1047   void combiner_argb8_float(UINT32 color,float reg[4]);
1048   UINT32 combiner_float_argb8(float reg[4]);
1049   UINT32 dilate0(UINT32 value,int bits);
1050   UINT32 dilate1(UINT32 value,int bits);
1051   void computedilated(void);
1052   void putpixtex(int xp,int yp,int up,int vp);
1053   int toggle_register_combiners_usage();
1054   void debug_grab_texture(int type, const char *filename);
1055   void debug_grab_vertex_program_slot(int slot, UINT32 *instruction);
1056   void savestate_items();
1057
1058   struct vertex {
1059      union {
1060         float fv[4];
1061         UINT32 iv[4];
1062      } attribute[16];
1063   };
1064   int read_vertices_0x1810(address_space & space, vertex *destination, int offset, int limit);
1065   int read_vertices_0x1800(address_space & space, vertex *destination, UINT32 address, int limit);
1066   int read_vertices_0x1818(address_space & space, vertex *destination, UINT32 address, int limit);
1067   void convert_vertices_poly(vertex *source, vertex_t *destination, int count);
1068
1069   struct {
1070      UINT32 regs[0x80/4];
1071      struct {
1072         UINT32 objhandle;
1073         UINT32 objclass;
1074         UINT32 method[0x2000/4];
1075      } object;
1076   } channel[32][8];
1077   UINT32 pfifo[0x2000/4];
1078   UINT32 pcrtc[0x1000/4];
1079   UINT32 pmc[0x1000/4];
1080   UINT32 ramin[0x100000/4];
1081   UINT32 dma_offset[2];
1082   UINT32 dma_size[2];
1083   UINT32 vertexbuffer_address[16];
1084   int vertexbuffer_stride[16];
1085   struct {
1086      int enabled;
1087      int sizeu;
1088      int sizev;
1089      int sizew;
1090      int dilate;
1091      int format;
1092      int rectangle_pitch;
1093      void *buffer;
1094   } texture[4];
1095   int primitives_count;
1096   int indexesleft_count;
1097   int indexesleft_first;
1098   UINT32 indexesleft[8];
1099   struct {
1100      float variable_A[4]; // 0=R 1=G 2=B 3=A
1101      float variable_B[4];
1102      float variable_C[4];
1103      float variable_D[4];
1104      float variable_E[4];
1105      float variable_F[4];
1106      float variable_G;
1107      float variable_EF[4];
1108      float variable_sumclamp[4];
1109      float function_RGBop1[4]; // 0=R 1=G 2=B
1110      float function_RGBop2[4];
1111      float function_RGBop3[4];
1112      float function_Aop1;
1113      float function_Aop2;
1114      float function_Aop3;
1115      float register_primarycolor[4]; // rw
1116      float register_secondarycolor[4];
1117      float register_texture0color[4];
1118      float register_texture1color[4];
1119      float register_texture2color[4];
1120      float register_texture3color[4];
1121      float register_color0[4];
1122      float register_color1[4];
1123      float register_spare0[4];
1124      float register_spare1[4];
1125      float register_fogcolor[4]; // ro
1126      float register_zero[4];
1127      float output[4];
1128      struct {
1129         float register_constantcolor0[4];
1130         float register_constantcolor1[4];
1131         int mapin_aA_input;
1132         int mapin_aA_component;
1133         int mapin_aA_mapping;
1134         int mapin_aB_input;
1135         int mapin_aB_component;
1136         int mapin_aB_mapping;
1137         int mapin_aC_input;
1138         int mapin_aC_component;
1139         int mapin_aC_mapping;
1140         int mapin_aD_input;
1141         int mapin_aD_component;
1142         int mapin_aD_mapping;
1143         int mapin_rgbA_input;
1144         int mapin_rgbA_component;
1145         int mapin_rgbA_mapping;
1146         int mapin_rgbB_input;
1147         int mapin_rgbB_component;
1148         int mapin_rgbB_mapping;
1149         int mapin_rgbC_input;
1150         int mapin_rgbC_component;
1151         int mapin_rgbC_mapping;
1152         int mapin_rgbD_input;
1153         int mapin_rgbD_component;
1154         int mapin_rgbD_mapping;
1155         int mapout_aCD_output;
1156         int mapout_aAB_output;
1157         int mapout_aSUM_output;
1158         int mapout_aCD_dotproduct;
1159         int mapout_aAB_dotproduct;
1160         int mapout_a_muxsum;
1161         int mapout_a_bias;
1162         int mapout_a_scale;
1163         int mapout_rgbCD_output;
1164         int mapout_rgbAB_output;
1165         int mapout_rgbSUM_output;
1166         int mapout_rgbCD_dotproduct;
1167         int mapout_rgbAB_dotproduct;
1168         int mapout_rgb_muxsum;
1169         int mapout_rgb_bias;
1170         int mapout_rgb_scale;
1171      } stage[8];
1172      struct {
1173         float register_constantcolor0[4];
1174         float register_constantcolor1[4];
1175         int color_sum_clamp;
1176         int mapin_rgbA_input;
1177         int mapin_rgbA_component;
1178         int mapin_rgbA_mapping;
1179         int mapin_rgbB_input;
1180         int mapin_rgbB_component;
1181         int mapin_rgbB_mapping;
1182         int mapin_rgbC_input;
1183         int mapin_rgbC_component;
1184         int mapin_rgbC_mapping;
1185         int mapin_rgbD_input;
1186         int mapin_rgbD_component;
1187         int mapin_rgbD_mapping;
1188         int mapin_rgbE_input;
1189         int mapin_rgbE_component;
1190         int mapin_rgbE_mapping;
1191         int mapin_rgbF_input;
1192         int mapin_rgbF_component;
1193         int mapin_rgbF_mapping;
1194         int mapin_aG_input;
1195         int mapin_aG_component;
1196         int mapin_aG_mapping;
1197      } final;
1198      int stages;
1199      int used;
1200      osd_lock *lock;
1201   } combiner;
1202   bool alpha_test_enabled;
1203   int alpha_func;
1204   int alpha_reference;
1205   bool blending_enabled;
1206   int blend_equation;
1207   int blend_function_source;
1208   int blend_function_destination;
1209   UINT32 blend_color;
1210   bool logical_operation_enabled;
1211   int logical_operation;
1212   struct {
1213      float modelview[16];
1214      float modelview_inverse[16];
1215      float projection[16];
1216      float translate[4];
1217      float scale[4];
1218   } matrix;
1219   struct {
1220      UINT32 instruction[1024];
1221      int instructions;
1222      int upload_instruction;
1223      int start_instruction;
1224      float parameter[1024];
1225      int upload_parameter;
1226   } vertexprogram;
1227   int vertex_pipeline;
1228   int enabled_vertex_attributes;
1229   int vertex_attribute_words[16];
1230   int vertex_attribute_offset[16];
1231   bitmap_rgb32 fb;
1232   UINT32 dilated0[16][2048];
1233   UINT32 dilated1[16][2048];
1234   int dilatechose[256];
1235   nvidia_object_data *objectdata;
1236   int debug_grab_texttype;
1237   char *debug_grab_textfile;
1238
1239   enum NV2A_BEGIN_END {
1240      STOP=0,
1241      POINTS=1,
1242      LINES=2,
1243      LINE_LOOP=3,
1244      LINE_STRIP=4,
1245      TRIANGLES=5,
1246      TRIANGLE_STRIP=6,
1247      TRIANGLE_FAN=7,
1248      QUADS=8,
1249      QUAD_STRIP=9,
1250      POLYGON=10
1251   };
1252   enum NV2A_VERTEX_ATTR {
1253      POS=0,
1254      WEIGHT=1,
1255      NORMAL=2,
1256      COLOR0=3,
1257      COLOR1=4,
1258      FOG=5,
1259      TEX0=9,
1260      TEX1=10,
1261      TEX2=11,
1262      TEX3=12
1263   };
1264   enum NV2A_VTXBUF_TYPE {
1265      FLOAT=2,
1266      UBYTE=4,
1267      USHORT=5
1268   };
1269   enum NV2A_TEX_FORMAT {
1270      L8=0x0,
1271      I8=0x1,
1272      A1R5G5B5=0x2,
1273      A4R4G4B4=0x4,
1274      R5G6B5=0x5,
1275      A8R8G8B8=0x6,
1276      X8R8G8B8=0x7,
1277      INDEX8=0xb,
1278      DXT1=0xc,
1279      DXT3=0xe,
1280      DXT5=0xf,
1281      A1R5G5B5_RECT=0x10,
1282      R5G6B5_RECT=0x11,
1283      A8R8G8B8_RECT=0x12,
1284      L8_RECT=0x13,
1285      DSDT8_RECT=0x17,
1286      A8L8=0x1a,
1287      I8_RECT=0x1b,
1288      A4R4G4B4_RECT=0x1d,
1289      R8G8B8_RECT=0x1e,
1290      A8L8_RECT=0x20,
1291      Z24=0x2a,
1292      Z24_RECT=0x2b,
1293      Z16=0x2c,
1294      Z16_RECT=0x2d,
1295      DSDT8=0x28,
1296      HILO16=0x33,
1297      HILO16_RECT=0x36,
1298      HILO8=0x44,
1299      SIGNED_HILO8=0x45,
1300      HILO8_RECT=0x46,
1301      SIGNED_HILO8_RECT=0x47
1302   };
1303   enum NV2A_LOGIC_OP {
1304      CLEAR=0x1500,
1305      AND=0x1501,
1306      AND_REVERSE=0x1502,
1307      COPY=0x1503,
1308      AND_INVERTED=0x1504,
1309      NOOP=0x1505,
1310      XOR=0x1506,
1311      OR=0x1507,
1312      NOR=0x1508,
1313      EQUIV=0x1509,
1314      INVERT=0x150a,
1315      OR_REVERSE=0x150b,
1316      COPY_INVERTED=0x150c,
1317      OR_INVERTED=0x150d,
1318      NAND=0x150e,
1319      SET=0x150f
1320   };
1321   enum NV2A_BLEND_EQUATION {
1322      FUNC_ADD=0x8006,
1323      MIN=0x8007,
1324      MAX=0x8008,
1325      FUNC_SUBTRACT=0x800a,
1326      FUNC_REVERSE_SUBTRACT=0x80b
1327   };
1328   enum NV2A_BLEND_FACTOR {
1329      ZERO=0x0000,
1330      ONE=0x0001,
1331      SRC_COLOR=0x0300,
1332      ONE_MINUS_SRC_COLOR=0x0301,
1333      SRC_ALPHA=0x0302,
1334      ONE_MINUS_SRC_ALPHA=0x0303,
1335      DST_ALPHA=0x0304,
1336      ONE_MINUS_DST_ALPHA=0x0305,
1337      DST_COLOR=0x0306,
1338      ONE_MINUS_DST_COLOR=0x0307,
1339      SRC_ALPHA_SATURATE=0x0308,
1340      CONSTANT_COLOR=0x8001,
1341      ONE_MINUS_CONSTANT_COLOR=0x8002,
1342      CONSTANT_ALPHA=0x8003,
1343      ONE_MINUS_CONSTANT_ALPHA=0x8004
1344   };
1345   enum NV2A_COMPARISON_OP {
1346      NEVER=0x0200,
1347      LESS=0x0201,
1348      EQUAL=0x0202,
1349      LEQUAL=0x0203,
1350      GREATER=0x0204,
1351      NOTEQUAL=0x0205,
1352      GEQUAL=0x0206,
1353      ALWAYS=0x0207
1354   };
1355   enum NV2A_STENCIL_OP {
1356      ZEROOP=0x0000,
1357      INVERTOP=0x150a,
1358      KEEP=0x1e00,
1359      REPLACE=0x1e01,
1360      INCR=0x1e02,
1361      DECR=0x1e03,
1362      INCR_WRAP=0x8507,
1363      DECR_WRAP=0x8508
1364   };
1365};
1366
1367475/* jamtable instructions for Chihiro (different from console)
1368476St.     Instr.       Comment
13694770x01    POKEPCI      PCICONF[OP2] := OP1
r242208r242209
1380488*/
1381489
1382490/* jamtable disassembler */
1383static void jamtable_disasm(running_machine &machine, address_space &space,UINT32 address,UINT32 size) // 0xff000080 == fff00080
491static void jamtable_disasm(running_machine &machine, address_space &space, UINT32 address, UINT32 size) // 0xff000080 == fff00080
1384492{
1385   offs_t base,addr;
1386   UINT32 opcode,op1,op2;
493   offs_t base, addr;
494   UINT32 opcode, op1, op2;
1387495   char sop1[16];
1388496   char sop2[16];
1389497   char pcrel[16];
1390498
1391   addr=(offs_t)address;
1392   if (!debug_cpu_translate(space,TRANSLATE_READ_DEBUG,&addr))
499   addr = (offs_t)address;
500   if (!debug_cpu_translate(space, TRANSLATE_READ_DEBUG, &addr))
1393501   {
1394      debug_console_printf(machine,"Address is unmapped.\n");
502      debug_console_printf(machine, "Address is unmapped.\n");
1395503      return;
1396504   }
1397505   while (1)
1398506   {
1399      base=addr;
1400      opcode=space.read_byte(addr);
507      base = addr;
508      opcode = space.read_byte(addr);
1401509      addr++;
1402      op1=space.read_dword_unaligned(addr);
1403      addr+=4;
1404      op2=space.read_dword_unaligned(addr);
1405      addr+=4;
510      op1 = space.read_dword_unaligned(addr);
511      addr += 4;
512      op2 = space.read_dword_unaligned(addr);
513      addr += 4;
1406514      if (opcode == 0xe1)
1407515      {
1408         opcode=op2 & 255;
1409         op2=op1;
516         opcode = op2 & 255;
517         op2 = op1;
1410518         //op1=edi;
1411         sprintf(sop2,"%08X",op2);
1412         sprintf(sop1,"ACC");
1413         sprintf(pcrel,"PC+ACC");
519         sprintf(sop2, "%08X", op2);
520         sprintf(sop1, "ACC");
521         sprintf(pcrel, "PC+ACC");
1414522      }
1415523      else
1416524      {
1417         sprintf(sop2,"%08X",op2);
1418         sprintf(sop1,"%08X",op1);
1419         sprintf(pcrel,"%08X",base+9+op1);
525         sprintf(sop2, "%08X", op2);
526         sprintf(sop1, "%08X", op1);
527         sprintf(pcrel, "%08X", base + 9 + op1);
1420528      }
1421      debug_console_printf(machine,"%08X ",base);
529      debug_console_printf(machine, "%08X ", base);
1422530      // dl=instr ebx=par1 eax=par2
1423531      switch (opcode)
1424532      {
1425         case 0x01:
1426            // if ((op2 & 0xff) == 0x880) op1=op1 & 0xfffffffd
1427            // out cf8,op2
1428            // out cfc,op1
1429            // out cf8,0
1430            // cf8 (CONFIG_ADDRESS) format:
1431            // 31 30      24 23        16 15           11 10              8 7               2 1 0
1432            // +-+----------+------------+---------------+-----------------+-----------------+-+-+
1433            // | | Reserved | Bus Number | Device Number | Function Number | Register Number |0|0|
1434            // +-+----------+------------+---------------+-----------------+-----------------+-+-+
1435            // 31 - Enable bit
1436            debug_console_printf(machine,"POKEPCI PCICONF[%s]=%s\n",sop2,sop1);
1437            break;
1438         case 0x02:
1439            debug_console_printf(machine,"OUTB    PORT[%s]=%s\n",sop2,sop1);
1440            break;
1441         case 0x03:
1442            debug_console_printf(machine,"POKE    MEM[%s]=%s\n",sop2,sop1);
1443            break;
1444         case 0x04:
1445            debug_console_printf(machine,"BNE     IF ACC != %s THEN PC=%s\n",sop2,pcrel);
1446            break;
1447         case 0x05:
1448            // out cf8,op2
1449            // in acc,cfc
1450            debug_console_printf(machine,"PEEKPCI ACC=PCICONF[%s]\n",sop2);
1451            break;
1452         case 0x06:
1453            debug_console_printf(machine,"AND/OR  ACC=(ACC & %s) | %s\n",sop2,sop1);
1454            break;
1455         case 0x07:
1456            debug_console_printf(machine,"BRA     PC=%s\n",pcrel);
1457            break;
1458         case 0x08:
1459            debug_console_printf(machine,"INB     ACC=PORT[%s]\n",sop2);
1460            break;
1461         case 0x09:
1462            debug_console_printf(machine,"PEEK    ACC=MEM[%s]\n",sop2);
1463            break;
1464         case 0xee:
1465            debug_console_printf(machine,"END\n");
1466            break;
1467         default:
1468            debug_console_printf(machine,"NOP     ????\n");
1469            break;
533      case 0x01:
534         // if ((op2 & 0xff) == 0x880) op1=op1 & 0xfffffffd
535         // out cf8,op2
536         // out cfc,op1
537         // out cf8,0
538         // cf8 (CONFIG_ADDRESS) format:
539         // 31 30      24 23        16 15           11 10              8 7               2 1 0
540         // +-+----------+------------+---------------+-----------------+-----------------+-+-+
541         // | | Reserved | Bus Number | Device Number | Function Number | Register Number |0|0|
542         // +-+----------+------------+---------------+-----------------+-----------------+-+-+
543         // 31 - Enable bit
544         debug_console_printf(machine, "POKEPCI PCICONF[%s]=%s\n", sop2, sop1);
545         break;
546      case 0x02:
547         debug_console_printf(machine, "OUTB    PORT[%s]=%s\n", sop2, sop1);
548         break;
549      case 0x03:
550         debug_console_printf(machine, "POKE    MEM[%s]=%s\n", sop2, sop1);
551         break;
552      case 0x04:
553         debug_console_printf(machine, "BNE     IF ACC != %s THEN PC=%s\n", sop2, pcrel);
554         break;
555      case 0x05:
556         // out cf8,op2
557         // in acc,cfc
558         debug_console_printf(machine, "PEEKPCI ACC=PCICONF[%s]\n", sop2);
559         break;
560      case 0x06:
561         debug_console_printf(machine, "AND/OR  ACC=(ACC & %s) | %s\n", sop2, sop1);
562         break;
563      case 0x07:
564         debug_console_printf(machine, "BRA     PC=%s\n", pcrel);
565         break;
566      case 0x08:
567         debug_console_printf(machine, "INB     ACC=PORT[%s]\n", sop2);
568         break;
569      case 0x09:
570         debug_console_printf(machine, "PEEK    ACC=MEM[%s]\n", sop2);
571         break;
572      case 0xee:
573         debug_console_printf(machine, "END\n");
574         break;
575      default:
576         debug_console_printf(machine, "NOP     ????\n");
577         break;
1470578      }
1471579      if (opcode == 0xee)
1472580         break;
1473581      if (size <= 9)
1474582         break;
1475      size-=9;
583      size -= 9;
1476584   }
1477585}
1478586
1479587static void jamtable_disasm_command(running_machine &machine, int ref, int params, const char **param)
1480588{
1481589   chihiro_state *state = machine.driver_data<chihiro_state>();
1482   address_space &space=state->m_maincpu->space();
1483   UINT64  addr,size;
590   address_space &space = state->m_maincpu->space();
591   UINT64  addr, size;
1484592
1485593   if (params < 2)
1486594      return;
r242208r242209
1494602static void dump_string_command(running_machine &machine, int ref, int params, const char **param)
1495603{
1496604   chihiro_state *state = machine.driver_data<chihiro_state>();
1497   address_space &space=state->m_maincpu->space();
605   address_space &space = state->m_maincpu->space();
1498606   UINT64  addr;
1499607   offs_t address;
1500   UINT32 length,maximumlength;
608   UINT32 length, maximumlength;
1501609   offs_t buffer;
1502610
1503611   if (params < 1)
1504612      return;
1505613   if (!debug_command_parameter_number(machine, param[0], &addr))
1506614      return;
1507   address=(offs_t)addr;
1508   if (!debug_cpu_translate(space,TRANSLATE_READ_DEBUG,&address))
615   address = (offs_t)addr;
616   if (!debug_cpu_translate(space, TRANSLATE_READ_DEBUG, &address))
1509617   {
1510      debug_console_printf(machine,"Address is unmapped.\n");
618      debug_console_printf(machine, "Address is unmapped.\n");
1511619      return;
1512620   }
1513   length=space.read_word_unaligned(address);
1514   maximumlength=space.read_word_unaligned(address+2);
1515   buffer=space.read_dword_unaligned(address+4);
1516   debug_console_printf(machine,"Length %d word\n",length);
1517   debug_console_printf(machine,"MaximumLength %d word\n",maximumlength);
1518   debug_console_printf(machine,"Buffer %08X byte* ",buffer);
1519   if (!debug_cpu_translate(space,TRANSLATE_READ_DEBUG,&buffer))
621   length = space.read_word_unaligned(address);
622   maximumlength = space.read_word_unaligned(address + 2);
623   buffer = space.read_dword_unaligned(address + 4);
624   debug_console_printf(machine, "Length %d word\n", length);
625   debug_console_printf(machine, "MaximumLength %d word\n", maximumlength);
626   debug_console_printf(machine, "Buffer %08X byte* ", buffer);
627   if (!debug_cpu_translate(space, TRANSLATE_READ_DEBUG, &buffer))
1520628   {
1521      debug_console_printf(machine,"\nBuffer is unmapped.\n");
629      debug_console_printf(machine, "\nBuffer is unmapped.\n");
1522630      return;
1523631   }
1524632   if (length > 256)
1525      length=256;
1526   for (int a=0;a < length;a++)
633      length = 256;
634   for (int a = 0; a < length; a++)
1527635   {
1528      UINT8 c=space.read_byte(buffer+a);
1529      debug_console_printf(machine,"%c",c);
636      UINT8 c = space.read_byte(buffer + a);
637      debug_console_printf(machine, "%c", c);
1530638   }
1531   debug_console_printf(machine,"\n");
639   debug_console_printf(machine, "\n");
1532640}
1533641
1534642static void dump_process_command(running_machine &machine, int ref, int params, const char **param)
1535643{
1536644   chihiro_state *state = machine.driver_data<chihiro_state>();
1537   address_space &space=state->m_maincpu->space();
645   address_space &space = state->m_maincpu->space();
1538646   UINT64 addr;
1539647   offs_t address;
1540648
r242208r242209
1542650      return;
1543651   if (!debug_command_parameter_number(machine, param[0], &addr))
1544652      return;
1545   address=(offs_t)addr;
1546   if (!debug_cpu_translate(space,TRANSLATE_READ_DEBUG,&address))
653   address = (offs_t)addr;
654   if (!debug_cpu_translate(space, TRANSLATE_READ_DEBUG, &address))
1547655   {
1548      debug_console_printf(machine,"Address is unmapped.\n");
656      debug_console_printf(machine, "Address is unmapped.\n");
1549657      return;
1550658   }
1551   debug_console_printf(machine,"ReadyListHead {%08X,%08X} _LIST_ENTRY\n",space.read_dword_unaligned(address),space.read_dword_unaligned(address+4));
1552   debug_console_printf(machine,"ThreadListHead {%08X,%08X} _LIST_ENTRY\n",space.read_dword_unaligned(address+8),space.read_dword_unaligned(address+12));
1553   debug_console_printf(machine,"StackCount %d dword\n",space.read_dword_unaligned(address+16));
1554   debug_console_printf(machine,"ThreadQuantum %d dword\n",space.read_dword_unaligned(address+20));
1555   debug_console_printf(machine,"BasePriority %d byte\n",space.read_byte(address+24));
1556   debug_console_printf(machine,"DisableBoost %d byte\n",space.read_byte(address+25));
1557   debug_console_printf(machine,"DisableQuantum %d byte\n",space.read_byte(address+26));
1558   debug_console_printf(machine,"_padding %d byte\n",space.read_byte(address+27));
659   debug_console_printf(machine, "ReadyListHead {%08X,%08X} _LIST_ENTRY\n", space.read_dword_unaligned(address), space.read_dword_unaligned(address + 4));
660   debug_console_printf(machine, "ThreadListHead {%08X,%08X} _LIST_ENTRY\n", space.read_dword_unaligned(address + 8), space.read_dword_unaligned(address + 12));
661   debug_console_printf(machine, "StackCount %d dword\n", space.read_dword_unaligned(address + 16));
662   debug_console_printf(machine, "ThreadQuantum %d dword\n", space.read_dword_unaligned(address + 20));
663   debug_console_printf(machine, "BasePriority %d byte\n", space.read_byte(address + 24));
664   debug_console_printf(machine, "DisableBoost %d byte\n", space.read_byte(address + 25));
665   debug_console_printf(machine, "DisableQuantum %d byte\n", space.read_byte(address + 26));
666   debug_console_printf(machine, "_padding %d byte\n", space.read_byte(address + 27));
1559667}
1560668
1561669static void dump_list_command(running_machine &machine, int ref, int params, const char **param)
1562670{
1563671   chihiro_state *state = machine.driver_data<chihiro_state>();
1564   address_space &space=state->m_maincpu->space();
1565   UINT64 addr,offs,start,old;
1566   offs_t address,offset;
672   address_space &space = state->m_maincpu->space();
673   UINT64 addr, offs, start, old;
674   offs_t address, offset;
1567675
1568676   if (params < 1)
1569677      return;
1570678   if (!debug_command_parameter_number(machine, param[0], &addr))
1571679      return;
1572   offs=0;
1573   offset=0;
680   offs = 0;
681   offset = 0;
1574682   if (params >= 2)
1575683   {
1576684      if (!debug_command_parameter_number(machine, param[1], &offs))
1577685         return;
1578      offset=(offs_t)offs;
686      offset = (offs_t)offs;
1579687   }
1580   start=addr;
1581   address=(offs_t)addr;
1582   if (!debug_cpu_translate(space,TRANSLATE_READ_DEBUG,&address))
688   start = addr;
689   address = (offs_t)addr;
690   if (!debug_cpu_translate(space, TRANSLATE_READ_DEBUG, &address))
1583691   {
1584      debug_console_printf(machine,"Address is unmapped.\n");
692      debug_console_printf(machine, "Address is unmapped.\n");
1585693      return;
1586694   }
1587695   if (params >= 2)
1588      debug_console_printf(machine,"Entry    Object\n");
696      debug_console_printf(machine, "Entry    Object\n");
1589697   else
1590      debug_console_printf(machine,"Entry\n");
1591   for (int num=0;num < 32;num++)
698      debug_console_printf(machine, "Entry\n");
699   for (int num = 0; num < 32; num++)
1592700   {
1593701      if (params >= 2)
1594         debug_console_printf(machine,"%08X %08X\n",(UINT32)addr,(offs_t)addr-offset);
702         debug_console_printf(machine, "%08X %08X\n", (UINT32)addr, (offs_t)addr - offset);
1595703      else
1596         debug_console_printf(machine,"%08X\n",(UINT32)addr);
1597      old=addr;
1598      addr=space.read_dword_unaligned(address);
704         debug_console_printf(machine, "%08X\n", (UINT32)addr);
705      old = addr;
706      addr = space.read_dword_unaligned(address);
1599707      if (addr == start)
1600708         break;
1601709      if (addr == old)
1602710         break;
1603      address=(offs_t)addr;
1604      if (!debug_cpu_translate(space,TRANSLATE_READ_DEBUG,&address))
711      address = (offs_t)addr;
712      if (!debug_cpu_translate(space, TRANSLATE_READ_DEBUG, &address))
1605713         break;
1606714   }
1607715}
r242208r242209
1609717static void curthread_command(running_machine &machine, int ref, int params, const char **param)
1610718{
1611719   chihiro_state *state = machine.driver_data<chihiro_state>();
1612   address_space &space=state->m_maincpu->space();
720   address_space &space = state->m_maincpu->space();
1613721   UINT64 fsbase;
1614   UINT32 kthrd,topstack,tlsdata;
722   UINT32 kthrd, topstack, tlsdata;
1615723   offs_t address;
1616724
1617725   fsbase = state->m_maincpu->state_int(44);
1618   address=(offs_t)fsbase+0x28;
1619   if (!debug_cpu_translate(space,TRANSLATE_READ_DEBUG,&address))
726   address = (offs_t)fsbase + 0x28;
727   if (!debug_cpu_translate(space, TRANSLATE_READ_DEBUG, &address))
1620728   {
1621      debug_console_printf(machine,"Address is unmapped.\n");
729      debug_console_printf(machine, "Address is unmapped.\n");
1622730      return;
1623731   }
1624   kthrd=space.read_dword_unaligned(address);
1625   debug_console_printf(machine,"Current thread is %08X\n",kthrd);
1626   address=(offs_t)kthrd+0x1c;
1627   if (!debug_cpu_translate(space,TRANSLATE_READ_DEBUG,&address))
732   kthrd = space.read_dword_unaligned(address);
733   debug_console_printf(machine, "Current thread is %08X\n", kthrd);
734   address = (offs_t)kthrd + 0x1c;
735   if (!debug_cpu_translate(space, TRANSLATE_READ_DEBUG, &address))
1628736      return;
1629   topstack=space.read_dword_unaligned(address);
1630   debug_console_printf(machine,"Current thread stack top is %08X\n",topstack);
1631   address=(offs_t)kthrd+0x28;
1632   if (!debug_cpu_translate(space,TRANSLATE_READ_DEBUG,&address))
737   topstack = space.read_dword_unaligned(address);
738   debug_console_printf(machine, "Current thread stack top is %08X\n", topstack);
739   address = (offs_t)kthrd + 0x28;
740   if (!debug_cpu_translate(space, TRANSLATE_READ_DEBUG, &address))
1633741      return;
1634   tlsdata=space.read_dword_unaligned(address);
742   tlsdata = space.read_dword_unaligned(address);
1635743   if (tlsdata == 0)
1636      address=(offs_t)topstack-0x210-8;
744      address = (offs_t)topstack - 0x210 - 8;
1637745   else
1638      address=(offs_t)tlsdata-8;
1639   if (!debug_cpu_translate(space,TRANSLATE_READ_DEBUG,&address))
746      address = (offs_t)tlsdata - 8;
747   if (!debug_cpu_translate(space, TRANSLATE_READ_DEBUG, &address))
1640748      return;
1641   debug_console_printf(machine,"Current thread function is %08X\n",space.read_dword_unaligned(address));
749   debug_console_printf(machine, "Current thread function is %08X\n", space.read_dword_unaligned(address));
1642750}
1643751
1644752static void generate_irq_command(running_machine &machine, int ref, int params, const char **param)
1645753{
1646754   UINT64 irq;
1647   chihiro_state *chst=machine.driver_data<chihiro_state>();
755   chihiro_state *chst = machine.driver_data<chihiro_state>();
1648756
1649757   if (params < 1)
1650758      return;
r242208r242209
1654762      return;
1655763   if (irq == 2)
1656764      return;
1657   chst->debug_generate_irq((int)irq,true);
765   chst->debug_generate_irq((int)irq, true);
1658766}
1659767
1660768static void nv2a_combiners_command(running_machine &machine, int ref, int params, const char **param)
1661769{
1662770   int en;
1663771
1664   chihiro_state *chst=machine.driver_data<chihiro_state>();
1665   en=chst->nvidia_nv2a->toggle_register_combiners_usage();
772   chihiro_state *chst = machine.driver_data<chihiro_state>();
773   en = chst->nvidia_nv2a->toggle_register_combiners_usage();
1666774   if (en != 0)
1667      debug_console_printf(machine,"Register combiners enabled\n");
775      debug_console_printf(machine, "Register combiners enabled\n");
1668776   else
1669      debug_console_printf(machine,"Register combiners disabled\n");
777      debug_console_printf(machine, "Register combiners disabled\n");
1670778}
1671779
1672780static void grab_texture_command(running_machine &machine, int ref, int params, const char **param)
r242208r242209
1680788      return;
1681789   if ((param[1][0] == 0) || (strlen(param[1]) > 127))
1682790      return;
1683   chst->nvidia_nv2a->debug_grab_texture((int)type,param[1]);
791   chst->nvidia_nv2a->debug_grab_texture((int)type, param[1]);
1684792}
1685793
1686794static void grab_vprog_command(running_machine &machine, int ref, int params, const char **param)
r242208r242209
1728836         if (!debug_cpu_translate(space, TRANSLATE_READ_DEBUG, &addr))
1729837            return;
1730838         instruction[0] = space.read_dword_unaligned(address);
1731         instruction[1] = space.read_dword_unaligned(address+4);
1732         instruction[2] = space.read_dword_unaligned(address+8);
1733         instruction[3] = space.read_dword_unaligned(address+12);
1734      } else
839         instruction[1] = space.read_dword_unaligned(address + 4);
840         instruction[2] = space.read_dword_unaligned(address + 8);
841         instruction[3] = space.read_dword_unaligned(address + 12);
842      }
843      else
1735844         chst->nvidia_nv2a->debug_grab_vertex_program_slot((int)address, instruction);
1736845      while (vd.disassemble(instruction, line) != 0)
1737846         debug_console_printf(machine, "%s\n", line);
r242208r242209
1745854
1746855static void help_command(running_machine &machine, int ref, int params, const char **param)
1747856{
1748   debug_console_printf(machine,"Available Chihiro commands:\n");
1749   debug_console_printf(machine,"  chihiro jamdis,<start>,<size> -- Disassemble <size> bytes of JamTable instructions starting at <start>\n");
1750   debug_console_printf(machine,"  chihiro dump_string,<address> -- Dump _STRING object at <address>\n");
1751   debug_console_printf(machine,"  chihiro dump_process,<address> -- Dump _PROCESS object at <address>\n");
1752   debug_console_printf(machine,"  chihiro dump_list,<address>[,<offset>] -- Dump _LIST_ENTRY chain starting at <address>\n");
1753   debug_console_printf(machine,"  chihiro curthread -- Print information about current thread\n");
1754   debug_console_printf(machine,"  chihiro irq,<number> -- Generate interrupt with irq number 0-15\n");
1755   debug_console_printf(machine,"  chihiro nv2a_combiners -- Toggle use of register combiners\n");
1756   debug_console_printf(machine,"  chihiro grab_texture,<type>,<filename> -- Save to <filename> the next used texture of type <type>\n");
1757   debug_console_printf(machine,"  chihiro grab_vprog,<filename> -- save current vertex program instruction slots to <filename>\n");
1758   debug_console_printf(machine,"  chihiro vprogdis,<address>,<length>[,<type>] -- disassemble <lenght> vertex program instructions at <address> of <type>\n");
1759   debug_console_printf(machine,"  chihiro help -- this list\n");
857   debug_console_printf(machine, "Available Chihiro commands:\n");
858   debug_console_printf(machine, "  chihiro jamdis,<start>,<size> -- Disassemble <size> bytes of JamTable instructions starting at <start>\n");
859   debug_console_printf(machine, "  chihiro dump_string,<address> -- Dump _STRING object at <address>\n");
860   debug_console_printf(machine, "  chihiro dump_process,<address> -- Dump _PROCESS object at <address>\n");
861   debug_console_printf(machine, "  chihiro dump_list,<address>[,<offset>] -- Dump _LIST_ENTRY chain starting at <address>\n");
862   debug_console_printf(machine, "  chihiro curthread -- Print information about current thread\n");
863   debug_console_printf(machine, "  chihiro irq,<number> -- Generate interrupt with irq number 0-15\n");
864   debug_console_printf(machine, "  chihiro nv2a_combiners -- Toggle use of register combiners\n");
865   debug_console_printf(machine, "  chihiro grab_texture,<type>,<filename> -- Save to <filename> the next used texture of type <type>\n");
866   debug_console_printf(machine, "  chihiro grab_vprog,<filename> -- save current vertex program instruction slots to <filename>\n");
867   debug_console_printf(machine, "  chihiro vprogdis,<address>,<length>[,<type>] -- disassemble <lenght> vertex program instructions at <address> of <type>\n");
868   debug_console_printf(machine, "  chihiro help -- this list\n");
1760869}
1761870
1762871static void chihiro_debug_commands(running_machine &machine, int ref, int params, const char **param)
1763872{
1764873   if (params < 1)
1765874      return;
1766   if (strcmp("jamdis",param[0]) == 0)
1767      jamtable_disasm_command(machine,ref,params-1,param+1);
1768   else if (strcmp("dump_string",param[0]) == 0)
1769      dump_string_command(machine,ref,params-1,param+1);
1770   else if (strcmp("dump_process",param[0]) == 0)
1771      dump_process_command(machine,ref,params-1,param+1);
1772   else if (strcmp("dump_list",param[0]) == 0)
1773      dump_list_command(machine,ref,params-1,param+1);
1774   else if (strcmp("curthread",param[0]) == 0)
1775      curthread_command(machine,ref,params-1,param+1);
1776   else if (strcmp("irq",param[0]) == 0)
1777      generate_irq_command(machine,ref,params-1,param+1);
1778   else if (strcmp("nv2a_combiners",param[0]) == 0)
1779      nv2a_combiners_command(machine,ref,params-1,param+1);
875   if (strcmp("jamdis", param[0]) == 0)
876      jamtable_disasm_command(machine, ref, params - 1, param + 1);
877   else if (strcmp("dump_string", param[0]) == 0)
878      dump_string_command(machine, ref, params - 1, param + 1);
879   else if (strcmp("dump_process", param[0]) == 0)
880      dump_process_command(machine, ref, params - 1, param + 1);
881   else if (strcmp("dump_list", param[0]) == 0)
882      dump_list_command(machine, ref, params - 1, param + 1);
883   else if (strcmp("curthread", param[0]) == 0)
884      curthread_command(machine, ref, params - 1, param + 1);
885   else if (strcmp("irq", param[0]) == 0)
886      generate_irq_command(machine, ref, params - 1, param + 1);
887   else if (strcmp("nv2a_combiners", param[0]) == 0)
888      nv2a_combiners_command(machine, ref, params - 1, param + 1);
1780889   else if (strcmp("grab_texture", param[0]) == 0)
1781890      grab_texture_command(machine, ref, params - 1, param + 1);
1782891   else if (strcmp("grab_vprog", param[0]) == 0)
r242208r242209
1784893   else if (strcmp("vprogdis", param[0]) == 0)
1785894      vprogdis_command(machine, ref, params - 1, param + 1);
1786895   else
1787      help_command(machine,ref,params-1,param+1);
896      help_command(machine, ref, params - 1, param + 1);
1788897}
1789898
1790/*
1791 * Graphics
1792 */
1793
1794UINT32 nv2a_renderer::dilate0(UINT32 value,int bits) // dilate first "bits" bits in "value"
899void chihiro_state::debug_generate_irq(int irq, bool active)
1795900{
1796   UINT32 x,m1,m2,m3;
1797   int a;
1798
1799   x = value;
1800   for (a=0;a < bits;a++)
1801   {
1802      m2 = 1 << (a << 1);
1803      m1 = m2 - 1;
1804      m3 = (~m1) << 1;
1805      x = (x & m1) + (x & m2) + ((x & m3) << 1);
1806   }
1807   return x;
1808}
1809
1810UINT32 nv2a_renderer::dilate1(UINT32 value,int bits) // dilate first "bits" bits in "value"
1811{
1812   UINT32 x,m1,m2,m3;
1813   int a;
1814
1815   x = value;
1816   for (a=0;a < bits;a++)
1817   {
1818      m2 = 1 << (a << 1);
1819      m1 = m2 - 1;
1820      m3 = (~m1) << 1;
1821      x = (x & m1) + ((x & m2) << 1) + ((x & m3) << 1);
1822   }
1823   return x;
1824}
1825
1826void nv2a_renderer::computedilated(void)
1827{
1828   int a,b;
1829
1830   for (b=0;b < 16;b++)
1831      for (a=0;a < 2048;a++) {
1832         dilated0[b][a]=dilate0(a,b);
1833         dilated1[b][a]=dilate1(a,b);
1834      }
1835   for (b=0;b < 16;b++)
1836      for (a=0;a < 16;a++)
1837         dilatechose[(b << 4) + a]=(a < b ? a : b);
1838}
1839
1840int nv2a_renderer::geforce_commandkind(UINT32 word)
1841{
1842   if ((word & 0x00000003) == 0x00000002)
1843      return 7; // call
1844   if ((word & 0x00000003) == 0x00000001)
1845      return 6; // jump
1846   if ((word & 0xE0030003) == 0x40000000)
1847      return 5; // non increasing
1848   if ((word & 0xE0000003) == 0x20000000)
1849      return 4; // old jump
1850   if ((word & 0xFFFF0003) == 0x00030000)
1851      return 3; // long non icreasing
1852   if ((word & 0xFFFFFFFF) == 0x00020000)
1853      return 2; // return
1854   if ((word & 0xFFFF0003) == 0x00010000)
1855      return 1; // sli conditional
1856   if ((word & 0xE0030003) == 0x00000000)
1857      return 0; // increasing
1858   return -1;
1859}
1860
1861UINT32 nv2a_renderer::geforce_object_offset(UINT32 handle)
1862{
1863   UINT32 h=((((handle >> 11) ^ handle) >> 11) ^ handle) & 0x7ff;
1864   UINT32 o=(pfifo[0x210/4] & 0x1f) << 8; // or 12 ?
1865   UINT32 e=o+h*8; // at 0xfd000000+0x00700000
1866   UINT32 w;
1867
1868   if (ramin[e/4] != handle)
1869      e=0;
1870   w=ramin[e/4+1];
1871   return (w & 0xffff)*0x10;
1872}
1873
1874void nv2a_renderer::geforce_read_dma_object(UINT32 handle,UINT32 &offset,UINT32 &size)
1875{
1876   //UINT32 objclass,pt_present,pt_linear,access,target,rorw;
1877   UINT32 dma_adjust,dma_frame;
1878   UINT32 o=geforce_object_offset(handle);
1879
1880   o=o/4;
1881   //objclass=ramin[o] & 0xfff;
1882   //pt_present=(ramin[o] >> 12) & 1;
1883   //pt_linear=(ramin[o] >> 13) & 1;
1884   //access=(ramin[o] >> 14) & 3;
1885   //target=(ramin[o] >> 16) & 3;
1886   dma_adjust=(ramin[o] >> 20) & 0xfff;
1887   size=ramin[o+1];
1888   //rorw=ramin[o+2] & 1;
1889   dma_frame=ramin[o+2] & 0xfffff000;
1890   offset=dma_frame+dma_adjust;
1891}
1892
1893/*void myline(bitmap_rgb32 &bmp,float x1,float y1,float x2,float y2)
1894{
1895    int xx1,yy1,xx2,yy2;
1896
1897    xx1=x1;
1898    xx2=x2;
1899    yy1=y1;
1900    yy2=y2;
1901    if (xx1 == xx2) {
1902        if (yy1 > yy2) {
1903            int t=yy1;
1904            yy1=yy2;
1905            yy2=t;
1906        }
1907        for (int y=yy1;y <= yy2;y++)
1908            *((UINT32 *)bmp.raw_pixptr(y,xx1))= -1;
1909    } else if (yy1 == yy2) {
1910        if (xx1 > xx2) {
1911            int t=xx1;
1912            xx1=xx2;
1913            xx2=t;
1914        }
1915        for (int x=xx1;x <= xx2;x++)
1916            *((UINT32 *)bmp.raw_pixptr(yy1,x))= -1;
1917    }
1918}*/
1919
1920inline UINT32 convert_a4r4g4b4_a8r8g8b8(UINT32 a4r4g4b4)
1921{
1922   UINT32 a8r8g8b8;
1923   int ca,cr,cg,cb;
1924
1925   cb=pal4bit(a4r4g4b4 & 0x000f);
1926   cg=pal4bit((a4r4g4b4 & 0x00f0) >> 4);
1927   cr=pal4bit((a4r4g4b4 & 0x0f00) >> 8);
1928   ca=pal4bit((a4r4g4b4 & 0xf000) >> 12);
1929   a8r8g8b8=(ca<<24)|(cr<<16)|(cg<<8)|(cb); // color converted to 8 bits per component
1930   return a8r8g8b8;
1931}
1932
1933inline UINT32 convert_a1r5g5b5_a8r8g8b8(UINT32 a1r5g5b5)
1934{
1935   UINT32 a8r8g8b8;
1936   int ca,cr,cg,cb;
1937
1938   cb=pal5bit(a1r5g5b5 & 0x001f);
1939   cg=pal5bit((a1r5g5b5 & 0x03e0) >> 5);
1940   cr=pal5bit((a1r5g5b5 & 0x7c00) >> 10);
1941   ca=a1r5g5b5 & 0x8000 ? 0xff : 0;
1942   a8r8g8b8=(ca<<24)|(cr<<16)|(cg<<8)|(cb); // color converted to 8 bits per component
1943   return a8r8g8b8;
1944}
1945
1946inline UINT32 convert_r5g6b5_r8g8b8(UINT32 r5g6b5)
1947{
1948   UINT32 r8g8b8;
1949   int cr,cg,cb;
1950
1951   cb=pal5bit(r5g6b5 & 0x001f);
1952   cg=pal6bit((r5g6b5 & 0x07e0) >> 5);
1953   cr=pal5bit((r5g6b5 & 0xf800) >> 11);
1954   r8g8b8=(cr<<16)|(cg<<8)|(cb); // color converted to 8 bits per component
1955   return r8g8b8;
1956}
1957
1958UINT32 nv2a_renderer::texture_get_texel(int number,int x,int y)
1959{
1960   UINT32 to, s, c, sa, ca;
1961   UINT32 a4r4g4b4, a1r5g5b5, r5g6b5;
1962   int bx, by;
1963   int color0, color1, color0m2, color1m2, alpha0, alpha1;
1964   UINT32 codes;
1965   UINT64 alphas;
1966   int cr, cg, cb;
1967
1968   // force to [0,size-1]
1969   x = (unsigned int)x & (texture[number].sizeu - 1);
1970   y = (unsigned int)y & (texture[number].sizev - 1);
1971   switch (texture[number].format) {
1972   case A8R8G8B8:
1973      to = dilated0[texture[number].dilate][x] + dilated1[texture[number].dilate][y]; // offset of texel in texture memory
1974      return *(((UINT32 *)texture[number].buffer) + to); // get texel color
1975   case DXT1:
1976      bx = x >> 2;
1977      by = y >> 2;
1978      x = x & 3;
1979      y = y & 3;
1980      to = bx + by*(texture[number].sizeu >> 2);
1981      color0 = *((UINT16 *)(((UINT64 *)texture[number].buffer) + to) + 0);
1982      color1 = *((UINT16 *)(((UINT64 *)texture[number].buffer) + to) + 1);
1983      codes = *((UINT32 *)(((UINT64 *)texture[number].buffer) + to) + 1);
1984      s = (y << 3) + (x << 1);
1985      c = (codes >> s) & 3;
1986      c = c + (color0 > color1 ? 0 : 4);
1987      color0m2 = color0 << 1;
1988      color1m2 = color1 << 1;
1989      switch (c) {
1990      case 0:
1991         return 0xff000000 + convert_r5g6b5_r8g8b8(color0);
1992      case 1:
1993         return 0xff000000 + convert_r5g6b5_r8g8b8(color1);
1994      case 2:
1995         cb = pal5bit(((color0m2 & 0x003e) + (color1 & 0x001f)) / 3);
1996         cg = pal6bit(((color0m2 & 0x0fc0) + (color1 & 0x07e0)) / 3 >> 5);
1997         cr = pal5bit(((color0m2 & 0x1f000) + color1) / 3 >> 11);
1998         return 0xff000000 | (cr << 16) | (cg << 8) | (cb);
1999      case 3:
2000         cb = pal5bit(((color1m2 & 0x003e) + (color0 & 0x001f)) / 3);
2001         cg = pal6bit(((color1m2 & 0x0fc0) + (color0 & 0x07e0)) / 3 >> 5);
2002         cr = pal5bit(((color1m2 & 0x1f000) + color0) / 3 >> 11);
2003         return 0xff000000 | (cr << 16) | (cg << 8) | (cb);
2004      case 4:
2005         return 0xff000000 + convert_r5g6b5_r8g8b8(color0);
2006      case 5:
2007         return 0xff000000 + convert_r5g6b5_r8g8b8(color1);
2008      case 6:
2009         cb = pal5bit(((color0 & 0x001f) + (color1 & 0x001f)) / 2);
2010         cg = pal6bit(((color0 & 0x07e0) + (color1 & 0x07e0)) / 2 >> 5);
2011         cr = pal5bit(((color0 & 0xf800) + (color1 & 0xf800)) / 2 >> 11);
2012         return 0xff000000 | (cr << 16) | (cg << 8) | (cb);
2013      default:
2014         return 0xff000000;
2015      }
2016   case DXT3:
2017      bx = x >> 2;
2018      by = y >> 2;
2019      x = x & 3;
2020      y = y & 3;
2021      to = (bx + by*(texture[number].sizeu >> 2)) << 1;
2022      color0 = *((UINT16 *)(((UINT64 *)texture[number].buffer) + to) + 4);
2023      color1 = *((UINT16 *)(((UINT64 *)texture[number].buffer) + to) + 5);
2024      codes = *((UINT32 *)(((UINT64 *)texture[number].buffer) + to) + 3);
2025      alphas = *(((UINT64 *)texture[number].buffer) + to);
2026      s = (y << 3) + (x << 1);
2027      sa = ((y << 2) + x) << 2;
2028      c = (codes >> s) & 3;
2029      ca = (alphas >> sa) & 15;
2030      switch (c) {
2031      case 0:
2032         return ((ca + (ca << 4)) << 24) + convert_r5g6b5_r8g8b8(color0);
2033      case 1:
2034         return ((ca + (ca << 4)) << 24) + convert_r5g6b5_r8g8b8(color1);
2035      case 2:
2036         cb = pal5bit((2 * (color0 & 0x001f) + (color1 & 0x001f)) / 3);
2037         cg = pal6bit((2 * (color0 & 0x07e0) + (color1 & 0x07e0)) / 3 >> 5);
2038         cr = pal5bit((2 * (color0 & 0xf800) + (color1 & 0xf800)) / 3 >> 11);
2039         return ((ca + (ca << 4)) << 24) | (cr << 16) | (cg << 8) | (cb);
2040      default:
2041         cb = pal5bit(((color0 & 0x001f) + 2 * (color1 & 0x001f)) / 3);
2042         cg = pal6bit(((color0 & 0x07e0) + 2 * (color1 & 0x07e0)) / 3 >> 5);
2043         cr = pal5bit(((color0 & 0xf800) + 2 * (color1 & 0xf800)) / 3 >> 11);
2044         return ((ca + (ca << 4)) << 24) | (cr << 16) | (cg << 8) | (cb);
2045      }
2046   case A4R4G4B4:
2047      to = dilated0[texture[number].dilate][x] + dilated1[texture[number].dilate][y]; // offset of texel in texture memory
2048      a4r4g4b4 = *(((UINT16 *)texture[number].buffer) + to); // get texel color
2049      return convert_a4r4g4b4_a8r8g8b8(a4r4g4b4);
2050   case A1R5G5B5:
2051      to = dilated0[texture[number].dilate][x] + dilated1[texture[number].dilate][y]; // offset of texel in texture memory
2052      a1r5g5b5 = *(((UINT16 *)texture[number].buffer) + to); // get texel color
2053      return convert_a1r5g5b5_a8r8g8b8(a1r5g5b5);
2054   case R5G6B5:
2055      to = dilated0[texture[number].dilate][x] + dilated1[texture[number].dilate][y]; // offset of texel in texture memory
2056      r5g6b5 = *(((UINT16 *)texture[number].buffer) + to); // get texel color
2057      return 0xff000000 + convert_r5g6b5_r8g8b8(r5g6b5);
2058   case R8G8B8_RECT:
2059      to = texture[number].rectangle_pitch*y + (x << 2);
2060      return *((UINT32 *)(((UINT8 *)texture[number].buffer) + to));
2061   case A8R8G8B8_RECT:
2062      to = texture[number].rectangle_pitch*y + (x << 2);
2063      return *((UINT32 *)(((UINT8 *)texture[number].buffer) + to));
2064   case DXT5:
2065      bx = x >> 2;
2066      by = y >> 2;
2067      x = x & 3;
2068      y = y & 3;
2069      to = (bx + by*(texture[number].sizeu >> 2)) << 1;
2070      color0 = *((UINT16 *)(((UINT64 *)texture[number].buffer) + to) + 4);
2071      color1 = *((UINT16 *)(((UINT64 *)texture[number].buffer) + to) + 5);
2072      codes = *((UINT32 *)(((UINT64 *)texture[number].buffer) + to) + 3);
2073      alpha0 = *((UINT8 *)(((UINT64 *)texture[number].buffer) + to) + 0);
2074      alpha1 = *((UINT8 *)(((UINT64 *)texture[number].buffer) + to) + 1);
2075      alphas = *(((UINT64 *)texture[number].buffer) + to);
2076      s = (y << 3) + (x << 1);
2077      sa = ((y << 2) + x) * 3;
2078      c = (codes >> s) & 3;
2079      ca = (alphas >> sa) & 7;
2080      ca = ca + (alpha0 > alpha1 ? 0 : 8);
2081      switch (ca) {
2082      case 0:
2083         ca = alpha0;
2084         break;
2085      case 1:
2086         ca = alpha1;
2087         break;
2088      case 2:
2089         ca = (6 * alpha0 + 1 * alpha1) / 7;
2090         break;
2091      case 3:
2092         ca = (5 * alpha0 + 2 * alpha1) / 7;
2093         break;
2094      case 4:
2095         ca = (4 * alpha0 + 3 * alpha1) / 7;
2096         break;
2097      case 5:
2098         ca = (3 * alpha0 + 4 * alpha1) / 7;
2099         break;
2100      case 6:
2101         ca = (2 * alpha0 + 5 * alpha1) / 7;
2102         break;
2103      case 7:
2104         ca = (1 * alpha0 + 6 * alpha1) / 7;
2105         break;
2106      case 8:
2107         ca = alpha0;
2108         break;
2109      case 9:
2110         ca = alpha1;
2111         break;
2112      case 10:
2113         ca = (4 * alpha0 + 1 * alpha1) / 5;
2114         break;
2115      case 11:
2116         ca = (3 * alpha0 + 2 * alpha1) / 5;
2117         break;
2118      case 12:
2119         ca = (2 * alpha0 + 3 * alpha1) / 5;
2120         break;
2121      case 13:
2122         ca = (1 * alpha0 + 4 * alpha1) / 5;
2123         break;
2124      case 14:
2125         ca = 0;
2126         break;
2127      case 15:
2128         ca = 255;
2129         break;
2130      }
2131      switch (c) {
2132      case 0:
2133         return (ca << 24) + convert_r5g6b5_r8g8b8(color0);
2134      case 1:
2135         return (ca << 24) + convert_r5g6b5_r8g8b8(color1);
2136      case 2:
2137         cb = pal5bit((2 * (color0 & 0x001f) + (color1 & 0x001f)) / 3);
2138         cg = pal6bit((2 * (color0 & 0x07e0) + (color1 & 0x07e0)) / 3 >> 5);
2139         cr = pal5bit((2 * (color0 & 0xf800) + (color1 & 0xf800)) / 3 >> 11);
2140         return (ca << 24) | (cr << 16) | (cg << 8) | (cb);
2141      default:
2142         cb = pal5bit(((color0 & 0x001f) + 2 * (color1 & 0x001f)) / 3);
2143         cg = pal6bit(((color0 & 0x07e0) + 2 * (color1 & 0x07e0)) / 3 >> 5);
2144         cr = pal5bit(((color0 & 0xf800) + 2 * (color1 & 0xf800)) / 3 >> 11);
2145         return (ca << 24) | (cr << 16) | (cg << 8) | (cb);
2146      }
2147   default:
2148      return 0xff00ff00;
2149   }
2150}
2151
2152void nv2a_renderer::write_pixel(int x, int y, UINT32 color)
2153{
2154   void *addr;
2155   UINT32 fbcolor;
2156   UINT32 c[4], fb[4], s[4], d[4], cc[4];
2157
2158   addr = this->fb.raw_pixptr(y, x);
2159   fbcolor = *((UINT32 *)addr);
2160   c[3] = color >> 24;
2161   c[2] = (color >> 16) & 255;
2162   c[1] = (color >> 8) & 255;
2163   c[0] = color & 255;
2164   fb[3] = fbcolor >> 24;
2165   fb[2] = (fbcolor >> 16) & 255;
2166   fb[1] = (fbcolor >> 8) & 255;
2167   fb[0] = fbcolor & 255;
2168   cc[3] = blend_color >> 24;
2169   cc[2] = (blend_color >> 16) & 255;
2170   cc[1] = (blend_color >> 8) & 255;
2171   cc[0] = blend_color & 255;
2172   // ownership test and scissor test not done
2173   // alpha test
2174   if (alpha_test_enabled) {
2175      switch (alpha_func) {
2176      case nv2a_renderer::NEVER:
2177         return;
2178      case nv2a_renderer::ALWAYS:
2179      default:
2180         break;
2181      case nv2a_renderer::LESS:
2182         if (c[3] >= alpha_reference)
2183            return;
2184         break;
2185      case nv2a_renderer::LEQUAL:
2186         if (c[3] > alpha_reference)
2187            return;
2188         break;
2189      case nv2a_renderer::EQUAL:
2190         if (c[3] != alpha_reference)
2191            return;
2192         break;
2193      case nv2a_renderer::GEQUAL:
2194         if (c[3] < alpha_reference)
2195            return;
2196         break;
2197      case nv2a_renderer::GREATER:
2198         if (c[3] <= alpha_reference)
2199            return;
2200         break;
2201      case nv2a_renderer::NOTEQUAL:
2202         if (c[3] == alpha_reference)
2203            return;
2204         break;
2205      }
2206   }
2207   // stencil test not done
2208   // depth buffer test not done
2209   // blending
2210   if (blending_enabled) {
2211      switch (blend_function_source) {
2212      case nv2a_renderer::ZERO:
2213         s[3] = s[2] = s[1] = s[0] = 0;
2214         break;
2215      case nv2a_renderer::ONE:
2216      default:
2217         s[3] = s[2] = s[1] = s[0] = 255;
2218         break;
2219      case nv2a_renderer::DST_COLOR:
2220         s[3] = fb[3];
2221         s[2] = fb[2];
2222         s[1] = fb[1];
2223         s[0] = fb[0];
2224         break;
2225      case nv2a_renderer::ONE_MINUS_DST_COLOR:
2226         s[3] = fb[3] ^ 255;
2227         s[2] = fb[2] ^ 255;
2228         s[1] = fb[1] ^ 255;
2229         s[0] = fb[0] ^ 255;
2230         break;
2231      case nv2a_renderer::SRC_ALPHA:
2232         s[3] = s[2] = s[1] = s[0] = c[3];
2233         break;
2234      case nv2a_renderer::ONE_MINUS_SRC_ALPHA:
2235         s[3] = s[2] = s[1] = s[0] = c[3] ^ 255;
2236         break;
2237      case nv2a_renderer::DST_ALPHA:
2238         s[3] = s[2] = s[1] = s[0] = fb[3];
2239         break;
2240      case nv2a_renderer::ONE_MINUS_DST_ALPHA:
2241         s[3] = s[2] = s[1] = s[0] = fb[3] ^ 255;
2242         break;
2243      case nv2a_renderer::CONSTANT_COLOR:
2244         s[3] = cc[3];
2245         s[2] = cc[2];
2246         s[1] = cc[1];
2247         s[0] = cc[0];
2248         break;
2249      case nv2a_renderer::ONE_MINUS_CONSTANT_COLOR:
2250         s[3] = cc[3] ^ 255;
2251         s[2] = cc[2] ^ 255;
2252         s[1] = cc[1] ^ 255;
2253         s[0] = cc[0] ^ 255;
2254         break;
2255      case nv2a_renderer::CONSTANT_ALPHA:
2256         s[3] = s[2] = s[1] = s[0] = cc[3];
2257         break;
2258      case nv2a_renderer::ONE_MINUS_CONSTANT_ALPHA:
2259         s[3] = s[2] = s[1] = s[0] = cc[3] ^ 255;
2260         break;
2261      case nv2a_renderer::SRC_ALPHA_SATURATE:
2262         s[3] = 255;
2263         if (c[3] < (fb[3] ^ 255))
2264            s[2] = c[3];
2265         else
2266            s[2] = fb[3];
2267         s[1] = s[0] = s[2];
2268         break;
2269      }
2270      switch (blend_function_destination) {
2271      case nv2a_renderer::ZERO:
2272      default:
2273         d[3] = d[2] = d[1] = d[0] = 0;
2274         break;
2275      case nv2a_renderer::ONE:
2276         d[3] = d[2] = d[1] = d[0] = 255;
2277         break;
2278      case nv2a_renderer::SRC_COLOR:
2279         d[3] = c[3];
2280         d[2] = c[2];
2281         d[1] = c[1];
2282         d[0] = c[0];
2283         break;
2284      case nv2a_renderer::ONE_MINUS_SRC_COLOR:
2285         d[3] = c[3] ^ 255;
2286         d[2] = c[2] ^ 255;
2287         d[1] = c[1] ^ 255;
2288         d[0] = c[0] ^ 255;
2289         break;
2290      case nv2a_renderer::SRC_ALPHA:
2291         d[3] = d[2] = d[1] = d[0] = c[3];
2292         break;
2293      case nv2a_renderer::ONE_MINUS_SRC_ALPHA:
2294         d[3] = d[2] = d[1] = d[0] = c[3] ^ 255;
2295         break;
2296      case nv2a_renderer::DST_ALPHA:
2297         d[3] = d[2] = d[1] = d[0] = fb[3];
2298         break;
2299      case nv2a_renderer::ONE_MINUS_DST_ALPHA:
2300         d[3] = d[2] = d[1] = d[0] = fb[3] ^ 255;
2301         break;
2302      case nv2a_renderer::CONSTANT_COLOR:
2303         d[3] = cc[3];
2304         d[2] = cc[2];
2305         d[1] = cc[1];
2306         d[0] = cc[0];
2307         break;
2308      case nv2a_renderer::ONE_MINUS_CONSTANT_COLOR:
2309         d[3] = cc[3] ^ 255;
2310         d[2] = cc[2] ^ 255;
2311         d[1] = cc[1] ^ 255;
2312         d[0] = cc[0] ^ 255;
2313         break;
2314      case nv2a_renderer::CONSTANT_ALPHA:
2315         d[3] = d[2] = d[1] = d[0] = cc[3];
2316         break;
2317      case nv2a_renderer::ONE_MINUS_CONSTANT_ALPHA:
2318         d[3] = d[2] = d[1] = d[0] = cc[3] ^ 255;
2319         break;
2320      }
2321      switch (blend_equation) {
2322      case nv2a_renderer::FUNC_ADD:
2323         c[3] = (c[3]*s[3] + fb[3]*d[3]) / 255;
2324         if (c[3] > 255)
2325            c[3] = 255;
2326         c[2] = (c[2]*s[2] + fb[2]*d[2]) / 255;
2327         if (c[2] > 255)
2328            c[2] = 255;
2329         c[1] = (c[1]*s[1] + fb[1]*d[1]) / 255;
2330         if (c[1] > 255)
2331            c[1] = 255;
2332         c[0] = (c[0]*s[0] + fb[0]*d[0]) / 255;
2333         if (c[0] > 255)
2334            c[0] = 255;
2335         break;
2336      case nv2a_renderer::FUNC_SUBTRACT:
2337         c[3] = (c[3]*s[3] - fb[3]*d[3]) / 255;
2338         if (c[3] < 0)
2339            c[3] = 255;
2340         c[2] = (c[2]*s[2] - fb[2]*d[2]) / 255;
2341         if (c[2] < 0)
2342            c[2] = 255;
2343         c[1] = (c[1]*s[1] - fb[1]*d[1]) / 255;
2344         if (c[1] < 0)
2345            c[1] = 255;
2346         c[0] = (c[0]*s[0] - fb[0]*d[0]) / 255;
2347         if (c[0] < 0)
2348            c[0] = 255;
2349         break;
2350      case nv2a_renderer::FUNC_REVERSE_SUBTRACT:
2351         c[3] = (fb[3] * d[3] - c[3] * s[3]) / 255;
2352         if (c[3] < 0)
2353            c[3] = 255;
2354         c[2] = (fb[2] * d[2] - c[2] * s[2]) / 255;
2355         if (c[2] < 0)
2356            c[2] = 255;
2357         c[1] = (fb[1] * d[1] - c[1] * s[1]) / 255;
2358         if (c[1] < 0)
2359            c[1] = 255;
2360         c[0] = (fb[0] * d[0] - c[0] * s[0]) / 255;
2361         if (c[0] < 0)
2362            c[0] = 255;
2363         break;
2364      case nv2a_renderer::MIN:
2365         c[3] = s[3];
2366         if (d[3] < c[3])
2367            c[3] = d[3];
2368         c[2] = s[2];
2369         if (d[2] < c[2])
2370            c[2] = d[2];
2371         c[1] = s[1];
2372         if (d[1] < c[1])
2373            c[1] = d[1];
2374         c[0] = s[0];
2375         if (d[0] < c[0])
2376            c[0] = d[0];
2377         break;
2378      case nv2a_renderer::MAX:
2379         c[3] = s[3];
2380         if (d[3] > c[3])
2381            c[3] = d[3];
2382         c[2] = s[2];
2383         if (d[2] > c[2])
2384            c[2] = d[2];
2385         c[1] = s[1];
2386         if (d[1] > c[1])
2387            c[1] = d[1];
2388         c[0] = s[0];
2389         if (d[0] > c[0])
2390            c[0] = d[0];
2391         break;
2392      }
2393   }
2394   // dithering not done
2395   // logical operation
2396   if (logical_operation_enabled) {
2397      switch (logical_operation) {
2398      case  nv2a_renderer::CLEAR:
2399         c[3] = 0;
2400         c[2] = 0;
2401         c[1] = 0;
2402         c[0] = 0;
2403         break;
2404      case  nv2a_renderer::AND:
2405         c[3] = c[3] & fb[3];
2406         c[2] = c[2] & fb[2];
2407         c[1] = c[1] & fb[1];
2408         c[0] = c[0] & fb[0];
2409         break;
2410      case  nv2a_renderer::AND_REVERSE:
2411         c[3] = c[3] & (fb[3] ^ 255);
2412         c[2] = c[2] & (fb[2] ^ 255);
2413         c[1] = c[1] & (fb[1] ^ 255);
2414         c[0] = c[0] & (fb[0] ^ 255);
2415         break;
2416      case  nv2a_renderer::COPY:
2417      default:
2418         break;
2419      case  nv2a_renderer::AND_INVERTED:
2420         c[3] = (c[3] ^ 255) & fb[3];
2421         c[2] = (c[2] ^ 255) & fb[2];
2422         c[1] = (c[1] ^ 255) & fb[1];
2423         c[0] = (c[0] ^ 255) & fb[0];
2424         break;
2425      case  nv2a_renderer::NOOP:
2426         c[3] = fb[3];
2427         c[2] = fb[2];
2428         c[1] = fb[1];
2429         c[0] = fb[0];
2430         break;
2431      case  nv2a_renderer::XOR:
2432         c[3] = c[3] ^ fb[3];
2433         c[2] = c[2] ^ fb[2];
2434         c[1] = c[1] ^ fb[1];
2435         c[0] = c[0] ^ fb[0];
2436         break;
2437      case  nv2a_renderer::OR:
2438         c[3] = c[3] | fb[3];
2439         c[2] = c[2] | fb[2];
2440         c[1] = c[1] | fb[1];
2441         c[0] = c[0] | fb[0];
2442         break;
2443      case  nv2a_renderer::NOR:
2444         c[3] = (c[3] | fb[3]) ^ 255;
2445         c[2] = (c[2] | fb[2]) ^ 255;
2446         c[1] = (c[1] | fb[1]) ^ 255;
2447         c[0] = (c[0] | fb[0]) ^ 255;
2448         break;
2449      case  nv2a_renderer::EQUIV:
2450         c[3] = (c[3] ^ fb[3]) ^ 255;
2451         c[2] = (c[2] ^ fb[2]) ^ 255;
2452         c[1] = (c[1] ^ fb[1]) ^ 255;
2453         c[0] = (c[0] ^ fb[0]) ^ 255;
2454         break;
2455      case  nv2a_renderer::INVERT:
2456         c[3] = fb[3] ^ 255;
2457         c[2] = fb[2] ^ 255;
2458         c[1] = fb[1] ^ 255;
2459         c[0] = fb[0] ^ 255;
2460         break;
2461      case  nv2a_renderer::OR_REVERSE:
2462         c[3] = c[3] | (fb[3] ^ 255);
2463         c[2] = c[2] | (fb[2] ^ 255);
2464         c[1] = c[1] | (fb[1] ^ 255);
2465         c[0] = c[0] | (fb[0] ^ 255);
2466         break;
2467      case  nv2a_renderer::COPY_INVERTED:
2468         c[3] = c[3] ^ 255;
2469         c[2] = c[2] ^ 255;
2470         c[1] = c[1] ^ 255;
2471         c[0] = c[0] ^ 255;
2472         break;
2473      case  nv2a_renderer::OR_INVERTED:
2474         c[3] = (c[3] ^ 255) | fb[3];
2475         c[2] = (c[2] ^ 255) | fb[2];
2476         c[1] = (c[1] ^ 255) | fb[1];
2477         c[0] = (c[0] ^ 255) | fb[0];
2478         break;
2479      case  nv2a_renderer::NAND:
2480         c[3] = (c[3] & fb[3]) ^ 255;
2481         c[2] = (c[2] & fb[2]) ^ 255;
2482         c[1] = (c[1] & fb[1]) ^ 255;
2483         c[0] = (c[0] & fb[0]) ^ 255;
2484         break;
2485      case  nv2a_renderer::SET:
2486         c[3] = 255;
2487         c[2] = 255;
2488         c[1] = 255;
2489         c[0] = 255;
2490         break;
2491      }
2492   }
2493   fbcolor = (c[3] << 24) | (c[2] << 16) | (c[1] << 8) | c[0];
2494   *((UINT32 *)addr) = fbcolor;
2495}
2496
2497void nv2a_renderer::render_color(INT32 scanline, const extent_t &extent, const nvidia_object_data &objectdata, int threadid)
2498{
2499   int x;
2500
2501   x=extent.stopx-extent.startx-1; // number of pixels to draw
2502   while (x >= 0) {
2503      UINT32 a8r8g8b8;
2504      int ca,cr,cg,cb;
2505      int xp=extent.startx+x; // x coordinate of current pixel
2506
2507      cb=(extent.param[0].start+(float)x*extent.param[0].dpdx);
2508      cg=(extent.param[1].start+(float)x*extent.param[1].dpdx);
2509      cr=(extent.param[2].start+(float)x*extent.param[2].dpdx);
2510      ca=(extent.param[3].start+(float)x*extent.param[3].dpdx);
2511      a8r8g8b8=(ca << 24)+(cr << 16)+(cg << 8)+cb; // pixel color obtained by interpolating the colors of the vertices
2512      write_pixel(xp, scanline, a8r8g8b8);
2513      x--;
2514   }
2515}
2516
2517void nv2a_renderer::render_texture_simple(INT32 scanline, const extent_t &extent, const nvidia_object_data &objectdata, int threadid)
2518{
2519   int x;
2520   UINT32 a8r8g8b8;
2521
2522   if (!objectdata.data->texture[0].enabled) {
2523      return;
2524   }
2525   x=extent.stopx-extent.startx-1;
2526   while (x >= 0) {
2527      int up,vp;
2528      int xp=extent.startx+x; // x coordinate of current pixel
2529
2530      up=(extent.param[4].start+(float)x*extent.param[4].dpdx)*(float)(objectdata.data->texture[0].sizeu-1); // x coordinate of texel in texture
2531      vp=extent.param[5].start*(float)(objectdata.data->texture[0].sizev-1); // y coordinate of texel in texture
2532      a8r8g8b8=texture_get_texel(0, up, vp);
2533      write_pixel(xp, scanline, a8r8g8b8);
2534      x--;
2535   }
2536}
2537
2538void nv2a_renderer::render_register_combiners(INT32 scanline, const extent_t &extent, const nvidia_object_data &objectdata, int threadid)
2539{
2540   int x,xp;
2541   int up,vp;
2542   int ca,cr,cg,cb;
2543   UINT32 color[6];
2544   UINT32 a8r8g8b8;
2545   int n;//,m,i,j,k;
2546
2547   color[0] = color[1] = color[2] = color[3] = color[4] = color[5] = 0;
2548
2549   osd_lock_acquire(combiner.lock); // needed since multithreading is not supported yet
2550   x=extent.stopx-extent.startx-1; // number of pixels to draw
2551   while (x >= 0) {
2552      xp=extent.startx+x;
2553      // 1: fetch data
2554      // 1.1: interpolated color from vertices
2555      cb=(extent.param[0].start+(float)x*extent.param[0].dpdx);
2556      cg=(extent.param[1].start+(float)x*extent.param[1].dpdx);
2557      cr=(extent.param[2].start+(float)x*extent.param[2].dpdx);
2558      ca=(extent.param[3].start+(float)x*extent.param[3].dpdx);
2559      color[0]=(ca << 24)+(cr << 16)+(cg << 8)+cb; // pixel color obtained by interpolating the colors of the vertices
2560      color[1]=0; // lighting not yet
2561      // 1.2: color for each of the 4 possible textures
2562      for (n=0;n < 4;n++) {
2563         if (texture[n].enabled) {
2564            up=(extent.param[4+n*2].start+(float)x*extent.param[4+n*2].dpdx)*(float)(objectdata.data->texture[n].sizeu-1);
2565            vp=extent.param[5+n*2].start*(float)(objectdata.data->texture[n].sizev-1);
2566            color[n+2]=texture_get_texel(n, up, vp);
2567         }
2568      }
2569      // 2: compute
2570      // 2.1: initialize
2571      combiner_initialize_registers(color);
2572      // 2.2: general cmbiner stages
2573      for (n=0;n < combiner.stages;n++) {
2574         // 2.2.1 initialize
2575         combiner_initialize_stage(n);
2576         // 2.2.2 map inputs
2577         combiner_map_input(n);
2578         // 2.2.3 compute possible outputs
2579         combiner_compute_rgb_outputs(n);
2580         combiner_compute_a_outputs(n);
2581         // 2.2.4 map outputs to registers
2582         combiner_map_output(n);
2583      }
2584      // 2.3: final cmbiner stage
2585      combiner_initialize_final();
2586      combiner_map_final_input();
2587      combiner_final_output();
2588      a8r8g8b8=combiner_float_argb8(combiner.output);
2589      // 3: write pixel
2590      write_pixel(xp, scanline, a8r8g8b8);
2591      x--;
2592   }
2593   osd_lock_release(combiner.lock);
2594}
2595
2596#if 0
2597const char *rc_mapping_str[]={
2598   "UNSIGNED_IDENTITY",
2599   "UNSIGNED_INVERT",
2600   "EXPAND_NORMAL",
2601   "EXPAND_NEGATE",
2602   "HALF_BIAS_NORMAL",
2603   "HALF_BIAS_NEGATE",
2604   "SIGNED_IDENTITY",
2605   "SIGNED_NEGATE"
2606};
2607
2608const char *rc_usage_rgb_str[]={
2609   "RGB",
2610   "ALPHA"
2611};
2612
2613const char *rc_usage_alpha_str[]={
2614   "BLUE",
2615   "ALPHA"
2616};
2617
2618const char *rc_variable_str[]={
2619   "ZERO",
2620   "CONSTANT_COLOR0",
2621   "CONSTANT_COLOR1",
2622   "FOG",
2623   "PRIMARY_COLOR",
2624   "SECONDARY_COLOR",
2625   "???",
2626   "???",
2627   "TEXTURE0",
2628   "TEXTURE1",
2629   "TEXTURE2",
2630   "TEXTURE3",
2631   "SPARE0",
2632   "SPARE1",
2633   "SPARE0_PLUS_SECONDARY_COLOR",
2634   "E_TIMES_F"
2635};
2636
2637const char *rc_bias_str[]={
2638   "NONE",
2639   "BIAS_BY_NEGATIVE_ONE_HALF"
2640};
2641
2642const char *rc_scale_str[]={
2643   "NONE",
2644   "SCALE_BY_TWO",
2645   "SCALE_BY_FOUR",
2646   "SCALE_BY_ONE_HALF"
2647};
2648
2649/* Dump the current setup of the register combiners */
2650void dumpcombiners(UINT32 *m)
2651{
2652   int a,b,n,v;
2653
2654   n=m[0x1e60/4] & 0xf;
2655   printf("Combiners active: %d\n\r",n);
2656   for (a=0;a < n;a++) {
2657      printf("Combiner %d\n\r",a+1);
2658      printf(" RC_IN_ALPHA %08X\n\r",m[0x0260/4+a]);
2659      for (b=24;b >= 0;b=b-8) {
2660         v=(m[0x0260/4+a] >> b) & 0xf;
2661         printf("  %c_INPUT %s\n\r",'A'+3-b/8,rc_variable_str[v]);
2662         v=(m[0x0260/4+a] >> (b+4)) & 1;
2663         printf("  %c_COMPONENT_USAGE %s\n\r",'A'+3-b/8,rc_usage_alpha_str[v]);
2664         v=(m[0x0260/4+a] >> (b+5)) & 7;
2665         printf("  %c_MAPPING %s\n\r",'A'+3-b/8,rc_mapping_str[v]);
2666      }
2667      printf(" RC_IN_RGB %08X\n\r",m[0x0ac0/4+a]);
2668      for (b=24;b >= 0;b=b-8) {
2669         v=(m[0x0ac0/4+a] >> b) & 0xf;
2670         printf("  %c_INPUT %s\n\r",'A'+3-b/8,rc_variable_str[v]);
2671         v=(m[0x0ac0/4+a] >> (b+4)) & 1;
2672         printf("  %c_COMPONENT_USAGE %s\n\r",'A'+3-b/8,rc_usage_rgb_str[v]);
2673         v=(m[0x0ac0/4+a] >> (b+5)) & 7;
2674         printf("  %c_MAPPING %s\n\r",'A'+3-b/8,rc_mapping_str[v]);
2675      }
2676      printf(" RC_OUT_ALPHA %08X\n\r",m[0x0aa0/4+a]);
2677      v=m[0x0aa0/4+a] & 0xf;
2678      printf("  CD_OUTPUT %s\n\r",rc_variable_str[v]);
2679      v=(m[0x0aa0/4+a] >> 4) & 0xf;
2680      printf("  AB_OUTPUT %s\n\r",rc_variable_str[v]);
2681      v=(m[0x0aa0/4+a] >> 8) & 0xf;
2682      printf("  SUM_OUTPUT %s\n\r",rc_variable_str[v]);
2683      v=(m[0x0aa0/4+a] >> 12) & 1;
2684      printf("  CD_DOT_PRODUCT %d\n\r",v);
2685      v=(m[0x0aa0/4+a] >> 13) & 1;
2686      printf("  AB_DOT_PRODUCT %d\n\r",v);
2687      v=(m[0x0aa0/4+a] >> 14) & 1;
2688      printf("  MUX_SUM %d\n\r",v);
2689      v=(m[0x0aa0/4+a] >> 15) & 1;
2690      printf("  BIAS %s\n\r",rc_bias_str[v]);
2691      v=(m[0x0aa0/4+a] >> 16) & 3;
2692      printf("  SCALE %s\n\r",rc_scale_str[v]);
2693      //v=(m[0x0aa0/4+a] >> 27) & 7;
2694      printf(" RC_OUT_RGB %08X\n\r",m[0x1e40/4+a]);
2695      v=m[0x1e40/4+a] & 0xf;
2696      printf("  CD_OUTPUT %s\n\r",rc_variable_str[v]);
2697      v=(m[0x1e40/4+a] >> 4) & 0xf;
2698      printf("  AB_OUTPUT %s\n\r",rc_variable_str[v]);
2699      v=(m[0x1e40/4+a] >> 8) & 0xf;
2700      printf("  SUM_OUTPUT %s\n\r",rc_variable_str[v]);
2701      v=(m[0x1e40/4+a] >> 12) & 1;
2702      printf("  CD_DOT_PRODUCT %d\n\r",v);
2703      v=(m[0x1e40/4+a] >> 13) & 1;
2704      printf("  AB_DOT_PRODUCT %d\n\r",v);
2705      v=(m[0x1e40/4+a] >> 14) & 1;
2706      printf("  MUX_SUM %d\n\r",v);
2707      v=(m[0x1e40/4+a] >> 15) & 1;
2708      printf("  BIAS %s\n\r",rc_bias_str[v]);
2709      v=(m[0x1e40/4+a] >> 16) & 3;
2710      printf("  SCALE %s\n\r",rc_scale_str[v]);
2711      //v=(m[0x1e40/4+a] >> 27) & 7;
2712      printf("\n\r");
2713   }
2714   printf("Combiner final %08X %08X\n\r",m[0x0288/4],m[0x028c/4]);
2715   for (a=24;a >= 0;a=a-8) {
2716      n=(m[0x0288/4] >> a) & 0xf;
2717      printf("  %c_INPUT %s\n\r",'A'+3-a/8,rc_variable_str[n]);
2718      n=(m[0x0288/4] >> (a+4)) & 1;
2719      printf("  %c_COMPONENT_USAGE %s\n\r",'A'+3-a/8,rc_usage_rgb_str[n]);
2720      n=(m[0x0288/4] >> (a+5)) & 7;
2721      printf("  %c_MAPPING %s\n\r",'A'+3-a/8,rc_mapping_str[n]);
2722   }
2723   for (a=24;a >= 8;a=a-8) {
2724      n=(m[0x028c/4] >> a) & 0xf;
2725      printf("  %c_INPUT %s\n\r",'E'+3-a/8,rc_variable_str[n]);
2726      n=(m[0x028c/4] >> (a+4)) & 1;
2727      printf("  %c_COMPONENT_USAGE %s\n\r",'E'+3-a/8,rc_usage_rgb_str[n]);
2728      n=(m[0x028c/4] >> (a+5)) & 7;
2729      printf("  %c_MAPPING %s\n\r",'E'+3-a/8,rc_mapping_str[n]);
2730   }
2731   n=(m[0x028c/4] >> 7) & 1;
2732   printf(" color sum clamp: %d\n\r",n);
2733}
2734#endif
2735
2736/* Read vertices data from system memory. Method 0x1810 */
2737int nv2a_renderer::read_vertices_0x1810(address_space & space, vertex *destination, int offset, int limit)
2738{
2739   UINT32 m, u;
2740
2741   for (m = 0; m < limit; m++) {
2742      destination[m].attribute[0].iv[0] = space.read_dword(vertexbuffer_address[0] + (m + offset)*vertexbuffer_stride[0] + 0);
2743      destination[m].attribute[0].iv[1] = space.read_dword(vertexbuffer_address[0] + (m + offset)*vertexbuffer_stride[0] + 4);
2744      destination[m].attribute[0].iv[2] = space.read_dword(vertexbuffer_address[0] + (m + offset)*vertexbuffer_stride[0] + 8);
2745      destination[m].attribute[0].iv[3] = space.read_dword(vertexbuffer_address[0] + (m + offset)*vertexbuffer_stride[0] + 12);
2746      destination[m].attribute[3].iv[0] = space.read_dword(vertexbuffer_address[3] + (m + offset)*vertexbuffer_stride[3] + 0); // color
2747      for (u = 0; u < 4; u++) {
2748         destination[m].attribute[9 + u].iv[0] = space.read_dword(vertexbuffer_address[9 + u] + (m + offset)*vertexbuffer_stride[9 + u] + 0);
2749         destination[m].attribute[9 + u].iv[1] = space.read_dword(vertexbuffer_address[9 + u] + (m + offset)*vertexbuffer_stride[9 + u] + 4);
2750      }
2751   }
2752   return m;
2753}
2754
2755/* Read vertices data from system memory. Method 0x1800 */
2756int nv2a_renderer::read_vertices_0x1800(address_space & space, vertex *destination, UINT32 address, int limit)
2757{
2758   UINT32 data;
2759   UINT32 m, u, i, c;
2760
2761   c = 0;
2762   for (m = 0; m < limit; m++) {
2763      if (indexesleft_count == 0) {
2764         data = space.read_dword(address);
2765         i = (indexesleft_first + indexesleft_count) & 7;
2766         indexesleft[i] = data & 0xffff;
2767         indexesleft[(i + 1) & 7] = (data >> 16) & 0xffff;
2768         indexesleft_count = indexesleft_count + 2;
2769         address += 4;
2770         c++;
2771      }
2772      destination[m].attribute[0].iv[0] = space.read_dword(vertexbuffer_address[0] + indexesleft[indexesleft_first] * vertexbuffer_stride[0] + 0);
2773      destination[m].attribute[0].iv[1] = space.read_dword(vertexbuffer_address[0] + indexesleft[indexesleft_first] * vertexbuffer_stride[0] + 4);
2774      destination[m].attribute[0].iv[2] = space.read_dword(vertexbuffer_address[0] + indexesleft[indexesleft_first] * vertexbuffer_stride[0] + 8);
2775      destination[m].attribute[0].iv[3] = space.read_dword(vertexbuffer_address[0] + indexesleft[indexesleft_first] * vertexbuffer_stride[0] + 12);
2776      destination[m].attribute[3].iv[0] = space.read_dword(vertexbuffer_address[3] + indexesleft[indexesleft_first] * vertexbuffer_stride[3] + 0); // color
2777      for (u = 0; u < 4; u++) {
2778         destination[m].attribute[9 + u].iv[0] = space.read_dword(vertexbuffer_address[9 + u] + indexesleft[indexesleft_first] * vertexbuffer_stride[9 + u] + 0);
2779         destination[m].attribute[9 + u].iv[1] = space.read_dword(vertexbuffer_address[9 + u] + indexesleft[indexesleft_first] * vertexbuffer_stride[9 + u] + 4);
2780      }
2781      indexesleft_first = (indexesleft_first + 1) & 7;
2782      indexesleft_count--;
2783   }
2784   return (int)c;
2785}
2786
2787/* Read vertices data from system memory. Method 0x1818 */
2788int nv2a_renderer::read_vertices_0x1818(address_space & space, vertex *destination, UINT32 address, int limit)
2789{
2790   UINT32 m, u, vwords;
2791
2792   vwords = vertex_attribute_words[15] + vertex_attribute_offset[15];
2793   for (m = 0; m < limit; m++) {
2794      destination[m].attribute[0].iv[0] = space.read_dword(address + vertex_attribute_offset[0] * 4 + 0);
2795      destination[m].attribute[0].iv[1] = space.read_dword(address + vertex_attribute_offset[0] * 4 + 4);
2796      destination[m].attribute[0].iv[2] = space.read_dword(address + vertex_attribute_offset[0] * 4 + 8);
2797      destination[m].attribute[0].iv[3] = space.read_dword(address + vertex_attribute_offset[0] * 4 + 12);
2798      destination[m].attribute[3].iv[0] = space.read_dword(address + vertex_attribute_offset[3] * 4 + 0); // color
2799      for (u = 0; u < 4; u++) {
2800         destination[m].attribute[9 + u].iv[0] = space.read_dword(address + vertex_attribute_offset[9 + u] * 4 + 0);
2801         destination[m].attribute[9 + u].iv[1] = space.read_dword(address + vertex_attribute_offset[9 + u] * 4 + 4);
2802      }
2803      address = address + vwords * 4;
2804   }
2805   return (int)(m*vwords);
2806}
2807
2808void nv2a_renderer::convert_vertices_poly(vertex *source, vertex_t *destination, int count)
2809{
2810   int m, u;
2811
2812   for (m = 0; m < count; m++) {
2813      destination[m].x = source[m].attribute[0].fv[0];
2814      destination[m].y = source[m].attribute[0].fv[1];
2815      u = source[m].attribute[3].iv[0];
2816      destination[m].p[0] = u & 0xff; // b
2817      destination[m].p[1] = (u & 0xff00) >> 8;  // g
2818      destination[m].p[2] = (u & 0xff0000) >> 16;  // r
2819      destination[m].p[3] = (u & 0xff000000) >> 24;  // a
2820      for (u = 0; u < 4; u++) {
2821         destination[m].p[4 + u * 2] = 0;
2822         destination[m].p[5 + u * 2] = 0;
2823         if (texture[u].enabled) {
2824            destination[m].p[4 + u * 2] = source[m].attribute[9 + u].fv[0];
2825            destination[m].p[5 + u * 2] = source[m].attribute[9 + u].fv[1];
2826         }
2827      }
2828   }
2829}
2830
2831void nv2a_renderer::geforce_exec_method(address_space & space,UINT32 chanel,UINT32 subchannel,UINT32 method,UINT32 address,int &countlen)
2832{
2833   UINT32 maddress;
2834   UINT32 data;
2835
2836   maddress=method*4;
2837   data=space.read_dword(address);
2838   channel[chanel][subchannel].object.method[method]=data;
2839   if (maddress == 0x17fc) {
2840      indexesleft_count = 0;
2841      indexesleft_first = 0;
2842      primitives_count = 0;
2843      countlen--;
2844   }
2845   if (maddress == 0x1810) {
2846      // draw vertices
2847      int offset,count,type;
2848      UINT32 n;
2849      render_delegate renderspans;
2850
2851      offset=data & 0xffffff;
2852      count=(data >> 24) & 0xff;
2853      type=channel[chanel][subchannel].object.method[0x17fc/4];
2854      if (((channel[chanel][subchannel].object.method[0x1e60/4] & 7) > 0) && (combiner.used != 0)) {
2855         renderspans=render_delegate(FUNC(nv2a_renderer::render_register_combiners),this);
2856      } else if (texture[0].enabled) {
2857         renderspans=render_delegate(FUNC(nv2a_renderer::render_texture_simple),this);
2858      } else
2859         renderspans=render_delegate(FUNC(nv2a_renderer::render_color),this);
2860#ifdef LOG_NV2A
2861      printf("vertex %d %d %d\n\r",type,offset,count);
2862#endif
2863      if (type == nv2a_renderer::QUADS) {
2864         for (n = 0; n <= count; n += 4) {
2865            vertex vert[4];
2866            vertex_t xy[4];
2867
2868            read_vertices_0x1810(space, vert, n+offset, 4);
2869            convert_vertices_poly(vert, xy, 4);
2870            render_polygon<4>(fb.cliprect(), renderspans, 4 + 4 * 2, xy); // 4 rgba, 4 texture units 2 uv
2871         }
2872         wait();
2873      } else if (type == nv2a_renderer::TRIANGLE_STRIP) {
2874         vertex vert[4];
2875         vertex_t xy[4];
2876
2877         read_vertices_0x1810(space, vert, offset, 2);
2878         convert_vertices_poly(vert, xy, 2);
2879         count = count - 2;
2880         offset = offset + 2;
2881         for (n = 0; n <= count; n++) {
2882            read_vertices_0x1810(space, vert + ((n+2) & 3), offset + n, 1);
2883            convert_vertices_poly(vert + ((n + 2) & 3), xy + ((n + 2) & 3), 1);
2884            render_triangle(fb.cliprect(), renderspans, 4 + 4 * 2, xy[((n & 1)+n) & 3], xy[((~n & 1)+n) & 3], xy[(2+n) & 3]);
2885         }
2886         wait();
2887      } else {
2888         logerror("Unsupported primitive %d for method 0x1810\n",type);
2889      }
2890      countlen--;
2891   }
2892   if (maddress == 0x1800) {
2893      UINT32 type, n;
2894      render_delegate renderspans;
2895
2896      // vertices are selected from the vertex buffer using an array of indexes
2897      // each dword after 1800 contains two 16 bit index values to select the vartices
2898      type = channel[chanel][subchannel].object.method[0x17fc / 4];
2899      if (((channel[chanel][subchannel].object.method[0x1e60 / 4] & 7) > 0) && (combiner.used != 0)) {
2900         renderspans = render_delegate(FUNC(nv2a_renderer::render_register_combiners), this);
2901      }
2902      else if (texture[0].enabled) {
2903         renderspans = render_delegate(FUNC(nv2a_renderer::render_texture_simple), this);
2904      }
2905      else
2906         renderspans = render_delegate(FUNC(nv2a_renderer::render_color), this);
2907#ifdef LOG_NV2A
2908      printf("vertex %d %d %d\n\r", type, offset, count);
2909#endif
2910      if (type == nv2a_renderer::QUADS) {
2911         while (1) {
2912            vertex vert[4];
2913            vertex_t xy[4];
2914            int c;
2915
2916            if ((countlen * 2 + indexesleft_count) < 4)
2917               break;
2918            c=read_vertices_0x1800(space, vert, address, 4);
2919            address = address + c*4;
2920            countlen = countlen - c;
2921            convert_vertices_poly(vert, xy, 4);
2922            render_polygon<4>(fb.cliprect(), renderspans, 4 + 4 * 2, xy); // 4 rgba, 4 texture units 2 uv
2923         }
2924         while (countlen > 0) {
2925            data = space.read_dword(address);
2926            n = (indexesleft_first + indexesleft_count) & 7;
2927            indexesleft[n] = data & 0xffff;
2928            indexesleft[(n + 1) & 7] = (data >> 16) & 0xffff;
2929            indexesleft_count = indexesleft_count + 2;
2930            address += 4;
2931            countlen--;
2932         }
2933         wait();
2934      }
2935      else if (type == nv2a_renderer::TRIANGLES) {
2936         while (1) {
2937            vertex vert[3];
2938            vertex_t xy[3];
2939            int c;
2940
2941            if ((countlen * 2 + indexesleft_count) < 3)
2942               break;
2943            c = read_vertices_0x1800(space, vert, address, 3);
2944            address = address + c * 4;
2945            countlen = countlen - c;
2946            convert_vertices_poly(vert, xy, 3);
2947            render_triangle(fb.cliprect(), renderspans, 4 + 4 * 2, xy[0], xy[1], xy[2]); // 4 rgba, 4 texture units 2 uv
2948         }
2949         while (countlen > 0) {
2950            data = space.read_dword(address);
2951            n = (indexesleft_first + indexesleft_count) & 7;
2952            indexesleft[n] = data & 0xffff;
2953            indexesleft[(n + 1) & 7] = (data >> 16) & 0xffff;
2954            indexesleft_count = indexesleft_count + 2;
2955            address += 4;
2956            countlen--;
2957         }
2958         wait();
2959      }
2960      else if (type == nv2a_renderer::TRIANGLE_STRIP) {
2961         if ((countlen * 2 + indexesleft_count) >= 3) {
2962            vertex vert[4];
2963            vertex_t xy[4];
2964            int c, count;
2965
2966            c = read_vertices_0x1800(space, vert, address, 2);
2967            convert_vertices_poly(vert, xy, 2);
2968            address = address + c * 4;
2969            countlen = countlen - c;
2970            count = countlen * 2 + indexesleft_count;
2971            for (n = 0; n < count; n++) { // <=
2972               c = read_vertices_0x1800(space, vert + ((n + 2) & 3), address, 1);
2973               address = address + c * 4;
2974               countlen = countlen - c;
2975               convert_vertices_poly(vert + ((n + 2) & 3), xy + ((n + 2) & 3), 1);
2976               render_triangle(fb.cliprect(), renderspans, 4 + 4 * 2, xy[((n & 1) + n) & 3], xy[((~n & 1) + n) & 3], xy[(2 + n) & 3]);
2977            }
2978         }
2979         while (countlen > 0) {
2980            data = space.read_dword(address);
2981            n = (indexesleft_first + indexesleft_count) & 7;
2982            indexesleft[n] = data & 0xffff;
2983            indexesleft[(n + 1) & 7] = (data >> 16) & 0xffff;
2984            indexesleft_count = indexesleft_count + 2;
2985            address += 4;
2986            countlen--;
2987         }
2988         wait();
2989      }
2990      else {
2991         logerror("Unsupported primitive %d for method 0x1800\n", type);
2992         countlen = 0;
2993      }
2994   }
2995   if (maddress == 0x1818) {
2996      int n;
2997      int type;
2998      render_delegate renderspans;
2999
3000      if (((channel[chanel][subchannel].object.method[0x1e60/4] & 7) > 0) && (combiner.used != 0)) {
3001         renderspans=render_delegate(FUNC(nv2a_renderer::render_register_combiners),this);
3002      } else if (texture[0].enabled) {
3003         renderspans=render_delegate(FUNC(nv2a_renderer::render_texture_simple),this);
3004      } else
3005         renderspans=render_delegate(FUNC(nv2a_renderer::render_color),this);
3006      // vertices are taken from the next words, not from a vertex buffer
3007      // first send primitive type with 17fc
3008      // then countlen number of dwords with 1818
3009      // end with 17fc primitive type 0
3010      // at 1760 16 words specify the vertex format:for each possible vertex attribute the number of components (0=not present) and type of each
3011      type=channel[chanel][subchannel].object.method[0x17fc/4];
3012      if (type == nv2a_renderer::TRIANGLE_FAN) {
3013         vertex vert[3];
3014         vertex_t xy[3];
3015         int c;
3016
3017         c=read_vertices_0x1818(space, vert, address, 2);
3018         convert_vertices_poly(vert, xy, 2);
3019         countlen = countlen - c;
3020         if (countlen < 0) {
3021            logerror("Method 0x1818 missing %d words to draw a complete primitive\n", -countlen);
3022            countlen = 0;
3023            return;
3024         }
3025         address = address + c * 4;
3026         for (n = 1; countlen > 0; n++) {
3027            c=read_vertices_0x1818(space, vert + ((n & 1) + 1), address, 1);
3028            countlen = countlen - c;
3029            if (countlen < 0) {
3030               logerror("Method 0x1818 missing %d words to draw a complete primitive\n", -countlen);
3031               countlen = 0;
3032               break;
3033            }
3034            address = address + c * 4;
3035            convert_vertices_poly(vert + ((n & 1) + 1), xy + ((n & 1) + 1), 1);
3036            render_triangle(fb.cliprect(), renderspans, 4 + 4 * 2, xy[0], xy[(~n & 1) + 1], xy[(n & 1) + 1]);
3037         }
3038         wait();
3039      } else if (type == nv2a_renderer::TRIANGLE_STRIP) {
3040         vertex vert[4];
3041         vertex_t xy[4];
3042         int c;
3043
3044         c=read_vertices_0x1818(space, vert, address, 2);
3045         convert_vertices_poly(vert, xy, 2);
3046         countlen = countlen - c;
3047         if (countlen < 0) {
3048            logerror("Method 0x1818 missing %d words to draw a complete primitive\n", -countlen);
3049            countlen = 0;
3050            return;
3051         }
3052         address = address + c * 4;
3053         for (n = 0;countlen > 0; n++) {
3054            c=read_vertices_0x1818(space, vert + ((n + 2) & 3), address, 1);
3055            convert_vertices_poly(vert + ((n + 2) & 3), xy + ((n + 2) & 3), 1);
3056            countlen = countlen - c;
3057            if (countlen < 0) {
3058               logerror("Method 0x1818 missing %d words to draw a complete primitive\n", -countlen);
3059               countlen = 0;
3060               break;
3061            }
3062            address = address + c * 4;
3063            render_triangle(fb.cliprect(), renderspans, 4 + 4 * 2, xy[((n & 1) + n) & 3], xy[((~n & 1) + n) & 3], xy[(2 + n) & 3]);
3064         }
3065         wait();
3066      } else if (type == nv2a_renderer::QUADS) {
3067         while (countlen > 0) {
3068            vertex vert[4];
3069            vertex_t xy[4];
3070            int c;
3071
3072            c = read_vertices_0x1818(space, vert, address, 4);
3073            convert_vertices_poly(vert, xy, 4);
3074            countlen = countlen - c;
3075            if (countlen < 0) {
3076               logerror("Method 0x1818 missing %d words to draw a complete primitive\n", -countlen);
3077               countlen = 0;
3078               break;
3079            }
3080            address = address + c * 4;
3081            render_polygon<4>(fb.cliprect(), renderspans, 4 + 4 * 2, xy); // 4 rgba, 4 texture units 2 uv
3082         }
3083         wait();
3084      } else if (type == nv2a_renderer::QUAD_STRIP) {
3085         vertex vert[4];
3086         vertex_t xy[4];
3087         int c;
3088
3089         c=read_vertices_0x1818(space, vert, address, 2);
3090         convert_vertices_poly(vert, xy, 2);
3091         countlen = countlen - c;
3092         if (countlen < 0) {
3093            logerror("Method 0x1818 missing %d words to draw a complete primitive\n", -countlen);
3094            countlen = 0;
3095            return;
3096         }
3097         address = address + c * 4;
3098         for (n = 0; countlen > 0; n+=2) {
3099            c = read_vertices_0x1818(space, vert + ((n + 2) & 3), address + ((n + 2) & 3), 2);
3100            convert_vertices_poly(vert + ((n + 2) & 3), xy + ((n + 2) & 3), 2);
3101            countlen = countlen - c;
3102            if (countlen < 0) {
3103               logerror("Method 0x1818 missing %d words to draw a complete primitive\n", -countlen);
3104               countlen = 0;
3105               return;
3106            }
3107            address = address + c * 4;
3108            render_triangle(fb.cliprect(), renderspans, 4 + 4 * 2, xy[n & 3], xy[(n + 1) & 3], xy[(n + 2) & 3]);
3109            render_triangle(fb.cliprect(), renderspans, 4 + 4 * 2, xy[(n + 2) & 3], xy[(n + 1) & 3], xy[(n + 3) & 3]);
3110         }
3111         wait();
3112      } else {
3113         logerror("Unsupported primitive %d for method 0x1818\n",type);
3114         countlen = 0;
3115      }
3116   }
3117   if ((maddress >= 0x1720) && (maddress < 0x1760)) {
3118      int bit = method - 0x1720 / 4;
3119
3120      if (data & 0x80000000)
3121         vertexbuffer_address[bit] = (data & 0x0fffffff) + dma_offset[1];
3122      else
3123         vertexbuffer_address[bit] = (data & 0x0fffffff) + dma_offset[0];
3124   }
3125   if ((maddress >= 0x1760) && (maddress < 0x17A0)) {
3126      int bit=method-0x1760/4;
3127
3128      vertexbuffer_stride[bit] = (data >> 8) & 255;
3129      //vertexbuffer_kind[n]=tmp & 15;
3130      //vertexbuffer_size[n]=(tmp >> 4) & 15;
3131      data = data & 255;
3132      switch (data & 15) {
3133         case 0:
3134            vertex_attribute_words[bit]=(((data >> 4) + 3) & 15) >> 2;
3135            break;
3136         case nv2a_renderer::FLOAT:
3137            vertex_attribute_words[bit]=(data >> 4);
3138            break;
3139         case nv2a_renderer::UBYTE:
3140            vertex_attribute_words[bit]=(((data >> 4) + 3) & 15) >> 2;
3141            break;
3142         case nv2a_renderer::USHORT:
3143            vertex_attribute_words[bit]=(((data >> 4) + 1) & 15) >> 1;
3144            break;
3145         default:
3146            vertex_attribute_words[bit]=0;
3147      }
3148      if (data > 15)
3149         enabled_vertex_attributes |= (1 << bit);
3150      else
3151         enabled_vertex_attributes &= ~(1 << bit);
3152      for (int n = bit+1; n < 16; n++) {
3153         if ((enabled_vertex_attributes & (1 << (n - 1))) != 0)
3154            vertex_attribute_offset[n] = vertex_attribute_offset[n - 1] + vertex_attribute_words[n - 1];
3155         else
3156            vertex_attribute_offset[n] = vertex_attribute_offset[n - 1];
3157      }
3158      countlen--;
3159   }
3160   if ((maddress == 0x1d6c) || (maddress == 0x1d70) || (maddress == 0x1a4))
3161      countlen--;
3162   if (maddress == 0x019c) {
3163      geforce_read_dma_object(data, dma_offset[0], dma_size[0]);
3164   }
3165   if (maddress == 0x01a0) {
3166      geforce_read_dma_object(data, dma_offset[1], dma_size[1]);
3167   }
3168   if (maddress == 0x1d70) {
3169      // with 1d70 write the value at offest [1d6c] inside dma object [1a4]
3170      UINT32 offset,base;
3171      UINT32 dmahand,dmaoff,smasiz;
3172
3173      offset=channel[chanel][subchannel].object.method[0x1d6c/4];
3174      dmahand=channel[chanel][subchannel].object.method[0x1a4/4];
3175      geforce_read_dma_object(dmahand,dmaoff,smasiz);
3176      base=dmaoff;
3177      space.write_dword(base+offset,data);
3178      countlen--;
3179   }
3180   if (maddress == 0x1d94) {
3181      // possible buffers: color, depth, stencil, and accumulation
3182      // clear framebuffer
3183      if (data & 0xf0) {
3184         // clear colors
3185         UINT32 color=channel[chanel][subchannel].object.method[0x1d90/4];
3186         fb.fill(color);
3187         //printf("clearscreen\n\r");
3188      }
3189      if (data & 0x03) {
3190         // clear stencil+zbuffer
3191      }
3192      countlen--;
3193   }
3194   if (maddress == 0x0300) {
3195      alpha_test_enabled = data != 0;
3196   }
3197   if (maddress == 0x033c) {
3198      alpha_func = data;
3199   }
3200   if (maddress == 0x0340) {
3201      alpha_reference = data;
3202   }
3203   if (maddress == 0x0304) {
3204      if (logical_operation_enabled)
3205         blending_enabled = false;
3206      else
3207         blending_enabled = data != 0;
3208   }
3209   if (maddress == 0x0344) {
3210      blend_function_source = data;
3211   }
3212   if (maddress == 0x0348) {
3213      blend_function_destination = data;
3214   }
3215   if (maddress == 0x034c) {
3216      blend_color = data;
3217   }
3218   if (maddress == 0x0350) {
3219      blend_equation = data;
3220   }
3221   if (maddress == 0x0d40) {
3222      if (data != 0)
3223         blending_enabled = false;
3224      else
3225         blending_enabled = channel[chanel][subchannel].object.method[0x0304 / 4] != 0;
3226      logical_operation_enabled = data != 0;
3227   }
3228   if (maddress == 0x0d44) {
3229      logical_operation = data;
3230   }
3231   // Texture Units
3232   if ((maddress >= 0x1b00) && (maddress < 0x1c00)) {
3233      int unit;//,off;
3234
3235      unit=(maddress >> 6) & 3;
3236      //off=maddress & 0xc0;
3237      maddress=maddress & ~0xc0;
3238      if (maddress == 0x1b00) {
3239         UINT32 offset;//,base;
3240         //UINT32 dmahand,dmaoff,dmasiz;
3241
3242         offset=data;
3243         texture[unit].buffer=space.get_read_ptr(offset);
3244         /*if (dma0 != 0) {
3245             dmahand=channel[channel][subchannel].object.method[0x184/4];
3246             geforce_read_dma_object(dmahand,dmaoff,smasiz);
3247         } else if (dma1 != 0) {
3248             dmahand=channel[channel][subchannel].object.method[0x188/4];
3249             geforce_read_dma_object(dmahand,dmaoff,smasiz);
3250         }*/
3251      }
3252      if (maddress == 0x1b04) {
3253         //int dma0,dma1,cubic,noborder,dims,mipmap;
3254         int basesizeu,basesizev,basesizew,format;
3255
3256         //dma0=(data >> 0) & 1;
3257         //dma1=(data >> 1) & 1;
3258         //cubic=(data >> 2) & 1;
3259         //noborder=(data >> 3) & 1;
3260         //dims=(data >> 4) & 15;
3261         //mipmap=(data >> 19) & 1;
3262         format=(data >> 8) & 255;
3263         basesizeu=(data >> 20) & 15;
3264         basesizev=(data >> 24) & 15;
3265         basesizew=(data >> 28) & 15;
3266         texture[unit].sizeu=1 << basesizeu;
3267         texture[unit].sizev=1 << basesizev;
3268         texture[unit].sizew=1 << basesizew;
3269         texture[unit].dilate=dilatechose[(basesizeu << 4)+basesizev];
3270         texture[unit].format=format;
3271         if (debug_grab_texttype == format) {
3272            FILE *f;
3273            int written;
3274
3275            debug_grab_texttype = -1;
3276            f = fopen(debug_grab_textfile, "wb");
3277            if (f) {
3278               written=(int)fwrite(texture[unit].buffer, texture[unit].sizeu*texture[unit].sizev*4, 1, f);
3279               fclose(f);
3280               logerror("Written %d bytes of texture to specified file\n", written);
3281            } else
3282               logerror("Unable to save texture to specified file\n");
3283         }
3284      }
3285      if (maddress == 0x1b0c) {
3286         // enable texture
3287         int enable;
3288
3289         enable=(data >> 30) & 1;
3290         texture[unit].enabled=enable;
3291      }
3292      if (maddress == 0x1b10) {
3293         texture[unit].rectangle_pitch=data >> 16;
3294      }
3295      countlen--;
3296   }
3297   // modelview matrix
3298   if ((maddress >= 0x0480) && (maddress < 0x04c0)) {
3299      maddress = (maddress - 0x0480) / 4;
3300      *(UINT32 *)(&matrix.modelview[maddress]) = data;
3301      countlen--;
3302   }
3303   // inverse modelview matrix
3304   if ((maddress >= 0x0580) && (maddress < 0x05c0)) {
3305      maddress = (maddress - 0x0580) / 4;
3306      *(UINT32 *)(&matrix.modelview_inverse[maddress]) = data;
3307      countlen--;
3308   }
3309   // projection matrix
3310   if ((maddress >= 0x0680) && (maddress < 0x06c0)) {
3311      maddress = (maddress - 0x0680) / 4;
3312      *(UINT32 *)(&matrix.projection[maddress]) = data;
3313      countlen--;
3314   }
3315   // viewport translate
3316   if ((maddress >= 0x0a20) && (maddress < 0x0a30)) {
3317      maddress = (maddress - 0x0a20) / 4;
3318      *(UINT32 *)(&matrix.translate[maddress]) = data;
3319      countlen--;
3320   }
3321   // viewport scale
3322   if ((maddress >= 0x0af0) && (maddress < 0x0b00)) {
3323      maddress = (maddress - 0x0af0) / 4;
3324      *(UINT32 *)(&matrix.scale[maddress]) = data;
3325      countlen--;
3326   }
3327   // Vertex program (shader)
3328   if (maddress == 0x1e94) {
3329      /*if (data == 2)
3330          logerror("Enabled vertex program\n");
3331      else if (data == 4)
3332          logerror("Enabled fixed function pipeline\n");
3333      else if (data == 6)
3334          logerror("Enabled both fixed function pipeline and vertex program ?\n");
3335      else
3336          logerror("Unknown value %d to method 0x1e94\n",data);*/
3337      vertex_pipeline = data & 6;
3338      countlen--;
3339   }
3340   if (maddress == 0x1e9c) {
3341      //logerror("VP_UPLOAD_FROM_ID %d\n",data);
3342      vertexprogram.upload_instruction=data*4;
3343      countlen--;
3344   }
3345   if (maddress == 0x1ea0) {
3346      //logerror("VP_START_FROM_ID %d\n",data);
3347      vertexprogram.instructions=vertexprogram.upload_instruction/4;
3348      vertexprogram.start_instruction = data * 4;
3349      countlen--;
3350   }
3351   if (maddress == 0x1ea4) {
3352      //logerror("VP_UPLOAD_CONST_ID %d\n",data);
3353      vertexprogram.upload_parameter=data*4;
3354      countlen--;
3355   }
3356   if ((maddress >= 0x0b00) && (maddress < 0x0b80)) {
3357      //logerror("VP_UPLOAD_INST\n");
3358      if (vertexprogram.upload_instruction < 1024)
3359         vertexprogram.instruction[vertexprogram.upload_instruction]=data;
3360      else
3361         logerror("Need to increase size of vertexprogram.instruction to %d\n\r", vertexprogram.upload_parameter);
3362      vertexprogram.upload_instruction++;
3363   }
3364   if ((maddress >= 0x0b80) && (maddress < 0x0c00)) {
3365      //logerror("VP_UPLOAD_CONST\n");
3366      if (vertexprogram.upload_parameter < 1024)
3367         *(UINT32 *)(&vertexprogram.parameter[vertexprogram.upload_parameter]) = data;
3368      else
3369         logerror("Need to increase size of vertexprogram.parameter to %d\n\r", vertexprogram.upload_parameter);
3370      vertexprogram.upload_parameter++;
3371   }
3372   // Register combiners
3373   if (maddress == 0x1e60) {
3374      combiner.stages=data & 15;
3375      countlen--;
3376   }
3377   if (maddress == 0x0288) {
3378      combiner.final.mapin_rgbD_input=data & 15;
3379      combiner.final.mapin_rgbD_component=(data >> 4) & 1;
3380      combiner.final.mapin_rgbD_mapping=(data >> 5) & 7;
3381      combiner.final.mapin_rgbC_input=(data >> 8) & 15;
3382      combiner.final.mapin_rgbC_component=(data >> 12) & 1;
3383      combiner.final.mapin_rgbC_mapping=(data >> 13) & 7;
3384      combiner.final.mapin_rgbB_input=(data >> 16) & 15;
3385      combiner.final.mapin_rgbB_component=(data >> 20) & 1;
3386      combiner.final.mapin_rgbB_mapping=(data >> 21) & 7;
3387      combiner.final.mapin_rgbA_input=(data >> 24) & 15;
3388      combiner.final.mapin_rgbA_component=(data >> 28) & 1;
3389      combiner.final.mapin_rgbA_mapping=(data >> 29) & 7;
3390      countlen--;
3391   }
3392   if (maddress == 0x028c) {
3393      combiner.final.color_sum_clamp=(data >> 7) & 1;
3394      combiner.final.mapin_aG_input=(data >> 8) & 15;
3395      combiner.final.mapin_aG_component=(data >> 12) & 1;
3396      combiner.final.mapin_aG_mapping=(data >> 13) & 7;
3397      combiner.final.mapin_rgbF_input=(data >> 16) & 15;
3398      combiner.final.mapin_rgbF_component=(data >> 20) & 1;
3399      combiner.final.mapin_rgbF_mapping=(data >> 21) & 7;
3400      combiner.final.mapin_rgbE_input=(data >> 24) & 15;
3401      combiner.final.mapin_rgbE_component=(data >> 28) & 1;
3402      combiner.final.mapin_rgbE_mapping=(data >> 29) & 7;
3403      countlen--;
3404   }
3405   if (maddress == 0x1e20) {
3406      combiner_argb8_float(data,combiner.final.register_constantcolor0);
3407      countlen--;
3408   }
3409   if (maddress == 0x1e24) {
3410      combiner_argb8_float(data,combiner.final.register_constantcolor1);
3411      countlen--;
3412   }
3413   if ((maddress >= 0x0260) && (maddress < 0x0280)) {
3414      int n;
3415
3416      n=(maddress-0x0260) >> 2;
3417      combiner.stage[n].mapin_aD_input=data & 15;
3418      combiner.stage[n].mapin_aD_component=(data >> 4) & 1;
3419      combiner.stage[n].mapin_aD_mapping=(data >> 5) & 7;
3420      combiner.stage[n].mapin_aC_input=(data >> 8) & 15;
3421      combiner.stage[n].mapin_aC_component=(data >> 12) & 1;
3422      combiner.stage[n].mapin_aC_mapping=(data >> 13) & 7;
3423      combiner.stage[n].mapin_aB_input=(data >> 16) & 15;
3424      combiner.stage[n].mapin_aB_component=(data >> 20) & 1;
3425      combiner.stage[n].mapin_aB_mapping=(data >> 21) & 7;
3426      combiner.stage[n].mapin_aA_input=(data >> 24) & 15;
3427      combiner.stage[n].mapin_aA_component=(data >> 28) & 1;
3428      combiner.stage[n].mapin_aA_mapping=(data >> 29) & 7;
3429      countlen--;
3430   }
3431   if ((maddress >= 0x0ac0) && (maddress < 0x0ae0)) {
3432      int n;
3433
3434      n=(maddress-0x0ac0) >> 2;
3435      combiner.stage[n].mapin_rgbD_input=data & 15;
3436      combiner.stage[n].mapin_rgbD_component=(data >> 4) & 1;
3437      combiner.stage[n].mapin_rgbD_mapping=(data >> 5) & 7;
3438      combiner.stage[n].mapin_rgbC_input=(data >> 8) & 15;
3439      combiner.stage[n].mapin_rgbC_component=(data >> 12) & 1;
3440      combiner.stage[n].mapin_rgbC_mapping=(data >> 13) & 7;
3441      combiner.stage[n].mapin_rgbB_input=(data >> 16) & 15;
3442      combiner.stage[n].mapin_rgbB_component=(data >> 20) & 1;
3443      combiner.stage[n].mapin_rgbB_mapping=(data >> 21) & 7;
3444      combiner.stage[n].mapin_rgbA_input=(data >> 24) & 15;
3445      combiner.stage[n].mapin_rgbA_component=(data >> 28) & 1;
3446      combiner.stage[n].mapin_rgbA_mapping=(data >> 29) & 7;
3447      countlen--;
3448   }
3449   if ((maddress >= 0x0a60) && (maddress < 0x0a80)) {
3450      int n;
3451
3452      n=(maddress-0x0a60) >> 2;
3453      combiner_argb8_float(data,combiner.stage[n].register_constantcolor0);
3454      countlen--;
3455   }
3456   if ((maddress >= 0x0a80) && (maddress < 0x0aa0)) {
3457      int n;
3458
3459      n=(maddress-0x0a80) >> 2;
3460      combiner_argb8_float(data,combiner.stage[n].register_constantcolor1);
3461      countlen--;
3462   }
3463   if ((maddress >= 0x0aa0) && (maddress < 0x0ac0)) {
3464      int n;
3465
3466      n=(maddress-0x0aa0) >> 2;
3467      combiner.stage[n].mapout_aCD_output=data & 15;
3468      combiner.stage[n].mapout_aAB_output=(data >> 4) & 15;
3469      combiner.stage[n].mapout_aSUM_output=(data >> 8) & 15;
3470      combiner.stage[n].mapout_aCD_dotproduct=(data >> 12) & 1;
3471      combiner.stage[n].mapout_aAB_dotproduct=(data >> 13) & 1;
3472      combiner.stage[n].mapout_a_muxsum=(data >> 14) & 1;
3473      combiner.stage[n].mapout_a_bias=(data >> 15) & 1;
3474      combiner.stage[n].mapout_a_scale=(data >> 16) & 3;
3475      //combiner.=(data >> 27) & 7;
3476      countlen--;
3477   }
3478   if ((maddress >= 0x1e40) && (maddress < 0x1e60)) {
3479      int n;
3480
3481      n=(maddress-0x1e40) >> 2;
3482      combiner.stage[n].mapout_rgbCD_output=data & 15;
3483      combiner.stage[n].mapout_rgbAB_output=(data >> 4) & 15;
3484      combiner.stage[n].mapout_rgbSUM_output=(data >> 8) & 15;
3485      combiner.stage[n].mapout_rgbCD_dotproduct=(data >> 12) & 1;
3486      combiner.stage[n].mapout_rgbAB_dotproduct=(data >> 13) & 1;
3487      combiner.stage[n].mapout_rgb_muxsum=(data >> 14) & 1;
3488      combiner.stage[n].mapout_rgb_bias=(data >> 15) & 1;
3489      combiner.stage[n].mapout_rgb_scale=(data >> 16) & 3;
3490      //combiner.=(data >> 27) & 7;
3491      countlen--;
3492   }
3493}
3494
3495int nv2a_renderer::toggle_register_combiners_usage()
3496{
3497   combiner.used=1-combiner.used;
3498   return combiner.used;
3499}
3500
3501void nv2a_renderer::debug_grab_texture(int type, const char *filename)
3502{
3503   debug_grab_texttype = type;
3504   if (debug_grab_textfile == NULL)
3505      debug_grab_textfile = (char *)malloc(128);
3506   strncpy(debug_grab_textfile, filename, 127);
3507}
3508
3509void nv2a_renderer::debug_grab_vertex_program_slot(int slot, UINT32 *instruction)
3510{
3511   if (slot >= 1024 / 4)
3512      return;
3513   instruction[0] = vertexprogram.instruction[slot * 4 + 0];
3514   instruction[1] = vertexprogram.instruction[slot * 4 + 1];
3515   instruction[2] = vertexprogram.instruction[slot * 4 + 2];
3516   instruction[3] = vertexprogram.instruction[slot * 4 + 3];
3517}
3518
3519void nv2a_renderer::savestate_items()
3520{
3521}
3522
3523void nv2a_renderer::combiner_argb8_float(UINT32 color,float reg[4])
3524{
3525   reg[0]=(float)(color & 0xff)/255.0;
3526   reg[1]=(float)((color >> 8) & 0xff)/255.0;
3527   reg[2]=(float)((color >> 16) & 0xff)/255.0;
3528   reg[3]=(float)((color >> 24) & 0xff)/255.0;
3529}
3530
3531UINT32 nv2a_renderer::combiner_float_argb8(float reg[4])
3532{
3533   UINT32 r,g,b,a;
3534
3535   a=reg[3]*255.0;
3536   b=reg[2]*255.0;
3537   g=reg[1]*255.0;
3538   r=reg[0]*255.0;
3539   return (a << 24) | (r << 16) | (g << 8) | b;
3540}
3541
3542float nv2a_renderer::combiner_map_input_select(int code,int index)
3543{
3544   switch (code) {
3545      case 0:
3546      default:
3547         return combiner.register_zero[index];
3548      case 1:
3549         return combiner.register_color0[index];
3550      case 2:
3551         return combiner.register_color1[index];
3552      case 3:
3553         return combiner.register_fogcolor[index];
3554      case 4:
3555         return combiner.register_primarycolor[index];
3556      case 5:
3557         return combiner.register_secondarycolor[index];
3558      case 8:
3559         return combiner.register_texture0color[index];
3560      case 9:
3561         return combiner.register_texture1color[index];
3562      case 10:
3563         return combiner.register_texture2color[index];
3564      case 11:
3565         return combiner.register_texture3color[index];
3566      case 12:
3567         return combiner.register_spare0[index];
3568      case 13:
3569         return combiner.register_spare1[index];
3570      case 14:
3571         return combiner.variable_sumclamp[index];
3572      case 15:
3573         return combiner.variable_EF[index];
3574   }
3575
3576   // never executed
3577   //return 0;
3578}
3579
3580float *nv2a_renderer::combiner_map_input_select3(int code)
3581{
3582   switch (code) {
3583      case 0:
3584      default:
3585         return combiner.register_zero;
3586      case 1:
3587         return combiner.register_color0;
3588      case 2:
3589         return combiner.register_color1;
3590      case 3:
3591         return combiner.register_fogcolor;
3592      case 4:
3593         return combiner.register_primarycolor;
3594      case 5:
3595         return combiner.register_secondarycolor;
3596      case 8:
3597         return combiner.register_texture0color;
3598      case 9:
3599         return combiner.register_texture1color;
3600      case 10:
3601         return combiner.register_texture2color;
3602      case 11:
3603         return combiner.register_texture3color;
3604      case 12:
3605         return combiner.register_spare0;
3606      case 13:
3607         return combiner.register_spare1;
3608      case 14:
3609         return combiner.variable_sumclamp;
3610      case 15:
3611         return combiner.variable_EF;
3612   }
3613
3614   // never executed
3615   //return 0;
3616}
3617
3618float *nv2a_renderer::combiner_map_output_select3(int code)
3619{
3620   switch (code) {
3621      case 0:
3622         return 0;
3623      case 1:
3624         return 0;
3625      case 2:
3626         return 0;
3627      case 3:
3628         return 0;
3629      case 4:
3630         return combiner.register_primarycolor;
3631      case 5:
3632         return combiner.register_secondarycolor;
3633      case 8:
3634         return combiner.register_texture0color;
3635      case 9:
3636         return combiner.register_texture1color;
3637      case 10:
3638         return combiner.register_texture2color;
3639      case 11:
3640         return combiner.register_texture3color;
3641      case 12:
3642         return combiner.register_spare0;
3643      case 13:
3644         return combiner.register_spare1;
3645      case 14:
3646         return 0;
3647      case 15:
3648      default:
3649         return 0;
3650   }
3651}
3652
3653float nv2a_renderer::combiner_map_input_function(int code,float value)
3654{
3655   float t;
3656
3657   switch (code) {
3658      case 0:
3659         return MAX(0.0,value);
3660      case 1:
3661         t=MAX(value, 0.0);
3662         return 1.0 - MIN(t, 1.0);
3663      case 2:
3664         return 2.0 * MAX(0.0, value) - 1.0;
3665      case 3:
3666         return -2.0 * MAX(0.0, value) + 1.0;
3667      case 4:
3668         return MAX(0.0, value) - 0.5;
3669      case 5:
3670         return -MAX(0.0, value) + 0.5;
3671      case 6:
3672         return value;
3673      case 7:
3674      default:
3675         return -value;
3676   }
3677
3678   // never executed
3679   //return 0;
3680}
3681
3682void nv2a_renderer::combiner_map_input_function3(int code,float *data)
3683{
3684   float t;
3685
3686   switch (code) {
3687      case 0:
3688         data[0]=MAX(0.0,data[0]);
3689         data[1]=MAX(0.0,data[1]);
3690         data[2]=MAX(0.0,data[2]);
3691      break;
3692      case 1:
3693         t=MAX(data[0], 0.0);
3694         data[0]=1.0 - MIN(t, 1.0);
3695         t=MAX(data[1], 0.0);
3696         data[1]=1.0 - MIN(t, 1.0);
3697         t=MAX(data[2], 0.0);
3698         data[2]=1.0 - MIN(t, 1.0);
3699      break;
3700      case 2:
3701         data[0]=2.0 * MAX(0.0, data[0]) - 1.0;
3702         data[1]=2.0 * MAX(0.0, data[1]) - 1.0;
3703         data[2]=2.0 * MAX(0.0, data[2]) - 1.0;
3704      break;
3705      case 3:
3706         data[0]=-2.0 * MAX(0.0, data[0]) + 1.0;
3707         data[1]=-2.0 * MAX(0.0, data[1]) + 1.0;
3708         data[2]=-2.0 * MAX(0.0, data[2]) + 1.0;
3709      break;
3710      case 4:
3711         data[0]=MAX(0.0, data[0]) - 0.5;
3712         data[1]=MAX(0.0, data[1]) - 0.5;
3713         data[2]=MAX(0.0, data[2]) - 0.5;
3714      break;
3715      case 5:
3716         data[0]=-MAX(0.0, data[0]) + 0.5;
3717         data[1]=-MAX(0.0, data[1]) + 0.5;
3718         data[2]=-MAX(0.0, data[2]) + 0.5;
3719      break;
3720      case 6:
3721         return;
3722      case 7:
3723      default:
3724         data[0]=-data[0];
3725         data[1]=-data[1];
3726         data[2]=-data[2];
3727      break;
3728   }
3729}
3730
3731void nv2a_renderer::combiner_initialize_registers(UINT32 argb8[6])
3732{
3733   combiner_argb8_float(argb8[0],combiner.register_primarycolor);
3734   combiner_argb8_float(argb8[1],combiner.register_secondarycolor);
3735   combiner_argb8_float(argb8[2],combiner.register_texture0color);
3736   combiner_argb8_float(argb8[3],combiner.register_texture1color);
3737   combiner_argb8_float(argb8[4],combiner.register_texture2color);
3738   combiner_argb8_float(argb8[5],combiner.register_texture3color);
3739   combiner.register_spare0[3]=combiner.register_texture0color[3];
3740   combiner.register_zero[0]=combiner.register_zero[1]=combiner.register_zero[2]=combiner.register_zero[3]=0;
3741}
3742
3743void nv2a_renderer::combiner_initialize_stage(int stage_number)
3744{
3745   int n=stage_number;
3746
3747   // put register_constantcolor0 in register_color0
3748   combiner.register_color0[0]=combiner.stage[n].register_constantcolor0[0];
3749   combiner.register_color0[1]=combiner.stage[n].register_constantcolor0[1];
3750   combiner.register_color0[2]=combiner.stage[n].register_constantcolor0[2];
3751   combiner.register_color0[3]=combiner.stage[n].register_constantcolor0[3];
3752   // put register_constantcolor1 in register_color1
3753   combiner.register_color1[0]=combiner.stage[n].register_constantcolor1[0];
3754   combiner.register_color1[1]=combiner.stage[n].register_constantcolor1[1];
3755   combiner.register_color1[2]=combiner.stage[n].register_constantcolor1[2];
3756   combiner.register_color1[3]=combiner.stage[n].register_constantcolor1[3];
3757}
3758
3759void nv2a_renderer::combiner_initialize_final()
3760{
3761   // put register_constantcolor0 in register_color0
3762   combiner.register_color0[0]=combiner.final.register_constantcolor0[0];
3763   combiner.register_color0[1]=combiner.final.register_constantcolor0[1];
3764   combiner.register_color0[2]=combiner.final.register_constantcolor0[2];
3765   combiner.register_color0[3]=combiner.final.register_constantcolor0[3];
3766   // put register_constantcolor1 in register_color1
3767   combiner.register_color1[0]=combiner.final.register_constantcolor1[0];
3768   combiner.register_color1[1]=combiner.final.register_constantcolor1[1];
3769   combiner.register_color1[2]=combiner.final.register_constantcolor1[2];
3770   combiner.register_color1[3]=combiner.final.register_constantcolor1[3];
3771}
3772
3773void nv2a_renderer::combiner_map_input(int stage_number)
3774{
3775   int n=stage_number;
3776   int c,d,i;
3777   float v,*pv;
3778
3779   // A
3780   v=combiner_map_input_select(combiner.stage[n].mapin_aA_input,2+combiner.stage[n].mapin_aA_component);
3781   combiner.variable_A[3]=combiner_map_input_function(combiner.stage[n].mapin_aA_mapping,v);
3782   // B
3783   v=combiner_map_input_select(combiner.stage[n].mapin_aB_input,2+combiner.stage[n].mapin_aB_component);
3784   combiner.variable_B[3]=combiner_map_input_function(combiner.stage[n].mapin_aB_mapping,v);
3785   // C
3786   v=combiner_map_input_select(combiner.stage[n].mapin_aC_input,2+combiner.stage[n].mapin_aC_component);
3787   combiner.variable_C[3]=combiner_map_input_function(combiner.stage[n].mapin_aC_mapping,v);
3788   // D
3789   v=combiner_map_input_select(combiner.stage[n].mapin_aD_input,2+combiner.stage[n].mapin_aD_component);
3790   combiner.variable_D[3]=combiner_map_input_function(combiner.stage[n].mapin_aD_mapping,v);
3791
3792   // A
3793   pv=combiner_map_input_select3(combiner.stage[n].mapin_rgbA_input);
3794   c=combiner.stage[n].mapin_rgbA_component*3;
3795   i=~combiner.stage[n].mapin_rgbA_component & 1;
3796   for (d=0;d < 3;d++) {
3797      combiner.variable_A[d]=pv[c];
3798      c=c+i;
3799   }
3800   combiner_map_input_function3(combiner.stage[n].mapin_rgbA_mapping,combiner.variable_A);
3801   // B
3802   pv=combiner_map_input_select3(combiner.stage[n].mapin_rgbB_input);
3803   c=combiner.stage[n].mapin_rgbB_component*3;
3804   i=~combiner.stage[n].mapin_rgbB_component & 1;
3805   for (d=0;d < 3;d++) {
3806      combiner.variable_B[d]=pv[c];
3807      c=c+i;
3808   }
3809   combiner_map_input_function3(combiner.stage[n].mapin_rgbB_mapping,combiner.variable_B);
3810   // C
3811   pv=combiner_map_input_select3(combiner.stage[n].mapin_rgbC_input);
3812   c=combiner.stage[n].mapin_rgbC_component*3;
3813   i=~combiner.stage[n].mapin_rgbC_component & 1;
3814   for (d=0;d < 3;d++) {
3815      combiner.variable_C[d]=pv[c];
3816      c=c+i;
3817   }
3818   combiner_map_input_function3(combiner.stage[n].mapin_rgbC_mapping,combiner.variable_C);
3819   // D
3820   pv=combiner_map_input_select3(combiner.stage[n].mapin_rgbD_input);
3821   c=combiner.stage[n].mapin_rgbD_component*3;
3822   i=~combiner.stage[n].mapin_rgbD_component & 1;
3823   for (d=0;d < 3;d++) {
3824      combiner.variable_D[d]=pv[c];
3825      c=c+i;
3826   }
3827   combiner_map_input_function3(combiner.stage[n].mapin_rgbD_mapping,combiner.variable_D);
3828}
3829
3830void nv2a_renderer::combiner_map_output(int stage_number)
3831{
3832   int n=stage_number;
3833   float *f;
3834
3835   // rgb
3836   f=combiner_map_output_select3(combiner.stage[n].mapout_rgbAB_output);
3837   if (f) {
3838      f[0]=combiner.function_RGBop1[0];
3839      f[1]=combiner.function_RGBop1[1];
3840      f[2]=combiner.function_RGBop1[2];
3841   }
3842   f=combiner_map_output_select3(combiner.stage[n].mapout_rgbCD_output);
3843   if (f) {
3844      f[0]=combiner.function_RGBop2[0];
3845      f[1]=combiner.function_RGBop2[1];
3846      f[2]=combiner.function_RGBop2[2];
3847   }
3848   if ((combiner.stage[n].mapout_rgbAB_dotproduct | combiner.stage[n].mapout_rgbCD_dotproduct) == 0) {
3849      f=combiner_map_output_select3(combiner.stage[n].mapout_rgbSUM_output);
3850      if (f) {
3851         f[0]=combiner.function_RGBop3[0];
3852         f[1]=combiner.function_RGBop3[1];
3853         f[2]=combiner.function_RGBop3[2];
3854      }
3855   }
3856   // a
3857   f=combiner_map_output_select3(combiner.stage[n].mapout_aAB_output);
3858   if (f)
3859      f[3]=combiner.function_Aop1;
3860   f=combiner_map_output_select3(combiner.stage[n].mapout_aCD_output);
3861   if (f)
3862      f[3]=combiner.function_Aop2;
3863   f=combiner_map_output_select3(combiner.stage[n].mapout_aSUM_output);
3864   if (f)
3865      f[3]=combiner.function_Aop3;
3866}
3867
3868void nv2a_renderer::combiner_map_final_input()
3869{
3870   int i,c,d;
3871   float *pv;
3872
3873   // E
3874   pv=combiner_map_input_select3(combiner.final.mapin_rgbE_input);
3875   c=combiner.final.mapin_rgbE_component*3;
3876   i=~combiner.final.mapin_rgbE_component & 1;
3877   for (d=0;d < 3;d++) {
3878      combiner.variable_E[d]=pv[c];
3879      c=c+i;
3880   }
3881   combiner_map_input_function3(combiner.final.mapin_rgbE_mapping,combiner.variable_E);
3882   // F
3883   pv=combiner_map_input_select3(combiner.final.mapin_rgbF_input);
3884   c=combiner.final.mapin_rgbF_component*3;
3885   i=~combiner.final.mapin_rgbF_component & 1;
3886   for (d=0;d < 3;d++) {
3887      combiner.variable_F[d]=pv[c];
3888      c=c+i;
3889   }
3890   combiner_map_input_function3(combiner.final.mapin_rgbF_mapping,combiner.variable_F);
3891   // EF
3892   combiner.variable_EF[0]=combiner.variable_E[0]*combiner.variable_F[0];
3893   combiner.variable_EF[1]=combiner.variable_E[1]*combiner.variable_F[1];
3894   combiner.variable_EF[2]=combiner.variable_E[2]*combiner.variable_F[2];
3895   // sumclamp
3896   combiner.variable_sumclamp[0]=MAX(0,combiner.register_spare0[0])+MAX(0,combiner.register_secondarycolor[0]);
3897   combiner.variable_sumclamp[1]=MAX(0,combiner.register_spare0[1])+MAX(0,combiner.register_secondarycolor[1]);
3898   combiner.variable_sumclamp[2]=MAX(0,combiner.register_spare0[2])+MAX(0,combiner.register_secondarycolor[2]);
3899   if (combiner.final.color_sum_clamp != 0) {
3900      combiner.variable_sumclamp[0]=MIN(combiner.variable_sumclamp[0],1.0);
3901      combiner.variable_sumclamp[1]=MIN(combiner.variable_sumclamp[1],1.0);
3902      combiner.variable_sumclamp[2]=MIN(combiner.variable_sumclamp[2],1.0);
3903   }
3904   // A
3905   pv=combiner_map_input_select3(combiner.final.mapin_rgbA_input);
3906   c=combiner.final.mapin_rgbA_component*3;
3907   i=~combiner.final.mapin_rgbA_component & 1;
3908   for (d=0;d < 3;d++) {
3909      combiner.variable_A[d]=pv[c];
3910      c=c+i;
3911   }
3912   combiner_map_input_function3(combiner.final.mapin_rgbA_mapping,combiner.variable_A);
3913   // B
3914   pv=combiner_map_input_select3(combiner.final.mapin_rgbB_input);
3915   c=combiner.final.mapin_rgbB_component*3;
3916   i=~combiner.final.mapin_rgbB_component & 1;
3917   for (d=0;d < 3;d++) {
3918      combiner.variable_B[d]=pv[c];
3919      c=c+i;
3920   }
3921   combiner_map_input_function3(combiner.final.mapin_rgbB_mapping,combiner.variable_B);
3922   // C
3923   pv=combiner_map_input_select3(combiner.final.mapin_rgbC_input);
3924   c=combiner.final.mapin_rgbC_component*3;
3925   i=~combiner.final.mapin_rgbC_component & 1;
3926   for (d=0;d < 3;d++) {
3927      combiner.variable_C[d]=pv[c];
3928      c=c+i;
3929   }
3930   combiner_map_input_function3(combiner.final.mapin_rgbC_mapping,combiner.variable_C);
3931   // D
3932   pv=combiner_map_input_select3(combiner.final.mapin_rgbD_input);
3933   c=combiner.final.mapin_rgbD_component*3;
3934   i=~combiner.final.mapin_rgbD_component & 1;
3935   for (d=0;d < 3;d++) {
3936      combiner.variable_D[d]=pv[c];
3937      c=c+i;
3938   }
3939   combiner_map_input_function3(combiner.final.mapin_rgbD_mapping,combiner.variable_D);
3940   // G
3941   combiner.variable_G=combiner_map_input_select(combiner.final.mapin_aG_input,2+combiner.final.mapin_aG_component);
3942}
3943
3944void nv2a_renderer::combiner_final_output()
3945{
3946   // rgb
3947   combiner.output[0]=combiner.variable_A[0]*combiner.variable_B[0]+(1.0-combiner.variable_A[0])*combiner.variable_C[0]+combiner.variable_D[0];
3948   combiner.output[1]=combiner.variable_A[1]*combiner.variable_B[1]+(1.0-combiner.variable_A[1])*combiner.variable_C[1]+combiner.variable_D[1];
3949   combiner.output[2]=combiner.variable_A[2]*combiner.variable_B[2]+(1.0-combiner.variable_A[2])*combiner.variable_C[2]+combiner.variable_D[2];
3950   combiner.output[0]=MIN(combiner.output[0],1.0);
3951   combiner.output[1]=MIN(combiner.output[1],1.0);
3952   combiner.output[2]=MIN(combiner.output[2],1.0);
3953   // a
3954   combiner.output[3]=combiner_map_input_function(combiner.final.mapin_aG_mapping,combiner.variable_G);
3955}
3956
3957void nv2a_renderer::combiner_function_AB(float result[4])
3958{
3959   result[0]=combiner.variable_A[0]*combiner.variable_B[0];
3960   result[1]=combiner.variable_A[1]*combiner.variable_B[1];
3961   result[2]=combiner.variable_A[2]*combiner.variable_B[2];
3962}
3963
3964void nv2a_renderer::combiner_function_AdotB(float result[4])
3965{
3966   result[0]=combiner.variable_A[0]*combiner.variable_B[0]+combiner.variable_A[1]*combiner.variable_B[1]+combiner.variable_A[2]*combiner.variable_B[2];
3967   result[1]=result[0];
3968   result[2]=result[0];
3969}
3970
3971void nv2a_renderer::combiner_function_CD(float result[4])
3972{
3973   result[0]=combiner.variable_C[0]*combiner.variable_D[0];
3974   result[1]=combiner.variable_C[1]*combiner.variable_D[1];
3975   result[2]=combiner.variable_C[2]*combiner.variable_D[2];
3976}
3977
3978void nv2a_renderer::combiner_function_CdotD(float result[4])
3979{
3980   result[0]=combiner.variable_C[0]*combiner.variable_D[0]+combiner.variable_C[1]*combiner.variable_D[1]+combiner.variable_C[2]*combiner.variable_D[2];
3981   result[1]=result[0];
3982   result[2]=result[0];
3983}
3984
3985void nv2a_renderer::combiner_function_ABmuxCD(float result[4])
3986{
3987   if (combiner.register_spare0[3] >= 0.5)
3988      combiner_function_AB(result);
3989   else
3990      combiner_function_CD(result);
3991}
3992
3993void nv2a_renderer::combiner_function_ABsumCD(float result[4])
3994{
3995   result[0]=combiner.variable_A[0]*combiner.variable_B[0]+combiner.variable_C[0]*combiner.variable_D[0];
3996   result[1]=combiner.variable_A[1]*combiner.variable_B[1]+combiner.variable_C[1]*combiner.variable_D[1];
3997   result[2]=combiner.variable_A[2]*combiner.variable_B[2]+combiner.variable_C[2]*combiner.variable_D[2];
3998}
3999
4000void nv2a_renderer::combiner_compute_rgb_outputs(int stage_number)
4001{
4002   int n=stage_number;
4003   int m;
4004   float biasrgb,scalergb;
4005
4006   if (combiner.stage[n].mapout_rgb_bias)
4007      biasrgb= -0.5;
4008   else
4009      biasrgb=0;
4010   switch (combiner.stage[n].mapout_rgb_scale) {
4011      case 0:
4012      default:
4013         scalergb=1.0;
4014      break;
4015      case 1:
4016         scalergb=2.0;
4017      break;
4018      case 2:
4019         scalergb=4.0;
4020      break;
4021      case 3:
4022         scalergb=0.5;
4023      break;
4024   }
4025   if (combiner.stage[n].mapout_rgbAB_dotproduct) {
4026      m=1;
4027      combiner_function_AdotB(combiner.function_RGBop1);
4028   } else {
4029      m=0;
4030      combiner_function_AB(combiner.function_RGBop1);
4031      }
4032   combiner.function_RGBop1[0]=MAX(MIN((combiner.function_RGBop1[0] + biasrgb) * scalergb, 1.0), -1.0);
4033   combiner.function_RGBop1[1]=MAX(MIN((combiner.function_RGBop1[1] + biasrgb) * scalergb, 1.0), -1.0);
4034   combiner.function_RGBop1[2]=MAX(MIN((combiner.function_RGBop1[2] + biasrgb) * scalergb, 1.0), -1.0);
4035   if (combiner.stage[n].mapout_rgbCD_dotproduct) {
4036      m=m | 1;
4037      combiner_function_CdotD(combiner.function_RGBop2);
4038   } else
4039      combiner_function_CD(combiner.function_RGBop2);
4040   combiner.function_RGBop2[0]=MAX(MIN((combiner.function_RGBop2[0] + biasrgb) * scalergb, 1.0), -1.0);
4041   combiner.function_RGBop2[1]=MAX(MIN((combiner.function_RGBop2[1] + biasrgb) * scalergb, 1.0), -1.0);
4042   combiner.function_RGBop2[2]=MAX(MIN((combiner.function_RGBop2[2] + biasrgb) * scalergb, 1.0), -1.0);
4043   if (m == 0) {
4044      if (combiner.stage[n].mapout_rgb_muxsum)
4045         combiner_function_ABmuxCD(combiner.function_RGBop3);
4046      else
4047         combiner_function_ABsumCD(combiner.function_RGBop3);
4048      combiner.function_RGBop3[0]=MAX(MIN((combiner.function_RGBop3[0] + biasrgb) * scalergb, 1.0), -1.0);
4049      combiner.function_RGBop3[1]=MAX(MIN((combiner.function_RGBop3[1] + biasrgb) * scalergb, 1.0), -1.0);
4050      combiner.function_RGBop3[2]=MAX(MIN((combiner.function_RGBop3[2] + biasrgb) * scalergb, 1.0), -1.0);
4051   }
4052}
4053
4054void nv2a_renderer::combiner_compute_a_outputs(int stage_number)
4055{
4056   int n=stage_number;
4057   float biasa,scalea;
4058
4059   if (combiner.stage[n].mapout_a_bias)
4060      biasa= -0.5;
4061   else
4062      biasa=0;
4063   switch (combiner.stage[n].mapout_a_scale) {
4064      case 0:
4065      default:
4066         scalea=1.0;
4067      break;
4068      case 1:
4069         scalea=2.0;
4070      break;
4071      case 2:
4072         scalea=4.0;
4073      break;
4074      case 3:
4075         scalea=0.5;
4076      break;
4077   }
4078   combiner.function_Aop1=combiner.variable_A[3]*combiner.variable_B[3];
4079   combiner.function_Aop1=MAX(MIN((combiner.function_Aop1 + biasa) * scalea, 1.0), -1.0);
4080   combiner.function_Aop2=combiner.variable_C[3]*combiner.variable_D[3];
4081   combiner.function_Aop2=MAX(MIN((combiner.function_Aop2 + biasa) * scalea, 1.0), -1.0);
4082   if (combiner.stage[n].mapout_a_muxsum) {
4083      if (combiner.register_spare0[3] >= 0.5)
4084         combiner.function_Aop3=combiner.variable_A[3]*combiner.variable_B[3];
4085      else
4086         combiner.function_Aop3=combiner.variable_C[3]*combiner.variable_D[3];
4087   } else
4088      combiner.function_Aop3=combiner.variable_A[3]*combiner.variable_B[3]+combiner.variable_C[3]*combiner.variable_D[3];
4089   combiner.function_Aop3=MAX(MIN((combiner.function_Aop3 + biasa) * scalea, 1.0), -1.0);
4090}
4091
4092void nv2a_renderer::vblank_callback(screen_device &screen, bool state)
4093{
4094   chihiro_state *chst=machine().driver_data<chihiro_state>();
4095
4096   //printf("vblank_callback\n\r");
4097   if (state == true)
4098      pcrtc[0x100/4] |= 1;
4099   else
4100      pcrtc[0x100/4] &= ~1;
4101   if (pcrtc[0x100/4] & pcrtc[0x140/4])
4102      pmc[0x100/4] |= 0x1000000;
4103   else
4104      pmc[0x100/4] &= ~0x1000000;
4105   if ((pmc[0x100/4] != 0) && (pmc[0x140/4] != 0)) {
4106      // send interrupt
4107      chst->chihiro_devs.pic8259_1->ir3_w(1); // IRQ 3
4108   } else
4109      chst->chihiro_devs.pic8259_1->ir3_w(0); // IRQ 3
4110}
4111
4112UINT32 nv2a_renderer::screen_update_callback(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
4113{
4114   UINT32 *dst=(UINT32 *)bitmap.raw_pixptr(0,0);
4115   UINT32 *src=(UINT32 *)fb.raw_pixptr(0,0);
4116
4117   //printf("updatescreen\n\r");
4118   memcpy(dst,src,bitmap.rowbytes()*bitmap.height());
4119   return 0;
4120}
4121
4122void chihiro_state::debug_generate_irq(int irq,bool active)
4123{
4124901   int state;
4125902
4126903   if (active)
4127904   {
4128      debug_irq_active=true;
4129      debug_irq_number=irq;
4130      state=1;
905      debug_irq_active = true;
906      debug_irq_number = irq;
907      state = 1;
4131908   }
4132909   else
4133910   {
4134      debug_irq_active=false;
4135      state=0;
911      debug_irq_active = false;
912      state = 0;
4136913   }
4137914   switch (irq)
4138915   {
r242208r242209
4186963
4187964void chihiro_state::vblank_callback(screen_device &screen, bool state)
4188965{
4189   nvidia_nv2a->vblank_callback(screen,state);
966   if (nvidia_nv2a->vblank_callback(screen, state))
967      chihiro_devs.pic8259_1->ir3_w(1); // IRQ 3
968   else
969      chihiro_devs.pic8259_1->ir3_w(0); // IRQ 3
4190970}
4191971
4192972UINT32 chihiro_state::screen_update_callback(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
r242208r242209
4194974   return nvidia_nv2a->screen_update_callback(screen, bitmap, cliprect);
4195975}
4196976
4197READ32_MEMBER( nv2a_renderer::geforce_r )
977READ32_MEMBER(chihiro_state::geforce_r)
4198978{
4199static int x,ret;
4200
4201   ret=0;
4202   if (offset == 0x1804f6) {
4203      x = x ^ 0x08080808;
4204      ret=x;
4205   }
4206   if ((offset >= 0x00101000/4) && (offset < 0x00102000/4)) {
4207      //logerror("NV_2A: read STRAPS[%06X] mask %08X value %08X\n",offset*4-0x00101000,mem_mask,ret);
4208   } else if ((offset >= 0x00002000/4) && (offset < 0x00004000/4)) {
4209      ret=pfifo[offset-0x00002000/4];
4210      // PFIFO.CACHE1.STATUS or PFIFO.RUNOUT_STATUS
4211      if ((offset == 0x3214/4) || (offset == 0x2400/4))
4212         ret=0x10;
4213      //logerror("NV_2A: read PFIFO[%06X] value %08X\n",offset*4-0x00002000,ret);
4214   } else if ((offset >= 0x00700000/4) && (offset < 0x00800000/4)) {
4215      ret=ramin[offset-0x00700000/4];
4216      //logerror("NV_2A: read PRAMIN[%06X] value %08X\n",offset*4-0x00700000,ret);
4217   } else if ((offset >= 0x00400000/4) && (offset < 0x00402000/4)) {
4218      //logerror("NV_2A: read PGRAPH[%06X] value %08X\n",offset*4-0x00400000,ret);
4219   } else if ((offset >= 0x00600000/4) && (offset < 0x00601000/4)) {
4220      ret=pcrtc[offset-0x00600000/4];
4221      //logerror("NV_2A: read PCRTC[%06X] value %08X\n",offset*4-0x00600000,ret);
4222   } else if ((offset >= 0x00000000/4) && (offset < 0x00001000/4)) {
4223      ret=pmc[offset-0x00000000/4];
4224      //logerror("NV_2A: read PMC[%06X] value %08X\n",offset*4-0x00000000,ret);
4225   } else if ((offset >= 0x00800000/4) && (offset < 0x00900000/4)) {
4226      // 32 channels size 0x10000 each, 8 subchannels per channel size 0x2000 each
4227      int chanel,subchannel,suboffset;
4228
4229      suboffset=offset-0x00800000/4;
4230      chanel=(suboffset >> (16-2)) & 31;
4231      subchannel=(suboffset >> (13-2)) & 7;
4232      suboffset=suboffset & 0x7ff;
4233      if (suboffset < 0x80/4)
4234         ret=channel[chanel][subchannel].regs[suboffset];
4235      //logerror("NV_2A: read channel[%02X,%d,%04X]=%08X\n",chanel,subchannel,suboffset*4,ret);
4236      return ret;
4237   } else ;
4238      //logerror("NV_2A: read at %08X mask %08X value %08X\n",0xfd000000+offset*4,mem_mask,ret);
4239   return ret;
979   return nvidia_nv2a->geforce_r(space, offset, mem_mask);
4240980}
4241981
4242WRITE32_MEMBER( nv2a_renderer::geforce_w )
982WRITE32_MEMBER(chihiro_state::geforce_w)
4243983{
4244   if ((offset >= 0x00101000/4) && (offset < 0x00102000/4)) {
4245      //logerror("NV_2A: write STRAPS[%06X] mask %08X value %08X\n",offset*4-0x00101000,mem_mask,data);
4246   } else if ((offset >= 0x00002000/4) && (offset < 0x00004000/4)) {
4247      COMBINE_DATA(pfifo+offset-0x00002000/4);
4248      //logerror("NV_2A: read PFIFO[%06X]=%08X\n",offset*4-0x00002000,data & mem_mask); // 2210 pfifo ramht & 1f0 << 12
4249   } else if ((offset >= 0x00700000/4) && (offset < 0x00800000/4)) {
4250      COMBINE_DATA(ramin+offset-0x00700000/4);
4251      //logerror("NV_2A: write PRAMIN[%06X]=%08X\n",offset*4-0x00700000,data & mem_mask);
4252   } else if ((offset >= 0x00400000/4) && (offset < 0x00402000/4)) {
4253      //logerror("NV_2A: write PGRAPH[%06X]=%08X\n",offset*4-0x00400000,data & mem_mask);
4254   } else if ((offset >= 0x00600000/4) && (offset < 0x00601000/4)) {
4255      COMBINE_DATA(pcrtc+offset-0x00600000/4);
4256      //logerror("NV_2A: write PCRTC[%06X]=%08X\n",offset*4-0x00600000,data & mem_mask);
4257   } else if ((offset >= 0x00000000/4) && (offset < 0x00001000/4)) {
4258      COMBINE_DATA(pmc+offset-0x00000000/4);
4259      //logerror("NV_2A: write PMC[%06X]=%08X\n",offset*4-0x00000000,data & mem_mask);
4260   } else if ((offset >= 0x00800000/4) && (offset < 0x00900000/4)) {
4261      // 32 channels size 0x10000 each, 8 subchannels per channel size 0x2000 each
4262      int chanel,subchannel,suboffset;
4263      int method,count,handle,objclass;
4264#ifdef LOG_NV2A
4265      int subch;
4266#endif
4267
4268      suboffset=offset-0x00800000/4;
4269      chanel=(suboffset >> (16-2)) & 31;
4270      subchannel=(suboffset >> (13-2)) & 7;
4271      suboffset=suboffset & 0x7ff;
4272      //logerror("NV_2A: write channel[%02X,%d,%04X]=%08X\n",chanel,subchannel,suboffset*4,data & mem_mask);
4273      if (suboffset >= 0x80/4)
4274         return;
4275      COMBINE_DATA(&channel[chanel][subchannel].regs[suboffset]);
4276      if ((suboffset == 0x40/4) || (suboffset == 0x44/4)) { // DMA_PUT or DMA_GET
4277         UINT32 *dmaput,*dmaget;
4278         UINT32 cmd,cmdtype;
4279         int countlen;
4280
4281         dmaput=&channel[chanel][subchannel].regs[0x40/4];
4282         dmaget=&channel[chanel][subchannel].regs[0x44/4];
4283         //printf("dmaget %08X dmaput %08X\n\r",*dmaget,*dmaput);
4284         if ((*dmaput == 0x048cf000) && (*dmaget == 0x07f4d000))
4285            *dmaget = *dmaput;
4286         while (*dmaget != *dmaput) {
4287            cmd=space.read_dword(*dmaget);
4288            *dmaget += 4;
4289            cmdtype=geforce_commandkind(cmd);
4290            switch (cmdtype)
4291            {
4292               case 6: // jump
4293#ifdef LOG_NV2A
4294                  printf("jump dmaget %08X",*dmaget);
4295#endif
4296                  *dmaget=cmd & 0xfffffffc;
4297#ifdef LOG_NV2A
4298                  printf(" -> %08X\n\r",*dmaget);
4299#endif
4300                  break;
4301               case 0: // increasing method
4302                  method=(cmd >> 2) & 2047; // method*4 is address // if method >= 0x40 send it to assigned object
4303#ifdef LOG_NV2A
4304                  subch=(cmd >> 13) & 7;
4305#endif
4306                  count=(cmd >> 18) & 2047;
4307                  if ((method == 0) && (count == 1)) {
4308                     handle=space.read_dword(*dmaget);
4309                     handle=geforce_object_offset(handle);
4310#ifdef LOG_NV2A
4311                     logerror("  assign to subchannel %d object at %d\n",subch,handle);
4312#endif
4313                     channel[chanel][subchannel].object.objhandle=handle;
4314                     handle=ramin[handle/4];
4315                     objclass=handle & 0xff;
4316                     channel[chanel][subchannel].object.objclass=objclass;
4317                     *dmaget += 4;
4318                  } else {
4319#ifdef LOG_NV2A
4320                     logerror("  subch. %d method %04x offset %04x count %d\n",subch,method,method*4,count);
4321#endif
4322                     while (count > 0) {
4323                        countlen=1;
4324                        geforce_exec_method(space,chanel,subchannel,method,*dmaget,countlen);
4325                        count--;
4326                        method++;
4327                        *dmaget += 4;
4328                     }
4329                  }
4330                  break;
4331               case 5: // non-increasing method
4332                  method=(cmd >> 2) & 2047;
4333#ifdef LOG_NV2A
4334                  subch=(cmd >> 13) & 7;
4335#endif
4336                  count=(cmd >> 18) & 2047;
4337                  if ((method == 0) && (count == 1)) {
4338#ifdef LOG_NV2A
4339                     logerror("  assign channel %d\n",subch);
4340#endif
4341                     handle=space.read_dword(*dmaget);
4342                     handle=geforce_object_offset(handle);
4343#ifdef LOG_NV2A
4344                     logerror("  assign to subchannel %d object at %d\n",subch,handle);
4345#endif
4346                     channel[chanel][subchannel].object.objhandle=handle;
4347                     handle=ramin[handle/4];
4348                     objclass=handle & 0xff;
4349                     channel[chanel][subchannel].object.objclass=objclass;
4350                     *dmaget += 4;
4351                  } else {
4352#ifdef LOG_NV2A
4353                     logerror("  subch. %d method %04x offset %04x count %d\n",subch,method,method*4,count);
4354#endif
4355                     while (count > 0) {
4356                        countlen=count;
4357                        geforce_exec_method(space,chanel,subchannel,method,*dmaget,countlen);
4358                        *dmaget += 4*(count-countlen);
4359                        count=countlen;
4360                     }
4361                  }
4362                  break;
4363               case 3: // long non-increasing method
4364                  method=(cmd >> 2) & 2047;
4365#ifdef LOG_NV2A
4366                  subch=(cmd >> 13) & 7;
4367#endif
4368                  count=space.read_dword(*dmaget);
4369                  *dmaget += 4;
4370                  if ((method == 0) && (count == 1)) {
4371                     handle=space.read_dword(*dmaget);
4372                     handle=geforce_object_offset(handle);
4373#ifdef LOG_NV2A
4374                     logerror("  assign to subchannel %d object at %d\n",subch,handle);
4375#endif
4376                     channel[chanel][subchannel].object.objhandle=handle;
4377                     handle=ramin[handle/4];
4378                     objclass=handle & 0xff;
4379                     channel[chanel][subchannel].object.objclass=objclass;
4380                     *dmaget += 4;
4381                  } else {
4382#ifdef LOG_NV2A
4383                     logerror("  subch. %d method %04x offset %04x count %d\n",subch,method,method*4,count);
4384#endif
4385                     while (count > 0) {
4386                        countlen=count;
4387                        geforce_exec_method(space,chanel,subchannel,method,*dmaget,countlen);
4388                        *dmaget += 4*(count-countlen);
4389                        count=countlen;
4390                     }
4391                  }
4392                  break;
4393               default:
4394                  logerror("  unimplemented command %08X\n",cmd);
4395            }
4396         }
4397      }
4398   } else ;
4399//      logerror("NV_2A: write at %08X mask %08X value %08X\n",0xfd000000+offset*4,mem_mask,data);
984   nvidia_nv2a->geforce_w(space, offset, data, mem_mask);
4400985}
4401986
4402READ32_MEMBER( chihiro_state::geforce_r )
4403{
4404   return nvidia_nv2a->geforce_r(space,offset,mem_mask);
4405}
4406
4407WRITE32_MEMBER( chihiro_state::geforce_w )
4408{
4409   nvidia_nv2a->geforce_w(space,offset,data,mem_mask);
4410}
4411
4412987static UINT32 geforce_pci_r(device_t *busdevice, device_t *device, int function, int reg, UINT32 mem_mask)
4413988{
4414989#ifdef LOG_PCI
4415//  logerror("  bus:1 device:NV_2A function:%d register:%d mask:%08X\n",function,reg,mem_mask);
990   //  logerror("  bus:1 device:NV_2A function:%d register:%d mask:%08X\n",function,reg,mem_mask);
4416991#endif
4417992   return 0;
4418993}
r242208r242209
4420995static void geforce_pci_w(device_t *busdevice, device_t *device, int function, int reg, UINT32 data, UINT32 mem_mask)
4421996{
4422997#ifdef LOG_PCI
4423//  logerror("  bus:1 device:NV_2A function:%d register:%d data:%08X mask:%08X\n",function,reg,data,mem_mask);
998   //  logerror("  bus:1 device:NV_2A function:%d register:%d data:%08X mask:%08X\n",function,reg,data,mem_mask);
4424999#endif
44251000}
44261001
r242208r242209
44291004 */
44301005
44311006#ifdef LOG_OHCI
4432static const char *const usbregnames[]={
1007static const char *const usbregnames[] = {
44331008   "HcRevision",
44341009   "HcControl",
44351010   "HcCommandStatus",
r242208r242209
44551030};
44561031#endif
44571032
4458READ32_MEMBER( chihiro_state::usbctrl_r )
1033READ32_MEMBER(chihiro_state::usbctrl_r)
44591034{
44601035   if (offset == 0) { /* hack needed until usb (and jvs) is implemented */
44611036      if (usbhack_counter == 0) {
4462         m_maincpu->space(0).write_byte(0x6a79f,0x01);
4463         m_maincpu->space(0).write_byte(0x6a7a0,0x00);
4464         m_maincpu->space(0).write_byte(0x6b575,0x00);
4465         m_maincpu->space(0).write_byte(0x6b576,0x00);
4466         m_maincpu->space(0).write_byte(0x6b5af,0x75);
4467         m_maincpu->space(0).write_byte(0x6b78a,0x75);
4468         m_maincpu->space(0).write_byte(0x6b7ca,0x00);
4469         m_maincpu->space(0).write_byte(0x6b7b8,0x00);
4470         m_maincpu->space(0).write_byte(0x8f5b2,0x75);
4471         m_maincpu->space(0).write_byte(0x79a9e,0x74);
4472         m_maincpu->space(0).write_byte(0x79b80,0x74);
4473         m_maincpu->space(0).write_byte(0x79b97,0x74);
1037         m_maincpu->space(0).write_byte(0x6a79f, 0x01);
1038         m_maincpu->space(0).write_byte(0x6a7a0, 0x00);
1039         m_maincpu->space(0).write_byte(0x6b575, 0x00);
1040         m_maincpu->space(0).write_byte(0x6b576, 0x00);
1041         m_maincpu->space(0).write_byte(0x6b5af, 0x75);
1042         m_maincpu->space(0).write_byte(0x6b78a, 0x75);
1043         m_maincpu->space(0).write_byte(0x6b7ca, 0x00);
1044         m_maincpu->space(0).write_byte(0x6b7b8, 0x00);
1045         m_maincpu->space(0).write_byte(0x8f5b2, 0x75);
1046         m_maincpu->space(0).write_byte(0x79a9e, 0x74);
1047         m_maincpu->space(0).write_byte(0x79b80, 0x74);
1048         m_maincpu->space(0).write_byte(0x79b97, 0x74);
44741049      }
44751050      // after game loaded
44761051      if (usbhack_counter == 1) {
4477         m_maincpu->space(0).write_byte(0x12e4cf,0x01);
4478         m_maincpu->space(0).write_byte(0x12e4d0,0x00);
4479         m_maincpu->space(0).write_byte(0x4793e,0x01);
4480         m_maincpu->space(0).write_byte(0x4793f,0x00);
4481         m_maincpu->space(0).write_byte(0x47aa3,0x01);
4482         m_maincpu->space(0).write_byte(0x47aa4,0x00);
4483         m_maincpu->space(0).write_byte(0x14f2b6,0x84);
4484         m_maincpu->space(0).write_byte(0x14f2d1,0x75);
4485         m_maincpu->space(0).write_byte(0x8732f,0x7d);
4486         m_maincpu->space(0).write_byte(0x87384,0x7d);
4487         m_maincpu->space(0).write_byte(0x87388,0xeb);
1052         m_maincpu->space(0).write_byte(0x12e4cf, 0x01);
1053         m_maincpu->space(0).write_byte(0x12e4d0, 0x00);
1054         m_maincpu->space(0).write_byte(0x4793e, 0x01);
1055         m_maincpu->space(0).write_byte(0x4793f, 0x00);
1056         m_maincpu->space(0).write_byte(0x47aa3, 0x01);
1057         m_maincpu->space(0).write_byte(0x47aa4, 0x00);
1058         m_maincpu->space(0).write_byte(0x14f2b6, 0x84);
1059         m_maincpu->space(0).write_byte(0x14f2d1, 0x75);
1060         m_maincpu->space(0).write_byte(0x8732f, 0x7d);
1061         m_maincpu->space(0).write_byte(0x87384, 0x7d);
1062         m_maincpu->space(0).write_byte(0x87388, 0xeb);
44881063      }
44891064      usbhack_counter++;
44901065   }
44911066#ifdef LOG_OHCI
4492   if (offset >= 0x54/4)
4493      logerror("usb controller 0 register HcRhPortStatus[%d] read\n",(offset-0x54/4)+1);
1067   if (offset >= 0x54 / 4)
1068      logerror("usb controller 0 register HcRhPortStatus[%d] read\n", (offset - 0x54 / 4) + 1);
44941069   else
4495      logerror("usb controller 0 register %s read\n",usbregnames[offset]);
1070      logerror("usb controller 0 register %s read\n", usbregnames[offset]);
44961071#endif
44971072   return 0;
44981073}
44991074
4500WRITE32_MEMBER( chihiro_state::usbctrl_w )
1075WRITE32_MEMBER(chihiro_state::usbctrl_w)
45011076{
45021077#ifdef LOG_OHCI
4503   if (offset >= 0x54/4)
4504      logerror("usb controller 0 register HcRhPortStatus[%d] write %08X\n",(offset-0x54/4)+1,data);
1078   if (offset >= 0x54 / 4)
1079      logerror("usb controller 0 register HcRhPortStatus[%d] write %08X\n", (offset - 0x54 / 4) + 1, data);
45051080   else
4506      logerror("usb controller 0 register %s write %08X\n",usbregnames[offset],data);
1081      logerror("usb controller 0 register %s write %08X\n", usbregnames[offset], data);
45071082#endif
45081083}
45091084
r242208r242209
45111086 * Audio
45121087 */
45131088
4514READ32_MEMBER( chihiro_state::audio_apu_r )
1089READ32_MEMBER(chihiro_state::audio_apu_r)
45151090{
4516   logerror("Audio_APU: read from %08X mask %08X\n",0xfe800000+offset*4,mem_mask);
4517   if (offset == 0x20010/4) // some kind of internal counter or state value
4518      return 0x20+4+8+0x48+0x80;
1091   logerror("Audio_APU: read from %08X mask %08X\n", 0xfe800000 + offset * 4, mem_mask);
1092   if (offset == 0x20010 / 4) // some kind of internal counter or state value
1093      return 0x20 + 4 + 8 + 0x48 + 0x80;
45191094   return apust.memory[offset];
45201095}
45211096
4522WRITE32_MEMBER( chihiro_state::audio_apu_w )
1097WRITE32_MEMBER(chihiro_state::audio_apu_w)
45231098{
45241099   //UINT32 old;
45251100   UINT32 v;
45261101
4527   logerror("Audio_APU: write at %08X mask %08X value %08X\n",0xfe800000+offset*4,mem_mask,data);
1102   logerror("Audio_APU: write at %08X mask %08X value %08X\n", 0xfe800000 + offset * 4, mem_mask, data);
45281103   //old = apust.memory[offset];
45291104   apust.memory[offset] = data;
4530   if (offset == 0x02040/4) // address of memory area with scatter-gather info (gpdsp scratch dma)
4531      apust.gpdsp_sgaddress=data;
4532   if (offset == 0x020d4/4) { // block count (gpdsp)
4533      apust.gpdsp_sgblocks=data;
4534      apust.gpdsp_address=apust.space->read_dword(apust.gpdsp_sgaddress); // memory address of first block
1105   if (offset == 0x02040 / 4) // address of memory area with scatter-gather info (gpdsp scratch dma)
1106      apust.gpdsp_sgaddress = data;
1107   if (offset == 0x020d4 / 4) { // block count (gpdsp)
1108      apust.gpdsp_sgblocks = data;
1109      apust.gpdsp_address = apust.space->read_dword(apust.gpdsp_sgaddress); // memory address of first block
45351110      apust.timer->enable();
4536      apust.timer->adjust(attotime::from_msec(1),0,attotime::from_msec(1));
1111      apust.timer->adjust(attotime::from_msec(1), 0, attotime::from_msec(1));
45371112   }
45381113   if (offset == 0x02048 / 4) // (epdsp scratch dma)
4539      apust.epdsp_sgaddress=data;
1114      apust.epdsp_sgaddress = data;
45401115   if (offset == 0x020dc / 4) // (epdsp)
4541      apust.epdsp_sgblocks=data;
1116      apust.epdsp_sgblocks = data;
45421117   if (offset == 0x0204c / 4) // address of memory area with information about blocks
45431118      apust.unknown_sgaddress = data;
45441119   if (offset == 0x020e0 / 4) // block count - 1
r242208r242209
45741149      return;
45751150   if (offset == 0x20304 / 4) { // format
45761151      /*
4577        bits 28-31 sample format:
4578         0  8-bit pcm
4579         5  16-bit pcm
4580         10 adpcm ?
4581         14 24-bit pcm
4582         15 32-bit pcm
4583        bits 16-20 number of channels - 1:
4584         0  mono
4585         1  stereo
1152      bits 28-31 sample format:
1153      0  8-bit pcm
1154      5  16-bit pcm
1155      10 adpcm ?
1156      14 24-bit pcm
1157      15 32-bit pcm
1158      bits 16-20 number of channels - 1:
1159      0  mono
1160      1  stereo
45861161      */
45871162      return;
45881163   }
r242208r242209
45971172   if (offset == 0x203a0 / 4) // start offset of data in scatter-gather heap
45981173      return;
45991174   if (offset == 0x203a4 / 4) { // first sample to play
4600      apust.voices_position_start[apust.voice_number] = data*1000;
1175      apust.voices_position_start[apust.voice_number] = data * 1000;
46011176      return;
46021177   }
46031178   if (offset == 0x203dc / 4) { // last sample to play
4604      apust.voices_position_end[apust.voice_number] = data*1000;
1179      apust.voices_position_end[apust.voice_number] = data * 1000;
46051180      return;
46061181   }
46071182   if (offset == 0x2010c / 4) // voice processor 0 idle 1 not idle ?
r242208r242209
46261201      return;
46271202}
46281203
4629READ32_MEMBER( chihiro_state::audio_ac93_r )
1204READ32_MEMBER(chihiro_state::audio_ac93_r)
46301205{
4631   UINT32 ret=0;
1206   UINT32 ret = 0;
46321207
4633   logerror("Audio_AC3: read from %08X mask %08X\n",0xfec00000+offset*4,mem_mask);
4634   if (offset < 0x80/4)
1208   logerror("Audio_AC3: read from %08X mask %08X\n", 0xfec00000 + offset * 4, mem_mask);
1209   if (offset < 0x80 / 4)
46351210   {
4636      ret=ac97st.mixer_regs[offset];
1211      ret = ac97st.mixer_regs[offset];
46371212   }
4638   if ((offset >= 0x100/4) && (offset <= 0x138/4))
1213   if ((offset >= 0x100 / 4) && (offset <= 0x138 / 4))
46391214   {
4640      offset=offset-0x100/4;
4641      if (offset == 0x18/4)
1215      offset = offset - 0x100 / 4;
1216      if (offset == 0x18 / 4)
46421217      {
46431218         ac97st.controller_regs[offset] &= ~0x02000000; // REGRST: register reset
46441219      }
4645      if (offset == 0x30/4)
1220      if (offset == 0x30 / 4)
46461221      {
46471222         ac97st.controller_regs[offset] |= 0x100; // PCRDY: primary codec ready
46481223      }
4649      if (offset == 0x34/4)
1224      if (offset == 0x34 / 4)
46501225      {
46511226         ac97st.controller_regs[offset] &= ~1; // CAS: codec access semaphore
46521227      }
4653      ret=ac97st.controller_regs[offset];
1228      ret = ac97st.controller_regs[offset];
46541229   }
46551230   return ret;
46561231}
46571232
4658WRITE32_MEMBER( chihiro_state::audio_ac93_w )
1233WRITE32_MEMBER(chihiro_state::audio_ac93_w)
46591234{
4660   logerror("Audio_AC3: write at %08X mask %08X value %08X\n",0xfec00000+offset*4,mem_mask,data);
4661   if (offset < 0x80/4)
1235   logerror("Audio_AC3: write at %08X mask %08X value %08X\n", 0xfec00000 + offset * 4, mem_mask, data);
1236   if (offset < 0x80 / 4)
46621237   {
4663      COMBINE_DATA(ac97st.mixer_regs+offset);
1238      COMBINE_DATA(ac97st.mixer_regs + offset);
46641239   }
4665   if ((offset >= 0x100/4) && (offset <= 0x138/4))
1240   if ((offset >= 0x100 / 4) && (offset <= 0x138 / 4))
46661241   {
4667      offset=offset-0x100/4;
4668      COMBINE_DATA(ac97st.controller_regs+offset);
1242      offset = offset - 0x100 / 4;
1243      COMBINE_DATA(ac97st.controller_regs + offset);
46691244   }
46701245}
46711246
r242208r242209
46761251   UINT64 bv;
46771252   UINT32 phys;
46781253
4679   cmd=apust.space->read_dword(apust.gpdsp_address+0x800+0x10);
1254   cmd = apust.space->read_dword(apust.gpdsp_address + 0x800 + 0x10);
46801255   if (cmd == 3)
4681      apust.space->write_dword(apust.gpdsp_address+0x800+0x10,0);
1256      apust.space->write_dword(apust.gpdsp_address + 0x800 + 0x10, 0);
46821257   /*else
4683       logerror("Audio_APU: unexpected value at address %d\n",apust.gpdsp_address+0x800+0x10);*/
1258   logerror("Audio_APU: unexpected value at address %d\n",apust.gpdsp_address+0x800+0x10);*/
46841259   for (b = 0; b < 4; b++) {
46851260      bv = 1;
46861261      for (bb = 0; bb < 64; bb++) {
r242208r242209
47041279static UINT32 dummy_pci_r(device_t *busdevice, device_t *device, int function, int reg, UINT32 mem_mask)
47051280{
47061281#ifdef LOG_PCI
4707//  logerror("  bus:0 function:%d register:%d mask:%08X\n",function,reg,mem_mask);
1282   //  logerror("  bus:0 function:%d register:%d mask:%08X\n",function,reg,mem_mask);
47081283#endif
47091284   return 0;
47101285}
r242208r242209
47121287static void dummy_pci_w(device_t *busdevice, device_t *device, int function, int reg, UINT32 data, UINT32 mem_mask)
47131288{
47141289#ifdef LOG_PCI
4715   if (reg >= 16) logerror("  bus:0 function:%d register:%d data:%08X mask:%08X\n",function,reg,data,mem_mask);
1290   if (reg >= 16) logerror("  bus:0 function:%d register:%d data:%08X mask:%08X\n", function, reg, data, mem_mask);
47161291#endif
47171292}
47181293
4719READ32_MEMBER( chihiro_state::dummy_r )
1294READ32_MEMBER(chihiro_state::dummy_r)
47201295{
47211296   return 0;
47221297}
47231298
4724WRITE32_MEMBER( chihiro_state::dummy_w )
1299WRITE32_MEMBER(chihiro_state::dummy_w)
47251300{
47261301}
47271302
r242208r242209
47671342void ide_baseboard_device::device_start()
47681343{
47691344   ata_mass_storage_device::device_start();
4770   chihirosystem=machine().driver_data<chihiro_state>();
1345   chihirosystem = machine().driver_data<chihiro_state>();
47711346   // savestates
47721347   save_item(NAME(read_buffer));
47731348   save_item(NAME(write_buffer));
r242208r242209
47811356{
47821357   if (!m_can_identify_device)
47831358   {
4784      m_num_cylinders=65535;
4785      m_num_sectors=255;
4786      m_num_heads=255;
1359      m_num_cylinders = 65535;
1360      m_num_sectors = 255;
1361      m_num_heads = 255;
47871362      ide_build_identify_device();
47881363      m_can_identify_device = 1;
47891364   }
r242208r242209
47981373
47991374   /*
48001375   It assumes there are 4 "partitions", the size of the first one depends on bits 3-0 of io port 40f4:
4801    Value    Size lba
4802      0   0x40000-0x8000
4803        ...
4804      4   0x400000-0x8000
1376   Value    Size lba
1377   0   0x40000-0x8000
1378   ...
1379   4   0x400000-0x8000
48051380   The size of the second one is always 0x8000 sectors, and is used as a special communication area
48061381   This is a list of the partitions in the minimum size case:
4807    Name          Start lba  Size lba Size
4808    \??\mbfs:     0x0        0x38000  112MB
4809    \??\mbcom:    0x38000    0x8000   16MB
4810    \??\mbrom0:   0x8000000  0x800    1MB
4811    \??\mbrom1:   0x8000800  0x800    1MB
1382   Name          Start lba  Size lba Size
1383   \??\mbfs:     0x0        0x38000  112MB
1384   \??\mbcom:    0x38000    0x8000   16MB
1385   \??\mbrom0:   0x8000000  0x800    1MB
1386   \??\mbrom1:   0x8000800  0x800    1MB
48121387   This is a list of the partitions in the maximum size case:
4813    Name          Start lba  Size lba Size
4814    \??\mbfs:     0x0        0x3f8000 2032MB
4815    \??\mbcom:    0x3f8000   0x8000   16MB
4816    \??\mbrom0:   0x8000000  0x800    1MB
4817    \??\mbrom1:   0x8000800  0x800    1MB
1388   Name          Start lba  Size lba Size
1389   \??\mbfs:     0x0        0x3f8000 2032MB
1390   \??\mbcom:    0x3f8000   0x8000   16MB
1391   \??\mbrom0:   0x8000000  0x800    1MB
1392   \??\mbrom1:   0x8000800  0x800    1MB
48181393   */
4819   logerror("baseboard: read sector lba %08x\n",lba);
1394   logerror("baseboard: read sector lba %08x\n", lba);
48201395   if (lba >= 0x08000000) {
4821      off=(lba&0x7ff)*512;
4822      data=memregion(":others")->base();
4823      memcpy(buffer,data+off,512);
1396      off = (lba & 0x7ff) * 512;
1397      data = memregion(":others")->base();
1398      memcpy(buffer, data + off, 512);
48241399      return 1;
48251400   }
48261401   if (lba >= 0xf8000) {
4827      memset(buffer,0,512);
4828      lba=lba-0xf8000;
1402      memset(buffer, 0, 512);
1403      lba = lba - 0xf8000;
48291404      if (lba == 0x4800)
4830         memcpy(buffer,read_buffer,0x20);
1405         memcpy(buffer, read_buffer, 0x20);
48311406      else if (lba == 0x4801)
4832         memcpy(buffer,write_buffer,0x20);
1407         memcpy(buffer, write_buffer, 0x20);
48331408      return 1;
48341409   }
48351410   // in a type 1 chihiro this gets data from the dimm board memory
4836   data=chihirosystem->baseboard_ide_dimmboard(lba);
1411   data = chihirosystem->baseboard_ide_dimmboard(lba);
48371412   if (data != NULL)
4838      memcpy(buffer,data,512);
1413      memcpy(buffer, data, 512);
48391414   return 1;
48401415}
48411416
48421417int ide_baseboard_device::write_sector(UINT32 lba, const void *buffer)
48431418{
4844   logerror("baseboard: write sector lba %08x\n",lba);
1419   logerror("baseboard: write sector lba %08x\n", lba);
48451420   if (lba >= 0xf8000) {
4846      lba=lba-0xf8000;
1421      lba = lba - 0xf8000;
48471422      if (lba == 0x4800)
4848         memcpy(read_buffer,buffer,0x20);
1423         memcpy(read_buffer, buffer, 0x20);
48491424      else if (lba == 0x4801) {
4850         memcpy(write_buffer,buffer,0x20);
1425         memcpy(write_buffer, buffer, 0x20);
48511426         // call chihiro driver
4852         chihirosystem->baseboard_ide_event(3,read_buffer,write_buffer);
1427         chihirosystem->baseboard_ide_event(3, read_buffer, write_buffer);
48531428      }
48541429   }
48551430   return 1;
r242208r242209
48591434 * Chihiro Type 1 baseboard
48601435 */
48611436
4862void chihiro_state::dword_write_le(UINT8 *addr,UINT32 d)
1437void chihiro_state::dword_write_le(UINT8 *addr, UINT32 d)
48631438{
4864   addr[0]=d & 255;
4865   addr[1]=(d >> 8) & 255;
4866   addr[2]=(d >> 16) & 255;
4867   addr[3]=(d >> 24) & 255;
1439   addr[0] = d & 255;
1440   addr[1] = (d >> 8) & 255;
1441   addr[2] = (d >> 16) & 255;
1442   addr[3] = (d >> 24) & 255;
48681443}
48691444
4870void chihiro_state::word_write_le(UINT8 *addr,UINT16 d)
1445void chihiro_state::word_write_le(UINT8 *addr, UINT16 d)
48711446{
4872   addr[0]=d & 255;
4873   addr[1]=(d >> 8) & 255;
1447   addr[0] = d & 255;
1448   addr[1] = (d >> 8) & 255;
48741449}
48751450
4876void chihiro_state::baseboard_ide_event(int type,UINT8 *read_buffer,UINT8 *write_buffer)
1451void chihiro_state::baseboard_ide_event(int type, UINT8 *read_buffer, UINT8 *write_buffer)
48771452{
48781453   int c;
48791454
r242208r242209
48811456      return;
48821457#ifdef LOG_BASEBOARD
48831458   logerror("Baseboard sector command:\n");
4884   for (int a=0;a < 32;a++)
4885      logerror(" %02X",write_buffer[a]);
1459   for (int a = 0; a < 32; a++)
1460      logerror(" %02X", write_buffer[a]);
48861461   logerror("\n");
48871462#endif
48881463   // response
48891464   // second word 8001 (8000+counter), first word=first word of written data (command ?), second dword ?
4890   read_buffer[0]=write_buffer[0];
4891   read_buffer[1]=write_buffer[1];
4892   read_buffer[2]=0x01; // write_buffer[2];
4893   read_buffer[3]=0x80; // write_buffer[3] | 0x80;
4894   c=write_buffer[2]+(write_buffer[3] << 8); // 0001 0101 0103
1465   read_buffer[0] = write_buffer[0];
1466   read_buffer[1] = write_buffer[1];
1467   read_buffer[2] = 0x01; // write_buffer[2];
1468   read_buffer[3] = 0x80; // write_buffer[3] | 0x80;
1469   c = write_buffer[2] + (write_buffer[3] << 8); // 0001 0101 0103
48951470   switch (c)
48961471   {
4897      case 0x0001:
4898         // second dword
4899         dword_write_le(read_buffer+4,0x00f00000); // ?
4900         break;
4901      case 0x0100:
4902         // second dword third dword
4903         dword_write_le(read_buffer+4,5); // game data loading phase
4904         dword_write_le(read_buffer+8,0); // completion %
4905         break;
4906      case 0x0101:
4907         // third word fourth word
4908         word_write_le(read_buffer+4,0xca); // ?
4909         word_write_le(read_buffer+6,0xcb); // ?
4910         break;
4911      case 0x0102:
4912         // second dword
4913         dword_write_le(read_buffer+4,0); // bit 16 develop. mode
4914         break;
4915      case 0x0103:
4916         // dwords 1 3 4
4917         memcpy(read_buffer+4,"-abc-abc12345678",16); // ?
4918         break;
1472   case 0x0001:
1473      // second dword
1474      dword_write_le(read_buffer + 4, 0x00f00000); // ?
1475      break;
1476   case 0x0100:
1477      // second dword third dword
1478      dword_write_le(read_buffer + 4, 5); // game data loading phase
1479      dword_write_le(read_buffer + 8, 0); // completion %
1480      break;
1481   case 0x0101:
1482      // third word fourth word
1483      word_write_le(read_buffer + 4, 0xca); // ?
1484      word_write_le(read_buffer + 6, 0xcb); // ?
1485      break;
1486   case 0x0102:
1487      // second dword
1488      dword_write_le(read_buffer + 4, 0); // bit 16 develop. mode
1489      break;
1490   case 0x0103:
1491      // dwords 1 3 4
1492      memcpy(read_buffer + 4, "-abc-abc12345678", 16); // ?
1493      break;
49191494   }
49201495   // clear
4921   write_buffer[0]=write_buffer[1]=write_buffer[2]=write_buffer[3]=0;
1496   write_buffer[0] = write_buffer[1] = write_buffer[2] = write_buffer[3] = 0;
49221497   // irq 10 active
49231498   chihiro_devs.pic8259_2->ir2_w(1);
49241499}
r242208r242209
49271502{
49281503   // return pointer to memory containing decrypted gdrom data (contains an image of a fatx partition)
49291504   if (chihiro_devs.dimmboard != NULL)
4930      return dimm_board_memory+lba*512;
1505      return dimm_board_memory + lba * 512;
49311506   return NULL;
49321507}
49331508
r242208r242209
49421517
49431518READ8_MEMBER(chihiro_state::get_slave_ack)
49441519{
4945   if (offset==2) { // IRQ = 2
1520   if (offset == 2) { // IRQ = 2
49461521      return chihiro_devs.pic8259_2->acknowledge();
49471522   }
49481523   return 0x00;
r242208r242209
49521527{
49531528   int r = 0;
49541529   r = chihiro_devs.pic8259_2->acknowledge();
4955   if (r==0)
1530   if (r == 0)
49561531   {
49571532      r = chihiro_devs.pic8259_1->acknowledge();
49581533   }
49591534   if (debug_irq_active)
4960      debug_generate_irq(debug_irq_number,false);
1535      debug_generate_irq(debug_irq_number, false);
49611536   return r;
49621537}
49631538
49641539WRITE_LINE_MEMBER(chihiro_state::chihiro_pit8254_out0_changed)
49651540{
4966   if ( chihiro_devs.pic8259_1 )
1541   if (chihiro_devs.pic8259_1)
49671542   {
49681543      chihiro_devs.pic8259_1->ir0_w(state);
49691544   }
r242208r242209
49781553 * SMbus devices
49791554 */
49801555
4981int smbus_callback_pic16lc(chihiro_state &chs,int command,int rw,int data)
1556int smbus_callback_pic16lc(chihiro_state &chs, int command, int rw, int data)
49821557{
49831558   return chs.smbus_pic16lc(command, rw, data);
49841559}
49851560
4986int chihiro_state::smbus_pic16lc(int command,int rw,int data)
1561int chihiro_state::smbus_pic16lc(int command, int rw, int data)
49871562{
49881563   if (rw == 1) { // read
49891564      if (command == 0) {
49901565         if (pic16lc_buffer[0] == 'D')
4991            pic16lc_buffer[0]='X';
1566            pic16lc_buffer[0] = 'X';
49921567         else if (pic16lc_buffer[0] == 'X')
4993            pic16lc_buffer[0]='B';
1568            pic16lc_buffer[0] = 'B';
49941569         else if (pic16lc_buffer[0] == 'B')
4995            pic16lc_buffer[0]='D';
1570            pic16lc_buffer[0] = 'D';
49961571      }
4997      logerror("pic16lc: %d %d %d\n",command,rw,pic16lc_buffer[command]);
1572      logerror("pic16lc: %d %d %d\n", command, rw, pic16lc_buffer[command]);
49981573      return pic16lc_buffer[command];
4999   } else
1574   }
1575   else
50001576      if (command == 0)
5001         pic16lc_buffer[0]='B';
1577         pic16lc_buffer[0] = 'B';
50021578      else
5003         pic16lc_buffer[command]=(UINT8)data;
5004   logerror("pic16lc: %d %d %d\n",command,rw,data);
1579         pic16lc_buffer[command] = (UINT8)data;
1580   logerror("pic16lc: %d %d %d\n", command, rw, data);
50051581   return 0;
50061582}
50071583
5008int smbus_callback_cx25871(chihiro_state &chs,int command,int rw,int data)
1584int smbus_callback_cx25871(chihiro_state &chs, int command, int rw, int data)
50091585{
50101586   return chs.smbus_cx25871(command, rw, data);
50111587}
50121588
5013int chihiro_state::smbus_cx25871(int command,int rw,int data)
1589int chihiro_state::smbus_cx25871(int command, int rw, int data)
50141590{
5015   logerror("cx25871: %d %d %d\n",command,rw,data);
1591   logerror("cx25871: %d %d %d\n", command, rw, data);
50161592   return 0;
50171593}
50181594
r242208r242209
50231599   0x4F,0x6E,0x6C,0x69,0x6E,0x65,0x6B,0x65,0x79,0x69,0x6E,0x76,0x61,0x6C,0x69,0x64,0x00,0x03,0x80,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,
50241600   0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
50251601
5026int smbus_callback_eeprom(chihiro_state &chs,int command,int rw,int data)
1602int smbus_callback_eeprom(chihiro_state &chs, int command, int rw, int data)
50271603{
50281604   return chs.smbus_eeprom(command, rw, data);
50291605}
50301606
5031int chihiro_state::smbus_eeprom(int command,int rw,int data)
1607int chihiro_state::smbus_eeprom(int command, int rw, int data)
50321608{
50331609   if (command >= 112)
50341610      return 0;
r242208r242209
50371613      // hack to avoid hanging if eeprom contents are not correct
50381614      // this would need dumping the serial eeprom on the xbox board
50391615      if (command == 0) {
5040         m_maincpu->space(0).write_byte(0x3b744,0x90);
5041         m_maincpu->space(0).write_byte(0x3b745,0x90);
5042         m_maincpu->space(0).write_byte(0x3b766,0xc9);
5043         m_maincpu->space(0).write_byte(0x3b767,0xc3);
1616         m_maincpu->space(0).write_byte(0x3b744, 0x90);
1617         m_maincpu->space(0).write_byte(0x3b745, 0x90);
1618         m_maincpu->space(0).write_byte(0x3b766, 0xc9);
1619         m_maincpu->space(0).write_byte(0x3b767, 0xc3);
50441620      }
5045      data = dummyeeprom[command]+dummyeeprom[command+1]*256;
5046      logerror("eeprom: %d %d %d\n",command,rw,data);
1621      data = dummyeeprom[command] + dummyeeprom[command + 1] * 256;
1622      logerror("eeprom: %d %d %d\n", command, rw, data);
50471623      return data;
50481624   }
5049   logerror("eeprom: %d %d %d\n",command,rw,data);
5050   dummyeeprom[command]=data;
1625   logerror("eeprom: %d %d %d\n", command, rw, data);
1626   dummyeeprom[command] = data;
50511627   return 0;
50521628}
50531629
r242208r242209
50551631 * SMbus controller
50561632 */
50571633
5058void chihiro_state::smbus_register_device(int address,int (*handler)(chihiro_state &chs,int command,int rw,int data))
1634void chihiro_state::smbus_register_device(int address, int(*handler)(chihiro_state &chs, int command, int rw, int data))
50591635{
50601636   if (address < 128)
5061      smbusst.devices[address]=handler;
1637      smbusst.devices[address] = handler;
50621638}
50631639
5064READ32_MEMBER( chihiro_state::smbus_r )
1640READ32_MEMBER(chihiro_state::smbus_r)
50651641{
50661642   if ((offset == 0) && (mem_mask == 0xff)) // 0 smbus status
50671643      smbusst.words[offset] = (smbusst.words[offset] & ~mem_mask) | ((smbusst.status << 0) & mem_mask);
r242208r242209
50701646   return smbusst.words[offset];
50711647}
50721648
5073WRITE32_MEMBER( chihiro_state::smbus_w )
1649WRITE32_MEMBER(chihiro_state::smbus_w)
50741650{
50751651   COMBINE_DATA(smbusst.words);
50761652   if ((offset == 0) && (mem_mask == 0xff)) // 0 smbus status
r242208r242209
50811657   }
50821658   if ((offset == 0) && (mem_mask == 0xff0000)) // 2 smbus control
50831659   {
5084      data=data>>16;
1660      data = data >> 16;
50851661      smbusst.control = data;
50861662      int cycletype = smbusst.control & 7;
50871663      if (smbusst.control & 8) { // start
r242208r242209
50891665         {
50901666            if (smbusst.devices[smbusst.address])
50911667               if (smbusst.rw == 0)
5092                  smbusst.devices[smbusst.address](*this,smbusst.command,smbusst.rw,smbusst.data);
1668                  smbusst.devices[smbusst.address](*this, smbusst.command, smbusst.rw, smbusst.data);
50931669               else
5094                  smbusst.data=smbusst.devices[smbusst.address](*this,smbusst.command,smbusst.rw,smbusst.data);
1670                  smbusst.data = smbusst.devices[smbusst.address](*this, smbusst.command, smbusst.rw, smbusst.data);
50951671            else
5096               logerror("SMBUS: access to missing device at address %d\n",smbusst.address);
1672               logerror("SMBUS: access to missing device at address %d\n", smbusst.address);
50971673            smbusst.status |= 0x10;
50981674            if (smbusst.control & 0x10)
50991675            {
r242208r242209
51091685   }
51101686   if ((offset == 1) && ((mem_mask == 0x00ff0000) || (mem_mask == 0xffff0000))) // 6 smbus data
51111687   {
5112      data=data>>16;
1688      data = data >> 16;
51131689      smbusst.data = data;
51141690   }
51151691   if ((offset == 2) && (mem_mask == 0xff)) // 8 smbus command
51161692      smbusst.command = data;
51171693}
51181694
5119READ32_MEMBER( chihiro_state::mediaboard_r )
1695READ32_MEMBER(chihiro_state::mediaboard_r)
51201696{
51211697   UINT32 r;
51221698
5123   logerror("I/O port read %04x mask %08X\n",offset*4+0x4000,mem_mask);
5124   r=0;
1699   logerror("I/O port read %04x mask %08X\n", offset * 4 + 0x4000, mem_mask);
1700   r = 0;
51251701   if ((offset == 7) && ACCESSING_BITS_16_31)
5126      r=0x10000000;
1702      r = 0x10000000;
51271703   if ((offset == 8) && ACCESSING_BITS_0_15)
5128      r=0x000000a0;
1704      r = 0x000000a0;
51291705   if ((offset == 8) && ACCESSING_BITS_16_31)
5130      r=0x42580000;
1706      r = 0x42580000;
51311707   if ((offset == 9) && ACCESSING_BITS_0_15)
5132      r=0x00004d41;
1708      r = 0x00004d41;
51331709   if ((offset == 0x3c) && ACCESSING_BITS_0_15)
5134      r=0x00000000; // bits 15-0 0 if media board present
1710      r = 0x00000000; // bits 15-0 0 if media board present
51351711   if ((offset == 0x3d) && ACCESSING_BITS_0_15)
5136      r=0x00000002; // bits 3-0 size of dimm board memory. Must be 2
1712      r = 0x00000002; // bits 3-0 size of dimm board memory. Must be 2
51371713   return r;
51381714}
51391715
5140WRITE32_MEMBER( chihiro_state::mediaboard_w )
1716WRITE32_MEMBER(chihiro_state::mediaboard_w)
51411717{
5142   logerror("I/O port write %04x mask %08X value %08X\n",offset*4+0x4000,mem_mask,data);
1718   logerror("I/O port write %04x mask %08X value %08X\n", offset * 4 + 0x4000, mem_mask, data);
51431719   // irq 10
51441720   if ((offset == 0x38) && ACCESSING_BITS_8_15)
51451721      chihiro_devs.pic8259_2->ir2_w(0);
51461722}
51471723
5148static ADDRESS_MAP_START( xbox_map, AS_PROGRAM, 32, chihiro_state )
1724static ADDRESS_MAP_START(xbox_map, AS_PROGRAM, 32, chihiro_state)
51491725   AM_RANGE(0x00000000, 0x07ffffff) AM_RAM // 128 megabytes
51501726   AM_RANGE(0xf0000000, 0xf0ffffff) AM_RAM
51511727   AM_RANGE(0xfd000000, 0xfdffffff) AM_RAM AM_READWRITE(geforce_r, geforce_w)
r242208r242209
51551731   AM_RANGE(0xff000000, 0xffffffff) AM_ROM AM_REGION("bios", 0) AM_MIRROR(0x00f80000)
51561732ADDRESS_MAP_END
51571733
5158static ADDRESS_MAP_START(xbox_map_io, AS_IO, 32, chihiro_state )
1734static ADDRESS_MAP_START(xbox_map_io, AS_IO, 32, chihiro_state)
51591735   AM_RANGE(0x0020, 0x0023) AM_DEVREADWRITE8("pic8259_1", pic8259_device, read, write, 0xffffffff)
51601736   AM_RANGE(0x0040, 0x0043) AM_DEVREADWRITE8("pit8254", pit8254_device, read, write, 0xffffffff)
51611737   AM_RANGE(0x00a0, 0x00a3) AM_DEVREADWRITE8("pic8259_2", pic8259_device, read, write, 0xffffffff)
r242208r242209
51671743   AM_RANGE(0xff60, 0xff67) AM_DEVREADWRITE("ide", bus_master_ide_controller_device, bmdma_r, bmdma_w)
51681744ADDRESS_MAP_END
51691745
5170static INPUT_PORTS_START( chihiro )
1746static INPUT_PORTS_START(chihiro)
51711747INPUT_PORTS_END
51721748
51731749void chihiro_state::machine_start()
51741750{
5175   nvidia_nv2a=auto_alloc(machine(), nv2a_renderer(machine()));
5176   memset(pic16lc_buffer,0,sizeof(pic16lc_buffer));
5177   pic16lc_buffer[0]='B';
5178   pic16lc_buffer[4]=0; // A/V connector, 2=vga
5179   smbus_register_device(0x10,smbus_callback_pic16lc);
5180   smbus_register_device(0x45,smbus_callback_cx25871);
5181   smbus_register_device(0x54,smbus_callback_eeprom);
5182   chihiro_devs.pic8259_1 = machine().device<pic8259_device>( "pic8259_1" );
5183   chihiro_devs.pic8259_2 = machine().device<pic8259_device>( "pic8259_2" );
5184   chihiro_devs.ide = machine().device<bus_master_ide_controller_device>( "ide" );
5185   chihiro_devs.dimmboard=machine().device<naomi_gdrom_board>("rom_board");
1751   nvidia_nv2a = auto_alloc(machine(), nv2a_renderer(machine()));
1752   memset(pic16lc_buffer, 0, sizeof(pic16lc_buffer));
1753   pic16lc_buffer[0] = 'B';
1754   pic16lc_buffer[4] = 0; // A/V connector, 2=vga
1755   smbus_register_device(0x10, smbus_callback_pic16lc);
1756   smbus_register_device(0x45, smbus_callback_cx25871);
1757   smbus_register_device(0x54, smbus_callback_eeprom);
1758   chihiro_devs.pic8259_1 = machine().device<pic8259_device>("pic8259_1");
1759   chihiro_devs.pic8259_2 = machine().device<pic8259_device>("pic8259_2");
1760   chihiro_devs.ide = machine().device<bus_master_ide_controller_device>("ide");
1761   chihiro_devs.dimmboard = machine().device<naomi_gdrom_board>("rom_board");
51861762   if (chihiro_devs.dimmboard != NULL) {
5187      dimm_board_memory=chihiro_devs.dimmboard->memory(dimm_board_memory_size);
1763      dimm_board_memory = chihiro_devs.dimmboard->memory(dimm_board_memory_size);
51881764   }
51891765   memset(apust.memory, 0, sizeof(apust.memory));
51901766   memset(apust.voices_heap_blockaddr, 0, sizeof(apust.voices_heap_blockaddr));
r242208r242209
51941770   memset(apust.voices_position_end, 0, sizeof(apust.voices_position_end));
51951771   memset(apust.voices_position_increment, 0, sizeof(apust.voices_position_increment));
51961772   apust.space = &m_maincpu->space();
5197   apust.timer=machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(chihiro_state::audio_apu_timer),this),(void *)"APU Timer");
1773   apust.timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(chihiro_state::audio_apu_timer), this), (void *)"APU Timer");
51981774   apust.timer->enable(false);
51991775   if (machine().debug_flags & DEBUG_FLAG_ENABLED)
5200      debug_console_register_command(machine(),"chihiro",CMDFLAG_NONE,0,1,4,chihiro_debug_commands);
5201   usbhack_counter=0;
1776      debug_console_register_command(machine(), "chihiro", CMDFLAG_NONE, 0, 1, 4, chihiro_debug_commands);
1777   usbhack_counter = 0;
52021778   // savestates
52031779   save_item(NAME(debug_irq_active));
52041780   save_item(NAME(debug_irq_number));
r242208r242209
52181794   SLOT_INTERFACE("bb", IDE_BASEBOARD)
52191795SLOT_INTERFACE_END
52201796
5221static MACHINE_CONFIG_START( chihiro_base, chihiro_state )
1797static MACHINE_CONFIG_START(chihiro_base, chihiro_state)
52221798
52231799   /* basic machine hardware */
52241800   MCFG_CPU_ADD("maincpu", PENTIUM3, 733333333) /* Wrong! family 6 model 8 stepping 10 */
52251801   MCFG_CPU_PROGRAM_MAP(xbox_map)
52261802   MCFG_CPU_IO_MAP(xbox_map_io)
5227   MCFG_CPU_IRQ_ACKNOWLEDGE_DRIVER(chihiro_state,irq_callback)
1803   MCFG_CPU_IRQ_ACKNOWLEDGE_DRIVER(chihiro_state, irq_callback)
52281804
52291805   MCFG_QUANTUM_TIME(attotime::from_hz(6000))
52301806
r242208r242209
52411817   MCFG_PCI_BUS_LEGACY_ADD("agpbus", 1)
52421818   MCFG_PCI_BUS_LEGACY_SIBLING("pcibus")
52431819   MCFG_PCI_BUS_LEGACY_DEVICE(0, "NV2A GeForce 3MX Integrated GPU/Northbridge", geforce_pci_r, geforce_pci_w)
5244   MCFG_PIC8259_ADD( "pic8259_1", WRITELINE(chihiro_state, chihiro_pic8259_1_set_int_line), VCC, READ8(chihiro_state,get_slave_ack) )
5245   MCFG_PIC8259_ADD( "pic8259_2", DEVWRITELINE("pic8259_1", pic8259_device, ir2_w), GND, NULL )
1820   MCFG_PIC8259_ADD("pic8259_1", WRITELINE(chihiro_state, chihiro_pic8259_1_set_int_line), VCC, READ8(chihiro_state, get_slave_ack))
1821   MCFG_PIC8259_ADD("pic8259_2", DEVWRITELINE("pic8259_1", pic8259_device, ir2_w), GND, NULL)
52461822
52471823   MCFG_DEVICE_ADD("pit8254", PIT8254, 0)
52481824   MCFG_PIT8253_CLK0(1125000) /* heartbeat IRQ */
r242208r242209
52511827   MCFG_PIT8253_CLK2(1125000) /* (unused) pio port c pin 4, and speaker polling enough */
52521828   MCFG_PIT8253_OUT2_HANDLER(WRITELINE(chihiro_state, chihiro_pit8254_out2_changed))
52531829
5254   MCFG_BUS_MASTER_IDE_CONTROLLER_ADD( "ide", ide_baseboard, NULL, "bb", true)
1830   MCFG_BUS_MASTER_IDE_CONTROLLER_ADD("ide", ide_baseboard, NULL, "bb", true)
52551831   MCFG_ATA_INTERFACE_IRQ_HANDLER(DEVWRITELINE("pic8259_2", pic8259_device, ir6_w))
52561832   MCFG_BUS_MASTER_IDE_CONTROLLER_SPACE("maincpu", AS_PROGRAM)
52571833
r242208r242209
52611837   MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(2500))  /* not accurate */
52621838   MCFG_SCREEN_SIZE(640, 480)
52631839   MCFG_SCREEN_VISIBLE_AREA(0, 639, 0, 479)
5264   MCFG_SCREEN_UPDATE_DRIVER(chihiro_state,screen_update_callback)
5265   MCFG_SCREEN_VBLANK_DRIVER(chihiro_state,vblank_callback)
1840   MCFG_SCREEN_UPDATE_DRIVER(chihiro_state, screen_update_callback)
1841   MCFG_SCREEN_VBLANK_DRIVER(chihiro_state, vblank_callback)
52661842
52671843   MCFG_PALETTE_ADD("palette", 65536)
52681844MACHINE_CONFIG_END
52691845
5270static MACHINE_CONFIG_DERIVED( chihirogd, chihiro_base )
1846static MACHINE_CONFIG_DERIVED(chihirogd, chihiro_base)
52711847   MCFG_NAOMI_GDROM_BOARD_ADD("rom_board", ":gdrom", ":pic", NULL, NOOP)
52721848MACHINE_CONFIG_END
52731849
trunk/src/mame/drivers/gts1.c
r242208r242209
7070#include "cpu/pps4/pps4.h"
7171//#include "gts1.lh"
7272
73#define VERBOSE    1
74
75#if VERBOSE
76#define LOG(x) logerror x
77#else
78#define LOG(x)
79#endif
80
8173class gts1_state : public genpin_class
8274{
8375public:
84    gts1_state(const machine_config &mconfig, device_type type, const char *tag)
85        : genpin_class(mconfig, type, tag)
86        , m_maincpu(*this, "maincpu")
87    { }
76   gts1_state(const machine_config &mconfig, device_type type, const char *tag)
77      : genpin_class(mconfig, type, tag)
78      , m_maincpu(*this, "maincpu")
79   { }
8880
89    DECLARE_DRIVER_INIT(gts1);
90    DECLARE_READ8_MEMBER (gts1_pa_r);
91    DECLARE_WRITE8_MEMBER(gts1_pa_w);
92    DECLARE_WRITE8_MEMBER(gts1_pb_w);
81   DECLARE_DRIVER_INIT(gts1);
9382private:
94    virtual void machine_reset();
95    required_device<cpu_device> m_maincpu;
96    UINT8 m_6351_addr;
83   virtual void machine_reset();
84   required_device<cpu_device> m_maincpu;
9785};
9886
87
9988static ADDRESS_MAP_START( gts1_map, AS_PROGRAM, 8, gts1_state )
100    AM_RANGE(0x0000, 0x0fff) AM_ROM
89   AM_RANGE(0x0000, 0x0fff) AM_ROM
10190ADDRESS_MAP_END
10291
10392static ADDRESS_MAP_START( gts1_data, AS_DATA, 8, gts1_state )
104    AM_RANGE(0x0000, 0x0fff) AM_RAM // not correct
93   AM_RANGE(0x0000, 0x0fff) AM_RAM // not correct
10594ADDRESS_MAP_END
10695
10796static ADDRESS_MAP_START( gts1_io, AS_IO, 8, gts1_state )
108    AM_RANGE(0x0000, 0x00ff) AM_RAM // connects to all the other chips
109    AM_RANGE(0x0100, 0x0100) AM_READ (gts1_pa_r) AM_WRITE(gts1_pa_w)
110    AM_RANGE(0x0101, 0x0101) AM_WRITE(gts1_pb_w)
97   AM_RANGE(0x0000, 0x00ff) AM_RAM // connects to all the other chips
11198ADDRESS_MAP_END
11299
113100static INPUT_PORTS_START( gts1 )
114    PORT_START("DSW0")
115    PORT_DIPNAME( 0x01, 0x00, "S01")
116    PORT_DIPSETTING(    0x00, DEF_STR( Off ))
117    PORT_DIPSETTING(    0x01, DEF_STR( On ))
118    PORT_DIPNAME( 0x02, 0x00, "S02")
119    PORT_DIPSETTING(    0x00, DEF_STR( Off ))
120    PORT_DIPSETTING(    0x02, DEF_STR( On ))
121    PORT_DIPNAME( 0x04, 0x00, "S03")
122    PORT_DIPSETTING(    0x00, DEF_STR( Off ))
123    PORT_DIPSETTING(    0x04, DEF_STR( On ))
124    PORT_DIPNAME( 0x08, 0x00, "S04")
125    PORT_DIPSETTING(    0x00, DEF_STR( Off ))
126    PORT_DIPSETTING(    0x08, DEF_STR( On ))
127    PORT_DIPNAME( 0x10, 0x00, "S05")
128    PORT_DIPSETTING(    0x00, DEF_STR( Off ))
129    PORT_DIPSETTING(    0x10, DEF_STR( On ))
130    PORT_DIPNAME( 0x20, 0x20, "S06")
131    PORT_DIPSETTING(    0x00, DEF_STR( No ))
132    PORT_DIPSETTING(    0x20, DEF_STR( Yes ))
133    PORT_DIPNAME( 0x40, 0x40, "S07")
134    PORT_DIPSETTING(    0x00, DEF_STR( No ))
135    PORT_DIPSETTING(    0x40, DEF_STR( Yes ))
136    PORT_DIPNAME( 0x80, 0x80, "S08")
137    PORT_DIPSETTING(    0x00, DEF_STR( No ))
138    PORT_DIPSETTING(    0x80, DEF_STR( Yes ))
101   PORT_START("DSW0")
102   PORT_DIPNAME( 0x01, 0x00, "S01")
103   PORT_DIPSETTING(    0x00, DEF_STR( Off ))
104   PORT_DIPSETTING(    0x01, DEF_STR( On ))
105   PORT_DIPNAME( 0x02, 0x00, "S02")
106   PORT_DIPSETTING(    0x00, DEF_STR( Off ))
107   PORT_DIPSETTING(    0x02, DEF_STR( On ))
108   PORT_DIPNAME( 0x04, 0x00, "S03")
109   PORT_DIPSETTING(    0x00, DEF_STR( Off ))
110   PORT_DIPSETTING(    0x04, DEF_STR( On ))
111   PORT_DIPNAME( 0x08, 0x00, "S04")
112   PORT_DIPSETTING(    0x00, DEF_STR( Off ))
113   PORT_DIPSETTING(    0x08, DEF_STR( On ))
114   PORT_DIPNAME( 0x10, 0x00, "S05")
115   PORT_DIPSETTING(    0x00, DEF_STR( Off ))
116   PORT_DIPSETTING(    0x10, DEF_STR( On ))
117   PORT_DIPNAME( 0x20, 0x20, "S06")
118   PORT_DIPSETTING(    0x00, DEF_STR( No ))
119   PORT_DIPSETTING(    0x20, DEF_STR( Yes ))
120   PORT_DIPNAME( 0x40, 0x40, "S07")
121   PORT_DIPSETTING(    0x00, DEF_STR( No ))
122   PORT_DIPSETTING(    0x40, DEF_STR( Yes ))
123   PORT_DIPNAME( 0x80, 0x80, "S08")
124   PORT_DIPSETTING(    0x00, DEF_STR( No ))
125   PORT_DIPSETTING(    0x80, DEF_STR( Yes ))
139126
140    PORT_START("DSW1")
141    PORT_DIPNAME( 0x01, 0x00, "S09")
142    PORT_DIPSETTING(    0x00, DEF_STR( Off ))
143    PORT_DIPSETTING(    0x01, DEF_STR( On ))
144    PORT_DIPNAME( 0x02, 0x00, "S10")
145    PORT_DIPSETTING(    0x00, DEF_STR( Off ))
146    PORT_DIPSETTING(    0x02, DEF_STR( On ))
147    PORT_DIPNAME( 0x04, 0x00, "S11")
148    PORT_DIPSETTING(    0x00, DEF_STR( Off ))
149    PORT_DIPSETTING(    0x04, DEF_STR( On ))
150    PORT_DIPNAME( 0x08, 0x00, "S12")
151    PORT_DIPSETTING(    0x00, DEF_STR( Off ))
152    PORT_DIPSETTING(    0x08, DEF_STR( On ))
153    PORT_DIPNAME( 0x10, 0x00, "S13")
154    PORT_DIPSETTING(    0x00, DEF_STR( Off ))
155    PORT_DIPSETTING(    0x10, DEF_STR( On ))
156    PORT_DIPNAME( 0x20, 0x00, "S14")
157    PORT_DIPSETTING(    0x00, DEF_STR( Yes ))
158    PORT_DIPSETTING(    0x20, DEF_STR( No ))
159    PORT_DIPNAME( 0x40, 0x40, "S15")
160    PORT_DIPSETTING(    0x00, DEF_STR( No ))
161    PORT_DIPSETTING(    0x40, DEF_STR( Yes ))
162    PORT_DIPNAME( 0x80, 0x00, "S16")
163    PORT_DIPSETTING(    0x00, DEF_STR( No ))
164    PORT_DIPSETTING(    0x80, DEF_STR( Yes ))
127   PORT_START("DSW1")
128   PORT_DIPNAME( 0x01, 0x00, "S09")
129   PORT_DIPSETTING(    0x00, DEF_STR( Off ))
130   PORT_DIPSETTING(    0x01, DEF_STR( On ))
131   PORT_DIPNAME( 0x02, 0x00, "S10")
132   PORT_DIPSETTING(    0x00, DEF_STR( Off ))
133   PORT_DIPSETTING(    0x02, DEF_STR( On ))
134   PORT_DIPNAME( 0x04, 0x00, "S11")
135   PORT_DIPSETTING(    0x00, DEF_STR( Off ))
136   PORT_DIPSETTING(    0x04, DEF_STR( On ))
137   PORT_DIPNAME( 0x08, 0x00, "S12")
138   PORT_DIPSETTING(    0x00, DEF_STR( Off ))
139   PORT_DIPSETTING(    0x08, DEF_STR( On ))
140   PORT_DIPNAME( 0x10, 0x00, "S13")
141   PORT_DIPSETTING(    0x00, DEF_STR( Off ))
142   PORT_DIPSETTING(    0x10, DEF_STR( On ))
143   PORT_DIPNAME( 0x20, 0x00, "S14")
144   PORT_DIPSETTING(    0x00, DEF_STR( Yes ))
145   PORT_DIPSETTING(    0x20, DEF_STR( No ))
146   PORT_DIPNAME( 0x40, 0x40, "S15")
147   PORT_DIPSETTING(    0x00, DEF_STR( No ))
148   PORT_DIPSETTING(    0x40, DEF_STR( Yes ))
149   PORT_DIPNAME( 0x80, 0x00, "S16")
150   PORT_DIPSETTING(    0x00, DEF_STR( No ))
151   PORT_DIPSETTING(    0x80, DEF_STR( Yes ))
165152
166    PORT_START("DSW2")
167    PORT_DIPNAME( 0x01, 0x00, "S17")
168    PORT_DIPSETTING(    0x00, DEF_STR( Off ))
169    PORT_DIPSETTING(    0x01, DEF_STR( On ))
170    PORT_DIPNAME( 0x02, 0x00, "S18")
171    PORT_DIPSETTING(    0x00, DEF_STR( Off ))
172    PORT_DIPSETTING(    0x02, DEF_STR( On ))
173    PORT_DIPNAME( 0x04, 0x00, "S19")
174    PORT_DIPSETTING(    0x00, DEF_STR( Off ))
175    PORT_DIPSETTING(    0x04, DEF_STR( On ))
176    PORT_DIPNAME( 0x08, 0x00, "S20")
177    PORT_DIPSETTING(    0x00, DEF_STR( Off ))
178    PORT_DIPSETTING(    0x08, DEF_STR( On ))
179    PORT_DIPNAME( 0x10, 0x00, "S21")
180    PORT_DIPSETTING(    0x00, DEF_STR( Off ))
181    PORT_DIPSETTING(    0x10, DEF_STR( On ))
182    PORT_DIPNAME( 0x20, 0x00, "S22")
183    PORT_DIPSETTING(    0x00, DEF_STR( Off ))
184    PORT_DIPSETTING(    0x20, DEF_STR( On ))
185    PORT_DIPNAME( 0x40, 0x00, "S23")
186    PORT_DIPSETTING(    0x00, DEF_STR( Off ))
187    PORT_DIPSETTING(    0x40, DEF_STR( On ))
188    PORT_DIPNAME( 0x80, 0x00, "S24")
189    PORT_DIPSETTING(    0x00, DEF_STR( Off ))
190    PORT_DIPSETTING(    0x80, DEF_STR( On ))
153   PORT_START("DSW2")
154   PORT_DIPNAME( 0x01, 0x00, "S17")
155   PORT_DIPSETTING(    0x00, DEF_STR( Off ))
156   PORT_DIPSETTING(    0x01, DEF_STR( On ))
157   PORT_DIPNAME( 0x02, 0x00, "S18")
158   PORT_DIPSETTING(    0x00, DEF_STR( Off ))
159   PORT_DIPSETTING(    0x02, DEF_STR( On ))
160   PORT_DIPNAME( 0x04, 0x00, "S19")
161   PORT_DIPSETTING(    0x00, DEF_STR( Off ))
162   PORT_DIPSETTING(    0x04, DEF_STR( On ))
163   PORT_DIPNAME( 0x08, 0x00, "S20")
164   PORT_DIPSETTING(    0x00, DEF_STR( Off ))
165   PORT_DIPSETTING(    0x08, DEF_STR( On ))
166   PORT_DIPNAME( 0x10, 0x00, "S21")
167   PORT_DIPSETTING(    0x00, DEF_STR( Off ))
168   PORT_DIPSETTING(    0x10, DEF_STR( On ))
169   PORT_DIPNAME( 0x20, 0x00, "S22")
170   PORT_DIPSETTING(    0x00, DEF_STR( Off ))
171   PORT_DIPSETTING(    0x20, DEF_STR( On ))
172   PORT_DIPNAME( 0x40, 0x00, "S23")
173   PORT_DIPSETTING(    0x00, DEF_STR( Off ))
174   PORT_DIPSETTING(    0x40, DEF_STR( On ))
175   PORT_DIPNAME( 0x80, 0x00, "S24")
176   PORT_DIPSETTING(    0x00, DEF_STR( Off ))
177   PORT_DIPSETTING(    0x80, DEF_STR( On ))
191178INPUT_PORTS_END
192179
193180void gts1_state::machine_reset()
194181{
195    m_6351_addr = 0;
196182}
197183
198184DRIVER_INIT_MEMBER(gts1_state,gts1)
199185{
200186}
201187
202READ8_MEMBER (gts1_state::gts1_pa_r)
203{
204    // return ROM nibble
205    UINT8 *ROM = memregion("maincpu")->base();
206    UINT8 data = ROM[0x2000 + m_6351_addr] & 0x0f;
207    LOG(("%s: ROM[%03x]:%02x\n", __FUNCTION__, m_6351_addr, data));
208    return data;
209}
210
211WRITE8_MEMBER(gts1_state::gts1_pa_w)
212{
213    // write address lines 7-4
214    m_6351_addr = (m_6351_addr & 0x0f) | ((data & 0x0f) << 4);
215    LOG(("%s: ROM hi:%x addr:%02x\n", __FUNCTION__, data & 0x0f, m_6351_addr));
216}
217
218WRITE8_MEMBER(gts1_state::gts1_pb_w)
219{
220    // write address lines 3-0
221    m_6351_addr = (m_6351_addr & 0xf0) | (data & 0x0f);
222    LOG(("%s: ROM lo:%x addr:%02x\n", __FUNCTION__, data & 0x0f, m_6351_addr));
223}
224
225
226188static MACHINE_CONFIG_START( gts1, gts1_state )
227    /* basic machine hardware */
228    MCFG_CPU_ADD("maincpu", PPS4, XTAL_3_579545MHz / 18)  // divided in the CPU
229    MCFG_CPU_PROGRAM_MAP(gts1_map)
230    MCFG_CPU_DATA_MAP(gts1_data)
231    MCFG_CPU_IO_MAP(gts1_io)
189   /* basic machine hardware */
190   MCFG_CPU_ADD("maincpu", PPS4, XTAL_3_579545MHz / 18)  // divided in the CPU
191   MCFG_CPU_PROGRAM_MAP(gts1_map)
192   MCFG_CPU_DATA_MAP(gts1_data)
193   MCFG_CPU_IO_MAP(gts1_io)
232194
233    //MCFG_NVRAM_ADD_0FILL("nvram")
195   //MCFG_NVRAM_ADD_0FILL("nvram")
234196
235    /* Video */
236    //MCFG_DEFAULT_LAYOUT(layout_gts1)
197   /* Video */
198   //MCFG_DEFAULT_LAYOUT(layout_gts1)
237199
238    /* Sound */
239    MCFG_FRAGMENT_ADD( genpin_audio )
200   /* Sound */
201   MCFG_FRAGMENT_ADD( genpin_audio )
240202MACHINE_CONFIG_END
241203
242204
243205ROM_START( gts1 )
244    ROM_REGION( 0x10000, "maincpu", 0 )
245    ROM_LOAD("u5_cf.bin", 0x0000, 0x0800, CRC(e0d4b405) SHA1(17aadd79c0dcbb336aadd5d203bc6ca866492345))
246    ROM_LOAD("u4_ce.bin", 0x0800, 0x0800, CRC(4cd312dd) SHA1(31245daa9972ef8652caee69986585bb8239e86e))
206   ROM_REGION( 0x10000, "maincpu", 0 )
207   ROM_LOAD("u5_cf.bin", 0x0000, 0x0800, CRC(e0d4b405) SHA1(17aadd79c0dcbb336aadd5d203bc6ca866492345))
208   ROM_LOAD("u4_ce.bin", 0x0800, 0x0800, CRC(4cd312dd) SHA1(31245daa9972ef8652caee69986585bb8239e86e))
247209ROM_END
248210
249211ROM_START( gts1s )
250    ROM_REGION( 0x10000, "maincpu", 0 )
251    ROM_LOAD("u5_cf.bin", 0x0000, 0x0800, CRC(e0d4b405) SHA1(17aadd79c0dcbb336aadd5d203bc6ca866492345))
252    ROM_LOAD("u4_ce.bin", 0x0800, 0x0800, CRC(4cd312dd) SHA1(31245daa9972ef8652caee69986585bb8239e86e))
212   ROM_REGION( 0x10000, "maincpu", 0 )
213   ROM_LOAD("u5_cf.bin", 0x0000, 0x0800, CRC(e0d4b405) SHA1(17aadd79c0dcbb336aadd5d203bc6ca866492345))
214   ROM_LOAD("u4_ce.bin", 0x0800, 0x0800, CRC(4cd312dd) SHA1(31245daa9972ef8652caee69986585bb8239e86e))
253215ROM_END
254216
255217/*-------------------------------------------------------------------
256218/ Asteroid Annie and the Aliens (12/1980) #442
257219/-------------------------------------------------------------------*/
258220ROM_START(astannie)
259    ROM_REGION(0x10000, "maincpu", 0)
260    ROM_LOAD("u5_cf.bin", 0x0000, 0x0800, CRC(e0d4b405) SHA1(17aadd79c0dcbb336aadd5d203bc6ca866492345))
261    ROM_LOAD("u4_ce.bin", 0x0800, 0x0800, CRC(4cd312dd) SHA1(31245daa9972ef8652caee69986585bb8239e86e))
262    ROM_LOAD("442.cpu", 0x2000, 0x0400, CRC(579521e0) SHA1(b1b19473e1ca3373955ee96104b87f586c4c311c))
263    ROM_REGION(0x10000, "cpu2", 0)
264    ROM_LOAD("442.snd", 0x0400, 0x0400, CRC(c70195b4) SHA1(ff06197f07111d6a4b8942dcfe8d2279bda6f281))
265    ROM_RELOAD( 0x0800, 0x0400)
266    ROM_LOAD("6530sys1.bin", 0x0c00, 0x0400, CRC(b7831321) SHA1(c94f4bee97854d0373653a6867016e27d3fc1340))
267    ROM_RELOAD( 0xfc00, 0x0400)
221   ROM_REGION(0x10000, "maincpu", 0)
222   ROM_LOAD("u5_cf.bin", 0x0000, 0x0800, CRC(e0d4b405) SHA1(17aadd79c0dcbb336aadd5d203bc6ca866492345))
223   ROM_LOAD("u4_ce.bin", 0x0800, 0x0800, CRC(4cd312dd) SHA1(31245daa9972ef8652caee69986585bb8239e86e))
224   ROM_LOAD("442.cpu", 0x2000, 0x0400, CRC(579521e0) SHA1(b1b19473e1ca3373955ee96104b87f586c4c311c))
225   ROM_REGION(0x10000, "cpu2", 0)
226   ROM_LOAD("442.snd", 0x0400, 0x0400, CRC(c70195b4) SHA1(ff06197f07111d6a4b8942dcfe8d2279bda6f281))
227   ROM_RELOAD( 0x0800, 0x0400)
228   ROM_LOAD("6530sys1.bin", 0x0c00, 0x0400, CRC(b7831321) SHA1(c94f4bee97854d0373653a6867016e27d3fc1340))
229   ROM_RELOAD( 0xfc00, 0x0400)
268230ROM_END
269231
270232/*-------------------------------------------------------------------
271233/ Buck Rogers (01/1980) #437
272234/-------------------------------------------------------------------*/
273235ROM_START(buckrgrs)
274    ROM_REGION(0x10000, "maincpu", 0)
275    ROM_LOAD("u5_cf.bin", 0x0000, 0x0800, CRC(e0d4b405) SHA1(17aadd79c0dcbb336aadd5d203bc6ca866492345))
276    ROM_LOAD("u4_ce.bin", 0x0800, 0x0800, CRC(4cd312dd) SHA1(31245daa9972ef8652caee69986585bb8239e86e))
277    ROM_LOAD("437.cpu", 0x2000, 0x0400, CRC(e57d9278) SHA1(dfc4ebff1e14b9a074468671a8e5ac7948d5b352))
278    ROM_REGION(0x10000, "cpu2", 0)
279    ROM_LOAD("437.snd", 0x0400, 0x0400, CRC(732b5a27) SHA1(7860ea54e75152246c3ac3205122d750b243b40c))
280    ROM_RELOAD( 0x0800, 0x0400)
281    ROM_LOAD("6530sys1.bin", 0x0c00, 0x0400, CRC(b7831321) SHA1(c94f4bee97854d0373653a6867016e27d3fc1340))
282    ROM_RELOAD( 0xfc00, 0x0400)
236   ROM_REGION(0x10000, "maincpu", 0)
237   ROM_LOAD("u5_cf.bin", 0x0000, 0x0800, CRC(e0d4b405) SHA1(17aadd79c0dcbb336aadd5d203bc6ca866492345))
238   ROM_LOAD("u4_ce.bin", 0x0800, 0x0800, CRC(4cd312dd) SHA1(31245daa9972ef8652caee69986585bb8239e86e))
239   ROM_LOAD("437.cpu", 0x2000, 0x0400, CRC(e57d9278) SHA1(dfc4ebff1e14b9a074468671a8e5ac7948d5b352))
240   ROM_REGION(0x10000, "cpu2", 0)
241   ROM_LOAD("437.snd", 0x0400, 0x0400, CRC(732b5a27) SHA1(7860ea54e75152246c3ac3205122d750b243b40c))
242   ROM_RELOAD( 0x0800, 0x0400)
243   ROM_LOAD("6530sys1.bin", 0x0c00, 0x0400, CRC(b7831321) SHA1(c94f4bee97854d0373653a6867016e27d3fc1340))
244   ROM_RELOAD( 0xfc00, 0x0400)
283245ROM_END
284246
285247/*-------------------------------------------------------------------
286248/ Charlie's Angels (11/1978) #425
287249/-------------------------------------------------------------------*/
288250ROM_START(charlies)
289    ROM_REGION(0x10000, "maincpu", 0)
290    ROM_LOAD("u5_cf.bin", 0x0000, 0x0800, CRC(e0d4b405) SHA1(17aadd79c0dcbb336aadd5d203bc6ca866492345))
291    ROM_LOAD("u4_ce.bin", 0x0800, 0x0800, CRC(4cd312dd) SHA1(31245daa9972ef8652caee69986585bb8239e86e))
292    ROM_LOAD("425.cpu", 0x2000, 0x0400, CRC(928b4279) SHA1(51096d45e880d6a8263eaeaa0cdab0f61ad2f58d))
251   ROM_REGION(0x10000, "maincpu", 0)
252   ROM_LOAD("u5_cf.bin", 0x0000, 0x0800, CRC(e0d4b405) SHA1(17aadd79c0dcbb336aadd5d203bc6ca866492345))
253   ROM_LOAD("u4_ce.bin", 0x0800, 0x0800, CRC(4cd312dd) SHA1(31245daa9972ef8652caee69986585bb8239e86e))
254   ROM_LOAD("425.cpu", 0x2000, 0x0400, CRC(928b4279) SHA1(51096d45e880d6a8263eaeaa0cdab0f61ad2f58d))
293255ROM_END
294256/*-------------------------------------------------------------------
295257/ Cleopatra (11/1977) #409
296258/-------------------------------------------------------------------*/
297259ROM_START(cleoptra)
298    ROM_REGION(0x10000, "maincpu", 0)
299    ROM_LOAD("u5_cf.bin", 0x0000, 0x0800, CRC(e0d4b405) SHA1(17aadd79c0dcbb336aadd5d203bc6ca866492345))
300    ROM_LOAD("u4_ce.bin", 0x0800, 0x0800, CRC(4cd312dd) SHA1(31245daa9972ef8652caee69986585bb8239e86e))
301    ROM_LOAD("409.cpu", 0x2000, 0x0400, CRC(8063ff71) SHA1(205f09f067bf79544d2ce2a48d23259901f935dd))
260   ROM_REGION(0x10000, "maincpu", 0)
261   ROM_LOAD("u5_cf.bin", 0x0000, 0x0800, CRC(e0d4b405) SHA1(17aadd79c0dcbb336aadd5d203bc6ca866492345))
262   ROM_LOAD("u4_ce.bin", 0x0800, 0x0800, CRC(4cd312dd) SHA1(31245daa9972ef8652caee69986585bb8239e86e))
263   ROM_LOAD("409.cpu", 0x2000, 0x0400, CRC(8063ff71) SHA1(205f09f067bf79544d2ce2a48d23259901f935dd))
302264ROM_END
303265
304266/*-------------------------------------------------------------------
305267/ Close Encounters of the Third Kind (10/1978) #424
306268/-------------------------------------------------------------------*/
307269ROM_START(closeenc)
308    ROM_REGION(0x10000, "maincpu", 0)
309    ROM_LOAD("u5_cf.bin", 0x0000, 0x0800, CRC(e0d4b405) SHA1(17aadd79c0dcbb336aadd5d203bc6ca866492345))
310    ROM_LOAD("u4_ce.bin", 0x0800, 0x0800, CRC(4cd312dd) SHA1(31245daa9972ef8652caee69986585bb8239e86e))
311    ROM_LOAD("424.cpu", 0x2000, 0x0400, CRC(a7a5dd13) SHA1(223c67b9484baa719c91de52b363ff22813db160))
270   ROM_REGION(0x10000, "maincpu", 0)
271   ROM_LOAD("u5_cf.bin", 0x0000, 0x0800, CRC(e0d4b405) SHA1(17aadd79c0dcbb336aadd5d203bc6ca866492345))
272   ROM_LOAD("u4_ce.bin", 0x0800, 0x0800, CRC(4cd312dd) SHA1(31245daa9972ef8652caee69986585bb8239e86e))
273   ROM_LOAD("424.cpu", 0x2000, 0x0400, CRC(a7a5dd13) SHA1(223c67b9484baa719c91de52b363ff22813db160))
312274ROM_END
313275
314276/*-------------------------------------------------------------------
315277/ Count-Down (05/1979) #422
316278/-------------------------------------------------------------------*/
317279ROM_START(countdwn)
318    ROM_REGION(0x10000, "maincpu", 0)
319    ROM_LOAD("u5_cf.bin", 0x0000, 0x0800, CRC(e0d4b405) SHA1(17aadd79c0dcbb336aadd5d203bc6ca866492345))
320    ROM_LOAD("u4_ce.bin", 0x0800, 0x0800, CRC(4cd312dd) SHA1(31245daa9972ef8652caee69986585bb8239e86e))
321    ROM_LOAD("422.cpu", 0x2000, 0x0400, CRC(51bc2df0) SHA1(d4b555d106c6b4e420b0fcd1df8871f869476c22))
280   ROM_REGION(0x10000, "maincpu", 0)
281   ROM_LOAD("u5_cf.bin", 0x0000, 0x0800, CRC(e0d4b405) SHA1(17aadd79c0dcbb336aadd5d203bc6ca866492345))
282   ROM_LOAD("u4_ce.bin", 0x0800, 0x0800, CRC(4cd312dd) SHA1(31245daa9972ef8652caee69986585bb8239e86e))
283   ROM_LOAD("422.cpu", 0x2000, 0x0400, CRC(51bc2df0) SHA1(d4b555d106c6b4e420b0fcd1df8871f869476c22))
322284ROM_END
323285
324286/*-------------------------------------------------------------------
325287/ Dragon (10/1978) #419
326288/-------------------------------------------------------------------*/
327289ROM_START(dragon)
328    ROM_REGION(0x10000, "maincpu", 0)
329    ROM_LOAD("u5_cf.bin", 0x0000, 0x0800, CRC(e0d4b405) SHA1(17aadd79c0dcbb336aadd5d203bc6ca866492345))
330    ROM_LOAD("u4_ce.bin", 0x0800, 0x0800, CRC(4cd312dd) SHA1(31245daa9972ef8652caee69986585bb8239e86e))
331    ROM_LOAD("419.cpu", 0x2000, 0x0400, CRC(018d9b3a) SHA1(da37ef5017c71bc41bdb1f30d3fd7ac3b7e1ee7e))
290   ROM_REGION(0x10000, "maincpu", 0)
291   ROM_LOAD("u5_cf.bin", 0x0000, 0x0800, CRC(e0d4b405) SHA1(17aadd79c0dcbb336aadd5d203bc6ca866492345))
292   ROM_LOAD("u4_ce.bin", 0x0800, 0x0800, CRC(4cd312dd) SHA1(31245daa9972ef8652caee69986585bb8239e86e))
293   ROM_LOAD("419.cpu", 0x2000, 0x0400, CRC(018d9b3a) SHA1(da37ef5017c71bc41bdb1f30d3fd7ac3b7e1ee7e))
332294ROM_END
333295
334296/*-------------------------------------------------------------------
335297/ Genie (11/1979) #435
336298/-------------------------------------------------------------------*/
337299ROM_START(geniep)
338    ROM_REGION(0x10000, "maincpu", 0)
339    ROM_LOAD("u5_cf.bin", 0x0000, 0x0800, CRC(e0d4b405) SHA1(17aadd79c0dcbb336aadd5d203bc6ca866492345))
340    ROM_LOAD("u4_ce.bin", 0x0800, 0x0800, CRC(4cd312dd) SHA1(31245daa9972ef8652caee69986585bb8239e86e))
341    ROM_LOAD("435.cpu", 0x2000, 0x0400, CRC(7749fd92) SHA1(9cd3e799842392e3939877bf295759c27f199e58))
342    ROM_REGION(0x10000, "cpu2", 0)
343    ROM_LOAD("435.snd", 0x0400, 0x0400, CRC(4a98ceed) SHA1(f1d7548e03107033c39953ee04b043b5301dbb47))
344    ROM_RELOAD( 0x0800, 0x0400)
345    ROM_LOAD("6530sys1.bin", 0x0c00, 0x0400, CRC(b7831321) SHA1(c94f4bee97854d0373653a6867016e27d3fc1340))
346    ROM_RELOAD( 0xfc00, 0x0400)
300   ROM_REGION(0x10000, "maincpu", 0)
301   ROM_LOAD("u5_cf.bin", 0x0000, 0x0800, CRC(e0d4b405) SHA1(17aadd79c0dcbb336aadd5d203bc6ca866492345))
302   ROM_LOAD("u4_ce.bin", 0x0800, 0x0800, CRC(4cd312dd) SHA1(31245daa9972ef8652caee69986585bb8239e86e))
303   ROM_LOAD("435.cpu", 0x2000, 0x0400, CRC(7749fd92) SHA1(9cd3e799842392e3939877bf295759c27f199e58))
304   ROM_REGION(0x10000, "cpu2", 0)
305   ROM_LOAD("435.snd", 0x0400, 0x0400, CRC(4a98ceed) SHA1(f1d7548e03107033c39953ee04b043b5301dbb47))
306   ROM_RELOAD( 0x0800, 0x0400)
307   ROM_LOAD("6530sys1.bin", 0x0c00, 0x0400, CRC(b7831321) SHA1(c94f4bee97854d0373653a6867016e27d3fc1340))
308   ROM_RELOAD( 0xfc00, 0x0400)
347309ROM_END
348310
349311/*-------------------------------------------------------------------
350312/ Joker Poker (08/1978) #417
351313/-------------------------------------------------------------------*/
352314ROM_START(jokrpokr)
353    ROM_REGION(0x10000, "maincpu", 0)
354    ROM_LOAD("u5_cf.bin", 0x0000, 0x0800, CRC(e0d4b405) SHA1(17aadd79c0dcbb336aadd5d203bc6ca866492345))
355    ROM_LOAD("u4_ce.bin", 0x0800, 0x0800, CRC(4cd312dd) SHA1(31245daa9972ef8652caee69986585bb8239e86e))
356    ROM_LOAD("417.cpu", 0x2000, 0x0400, CRC(33dade08) SHA1(23b8dbd7b6c84b806fc0d2da95478235cbf9f80a))
315   ROM_REGION(0x10000, "maincpu", 0)
316   ROM_LOAD("u5_cf.bin", 0x0000, 0x0800, CRC(e0d4b405) SHA1(17aadd79c0dcbb336aadd5d203bc6ca866492345))
317   ROM_LOAD("u4_ce.bin", 0x0800, 0x0800, CRC(4cd312dd) SHA1(31245daa9972ef8652caee69986585bb8239e86e))
318   ROM_LOAD("417.cpu", 0x2000, 0x0400, CRC(33dade08) SHA1(23b8dbd7b6c84b806fc0d2da95478235cbf9f80a))
357319ROM_END
358320
359321/*-------------------------------------------------------------------
r242208r242209
363325/ L'Hexagone (04/1986)
364326/-------------------------------------------------------------------*/
365327ROM_START(hexagone)
366    ROM_REGION(0x10000, "maincpu", 0)
367    ROM_LOAD("u5_cf.bin", 0x0000, 0x0800, CRC(e0d4b405) SHA1(17aadd79c0dcbb336aadd5d203bc6ca866492345))
368    ROM_LOAD("u4_ce.bin", 0x0800, 0x0800, CRC(4cd312dd) SHA1(31245daa9972ef8652caee69986585bb8239e86e))
369    ROM_LOAD("435.cpu", 0x2000, 0x0400, CRC(7749fd92) SHA1(9cd3e799842392e3939877bf295759c27f199e58))
370    ROM_REGION(0x10000, "cpu2", 0)
371    ROM_LOAD("hexagone.bin", 0, 0x4000, CRC(002b5464) SHA1(e2d971c4e85b4fb6580c2d3945c9946ea0cebc2e))
328   ROM_REGION(0x10000, "maincpu", 0)
329   ROM_LOAD("u5_cf.bin", 0x0000, 0x0800, CRC(e0d4b405) SHA1(17aadd79c0dcbb336aadd5d203bc6ca866492345))
330   ROM_LOAD("u4_ce.bin", 0x0800, 0x0800, CRC(4cd312dd) SHA1(31245daa9972ef8652caee69986585bb8239e86e))
331   ROM_LOAD("435.cpu", 0x2000, 0x0400, CRC(7749fd92) SHA1(9cd3e799842392e3939877bf295759c27f199e58))
332   ROM_REGION(0x10000, "cpu2", 0)
333   ROM_LOAD("hexagone.bin", 0, 0x4000, CRC(002b5464) SHA1(e2d971c4e85b4fb6580c2d3945c9946ea0cebc2e))
372334ROM_END
373335/*-------------------------------------------------------------------
374336/ Movie
r242208r242209
378340/ Pinball Pool (08/1979) #427
379341/-------------------------------------------------------------------*/
380342ROM_START(pinpool)
381    ROM_REGION(0x10000, "maincpu", 0)
382    ROM_LOAD("u5_cf.bin", 0x0000, 0x0800, CRC(e0d4b405) SHA1(17aadd79c0dcbb336aadd5d203bc6ca866492345))
383    ROM_LOAD("u4_ce.bin", 0x0800, 0x0800, CRC(4cd312dd) SHA1(31245daa9972ef8652caee69986585bb8239e86e))
384    ROM_LOAD("427.cpu", 0x2000, 0x0400, CRC(c496393d) SHA1(e91d9596aacdb4277fa200a3f8f9da099c278f32))
343   ROM_REGION(0x10000, "maincpu", 0)
344   ROM_LOAD("u5_cf.bin", 0x0000, 0x0800, CRC(e0d4b405) SHA1(17aadd79c0dcbb336aadd5d203bc6ca866492345))
345   ROM_LOAD("u4_ce.bin", 0x0800, 0x0800, CRC(4cd312dd) SHA1(31245daa9972ef8652caee69986585bb8239e86e))
346   ROM_LOAD("427.cpu", 0x2000, 0x0400, CRC(c496393d) SHA1(e91d9596aacdb4277fa200a3f8f9da099c278f32))
385347ROM_END
386348
387349/*-------------------------------------------------------------------
388350/ Roller Disco (02/1980) #440
389351/-------------------------------------------------------------------*/
390352ROM_START(roldisco)
391    ROM_REGION(0x10000, "maincpu", 0)
392    ROM_LOAD("u5_cf.bin", 0x0000, 0x0800, CRC(e0d4b405) SHA1(17aadd79c0dcbb336aadd5d203bc6ca866492345))
393    ROM_LOAD("u4_ce.bin", 0x0800, 0x0800, CRC(4cd312dd) SHA1(31245daa9972ef8652caee69986585bb8239e86e))
394    ROM_LOAD("440.cpu", 0x2000, 0x0400, CRC(bc50631f) SHA1(6aa3124d09fc4e369d087a5ad6dd1737ace55e41))
395    ROM_REGION(0x10000, "cpu2", 0)
396    ROM_LOAD("440.snd", 0x0400, 0x0400, CRC(4a0a05ae) SHA1(88f21b5638494d8e78dc0b6b7d69873b76b5f75d))
397    ROM_RELOAD( 0x0800, 0x0400)
398    ROM_LOAD("6530sys1.bin", 0x0c00, 0x0400, CRC(b7831321) SHA1(c94f4bee97854d0373653a6867016e27d3fc1340))
399    ROM_RELOAD( 0xfc00, 0x0400)
353   ROM_REGION(0x10000, "maincpu", 0)
354   ROM_LOAD("u5_cf.bin", 0x0000, 0x0800, CRC(e0d4b405) SHA1(17aadd79c0dcbb336aadd5d203bc6ca866492345))
355   ROM_LOAD("u4_ce.bin", 0x0800, 0x0800, CRC(4cd312dd) SHA1(31245daa9972ef8652caee69986585bb8239e86e))
356   ROM_LOAD("440.cpu", 0x2000, 0x0400, CRC(bc50631f) SHA1(6aa3124d09fc4e369d087a5ad6dd1737ace55e41))
357   ROM_REGION(0x10000, "cpu2", 0)
358   ROM_LOAD("440.snd", 0x0400, 0x0400, CRC(4a0a05ae) SHA1(88f21b5638494d8e78dc0b6b7d69873b76b5f75d))
359   ROM_RELOAD( 0x0800, 0x0400)
360   ROM_LOAD("6530sys1.bin", 0x0c00, 0x0400, CRC(b7831321) SHA1(c94f4bee97854d0373653a6867016e27d3fc1340))
361   ROM_RELOAD( 0xfc00, 0x0400)
400362ROM_END
401363
402364/*-------------------------------------------------------------------
r242208r242209
407369/ Sinbad (05/1978) #412
408370/-------------------------------------------------------------------*/
409371ROM_START(sinbad)
410    ROM_REGION(0x10000, "maincpu", 0)
411    ROM_LOAD("u5_cf.bin", 0x0000, 0x0800, CRC(e0d4b405) SHA1(17aadd79c0dcbb336aadd5d203bc6ca866492345))
412    ROM_LOAD("u4_ce.bin", 0x0800, 0x0800, CRC(4cd312dd) SHA1(31245daa9972ef8652caee69986585bb8239e86e))
413    ROM_LOAD("412.cpu", 0x2000, 0x0400, CRC(84a86b83) SHA1(f331f2ffd7d1b279b4ffbb939aa8649e723f5fac))
372   ROM_REGION(0x10000, "maincpu", 0)
373   ROM_LOAD("u5_cf.bin", 0x0000, 0x0800, CRC(e0d4b405) SHA1(17aadd79c0dcbb336aadd5d203bc6ca866492345))
374   ROM_LOAD("u4_ce.bin", 0x0800, 0x0800, CRC(4cd312dd) SHA1(31245daa9972ef8652caee69986585bb8239e86e))
375   ROM_LOAD("412.cpu", 0x2000, 0x0400, CRC(84a86b83) SHA1(f331f2ffd7d1b279b4ffbb939aa8649e723f5fac))
414376ROM_END
415377
416378ROM_START(sinbadn)
417    ROM_REGION(0x10000, "maincpu", 0)
418    ROM_LOAD("u5_cf.bin", 0x0000, 0x0800, CRC(e0d4b405) SHA1(17aadd79c0dcbb336aadd5d203bc6ca866492345))
419    ROM_LOAD("u4_ce.bin", 0x0800, 0x0800, CRC(4cd312dd) SHA1(31245daa9972ef8652caee69986585bb8239e86e))
420    ROM_LOAD("412no1.cpu", 0x2000, 0x0400, CRC(f5373f5f) SHA1(027840501416ff01b2adf07188c7d667adf3ad5f))
379   ROM_REGION(0x10000, "maincpu", 0)
380   ROM_LOAD("u5_cf.bin", 0x0000, 0x0800, CRC(e0d4b405) SHA1(17aadd79c0dcbb336aadd5d203bc6ca866492345))
381   ROM_LOAD("u4_ce.bin", 0x0800, 0x0800, CRC(4cd312dd) SHA1(31245daa9972ef8652caee69986585bb8239e86e))
382   ROM_LOAD("412no1.cpu", 0x2000, 0x0400, CRC(f5373f5f) SHA1(027840501416ff01b2adf07188c7d667adf3ad5f))
421383ROM_END
422384
423385/*-------------------------------------------------------------------
r242208r242209
428390/ Solar Ride (02/1979) #421
429391/-------------------------------------------------------------------*/
430392ROM_START(solaride)
431    ROM_REGION(0x10000, "maincpu", 0)
432    ROM_LOAD("u5_cf.bin", 0x0000, 0x0800, CRC(e0d4b405) SHA1(17aadd79c0dcbb336aadd5d203bc6ca866492345))
433    ROM_LOAD("u4_ce.bin", 0x0800, 0x0800, CRC(4cd312dd) SHA1(31245daa9972ef8652caee69986585bb8239e86e))
434    ROM_LOAD("421.cpu", 0x2000, 0x0400, CRC(6b5c5da6) SHA1(a09b7009473be53586f53f48b7bfed9a0c5ecd55))
393   ROM_REGION(0x10000, "maincpu", 0)
394   ROM_LOAD("u5_cf.bin", 0x0000, 0x0800, CRC(e0d4b405) SHA1(17aadd79c0dcbb336aadd5d203bc6ca866492345))
395   ROM_LOAD("u4_ce.bin", 0x0800, 0x0800, CRC(4cd312dd) SHA1(31245daa9972ef8652caee69986585bb8239e86e))
396   ROM_LOAD("421.cpu", 0x2000, 0x0400, CRC(6b5c5da6) SHA1(a09b7009473be53586f53f48b7bfed9a0c5ecd55))
435397ROM_END
436398
437399/*-------------------------------------------------------------------
438400/ The Incredible Hulk (10/1979) #433
439401/-------------------------------------------------------------------*/
440402ROM_START(hulk)
441    ROM_REGION(0x10000, "maincpu", 0)
442    ROM_LOAD("u5_cf.bin", 0x0000, 0x0800, CRC(e0d4b405) SHA1(17aadd79c0dcbb336aadd5d203bc6ca866492345))
443    ROM_LOAD("u4_ce.bin", 0x0800, 0x0800, CRC(4cd312dd) SHA1(31245daa9972ef8652caee69986585bb8239e86e))
444    ROM_LOAD("433.cpu", 0x2000, 0x0400, CRC(c05d2b52) SHA1(393fe063b029246317c90ee384db95a84d61dbb7))
445    ROM_REGION(0x10000, "cpu2", 0)
446    ROM_LOAD("433.snd", 0x0400, 0x0400, CRC(20cd1dff) SHA1(93e7c47ff7051c3c0dc9f8f95aa33ba094e7cf25))
447    ROM_RELOAD( 0x0800, 0x0400)
448    ROM_LOAD("6530sys1.bin", 0x0c00, 0x0400, CRC(b7831321) SHA1(c94f4bee97854d0373653a6867016e27d3fc1340))
449    ROM_RELOAD( 0xfc00, 0x0400)
403   ROM_REGION(0x10000, "maincpu", 0)
404   ROM_LOAD("u5_cf.bin", 0x0000, 0x0800, CRC(e0d4b405) SHA1(17aadd79c0dcbb336aadd5d203bc6ca866492345))
405   ROM_LOAD("u4_ce.bin", 0x0800, 0x0800, CRC(4cd312dd) SHA1(31245daa9972ef8652caee69986585bb8239e86e))
406   ROM_LOAD("433.cpu", 0x2000, 0x0400, CRC(c05d2b52) SHA1(393fe063b029246317c90ee384db95a84d61dbb7))
407   ROM_REGION(0x10000, "cpu2", 0)
408   ROM_LOAD("433.snd", 0x0400, 0x0400, CRC(20cd1dff) SHA1(93e7c47ff7051c3c0dc9f8f95aa33ba094e7cf25))
409   ROM_RELOAD( 0x0800, 0x0400)
410   ROM_LOAD("6530sys1.bin", 0x0c00, 0x0400, CRC(b7831321) SHA1(c94f4bee97854d0373653a6867016e27d3fc1340))
411   ROM_RELOAD( 0xfc00, 0x0400)
450412ROM_END
451413
452414/*-------------------------------------------------------------------
453415/ Torch (02/1980) #438
454416/-------------------------------------------------------------------*/
455417ROM_START(torch)
456    ROM_REGION(0x10000, "maincpu", 0)
457    ROM_LOAD("u5_cf.bin", 0x0000, 0x0800, CRC(e0d4b405) SHA1(17aadd79c0dcbb336aadd5d203bc6ca866492345))
458    ROM_LOAD("u4_ce.bin", 0x0800, 0x0800, CRC(4cd312dd) SHA1(31245daa9972ef8652caee69986585bb8239e86e))
459    ROM_LOAD("438.cpu", 0x2000, 0x0400, CRC(2d396a64) SHA1(38a1862771500faa471071db08dfbadc6e8759e8))
460    ROM_REGION(0x10000, "cpu2", 0)
461    ROM_LOAD("438.snd", 0x0400, 0x0400, CRC(a9619b48) SHA1(1906bc1b059bf31082e3b4546f5a30159479ad3c))
462    ROM_RELOAD( 0x0800, 0x0400)
463    ROM_LOAD("6530sys1.bin", 0x0c00, 0x0400, CRC(b7831321) SHA1(c94f4bee97854d0373653a6867016e27d3fc1340))
464    ROM_RELOAD( 0xfc00, 0x0400)
418   ROM_REGION(0x10000, "maincpu", 0)
419   ROM_LOAD("u5_cf.bin", 0x0000, 0x0800, CRC(e0d4b405) SHA1(17aadd79c0dcbb336aadd5d203bc6ca866492345))
420   ROM_LOAD("u4_ce.bin", 0x0800, 0x0800, CRC(4cd312dd) SHA1(31245daa9972ef8652caee69986585bb8239e86e))
421   ROM_LOAD("438.cpu", 0x2000, 0x0400, CRC(2d396a64) SHA1(38a1862771500faa471071db08dfbadc6e8759e8))
422   ROM_REGION(0x10000, "cpu2", 0)
423   ROM_LOAD("438.snd", 0x0400, 0x0400, CRC(a9619b48) SHA1(1906bc1b059bf31082e3b4546f5a30159479ad3c))
424   ROM_RELOAD( 0x0800, 0x0400)
425   ROM_LOAD("6530sys1.bin", 0x0c00, 0x0400, CRC(b7831321) SHA1(c94f4bee97854d0373653a6867016e27d3fc1340))
426   ROM_RELOAD( 0xfc00, 0x0400)
465427ROM_END
466428
467429/*-------------------------------------------------------------------
468430/ Totem (10/1979) #429
469431/-------------------------------------------------------------------*/
470432ROM_START(totem)
471    ROM_REGION(0x10000, "maincpu", 0)
472    ROM_LOAD("u5_cf.bin", 0x0000, 0x0800, CRC(e0d4b405) SHA1(17aadd79c0dcbb336aadd5d203bc6ca866492345))
473    ROM_LOAD("u4_ce.bin", 0x0800, 0x0800, CRC(4cd312dd) SHA1(31245daa9972ef8652caee69986585bb8239e86e))
474    ROM_LOAD("429.cpu", 0x2000, 0x0400, CRC(7885a384) SHA1(1770662af7d48ad8297097a9877c5c497119978d))
475    ROM_REGION(0x10000, "cpu2", 0)
476    ROM_LOAD("429.snd", 0x0400, 0x0400, CRC(5d1b7ed4) SHA1(4a584f880e907fb21da78f3b3a0617f20599688f))
477    ROM_RELOAD( 0x0800, 0x0400)
478    ROM_LOAD("6530sys1.bin", 0x0c00, 0x0400, CRC(b7831321) SHA1(c94f4bee97854d0373653a6867016e27d3fc1340))
479    ROM_RELOAD( 0xfc00, 0x0400)
433   ROM_REGION(0x10000, "maincpu", 0)
434   ROM_LOAD("u5_cf.bin", 0x0000, 0x0800, CRC(e0d4b405) SHA1(17aadd79c0dcbb336aadd5d203bc6ca866492345))
435   ROM_LOAD("u4_ce.bin", 0x0800, 0x0800, CRC(4cd312dd) SHA1(31245daa9972ef8652caee69986585bb8239e86e))
436   ROM_LOAD("429.cpu", 0x2000, 0x0400, CRC(7885a384) SHA1(1770662af7d48ad8297097a9877c5c497119978d))
437   ROM_REGION(0x10000, "cpu2", 0)
438   ROM_LOAD("429.snd", 0x0400, 0x0400, CRC(5d1b7ed4) SHA1(4a584f880e907fb21da78f3b3a0617f20599688f))
439   ROM_RELOAD( 0x0800, 0x0400)
440   ROM_LOAD("6530sys1.bin", 0x0c00, 0x0400, CRC(b7831321) SHA1(c94f4bee97854d0373653a6867016e27d3fc1340))
441   ROM_RELOAD( 0xfc00, 0x0400)
480442ROM_END
481443
482444/*-------------------------------------------------------------------
483445/ System 1 Test prom
484446/-------------------------------------------------------------------*/
485447ROM_START(sys1test)
486    ROM_REGION(0x10000, "maincpu", 0)
487    ROM_LOAD("u5_cf.bin", 0x0000, 0x0800, CRC(e0d4b405) SHA1(17aadd79c0dcbb336aadd5d203bc6ca866492345))
488    ROM_LOAD("u4_ce.bin", 0x0800, 0x0800, CRC(4cd312dd) SHA1(31245daa9972ef8652caee69986585bb8239e86e))
489    ROM_LOAD("test.cpu", 0x2000, 0x0400, CRC(8b0704bb) SHA1(5f0eb8d5af867b815b6012c9d078927398efe6d8))
448   ROM_REGION(0x10000, "maincpu", 0)
449   ROM_LOAD("u5_cf.bin", 0x0000, 0x0800, CRC(e0d4b405) SHA1(17aadd79c0dcbb336aadd5d203bc6ca866492345))
450   ROM_LOAD("u4_ce.bin", 0x0800, 0x0800, CRC(4cd312dd) SHA1(31245daa9972ef8652caee69986585bb8239e86e))
451   ROM_LOAD("test.cpu", 0x2000, 0x0400, CRC(8b0704bb) SHA1(5f0eb8d5af867b815b6012c9d078927398efe6d8))
490452ROM_END
491453
492454
trunk/src/mame/drivers/naomi.c
r242208r242209
259259Ferrari F355 Challenge (twin, prototype)        no cart  22848P* 21 (64Mb)   present  315-6206  317-0267-COM  * flash-PCB have CRC 330B A417, the rest is the same as regular cart, not dumped but known to exist
260260Ferrari F355 Challenge 2 (twin)                 no cart  23399   21 (64Mb)   present  315-6206  317-0287-COM  content is the same as regular 171-7919A cart
261261House of the Dead 2 (prototype)                 no cart  A1E2    21 (64Mb)   present  315-6206  present       no label on IC42
262Inu No Osanpo / Dog Walking (Rev A)           840-0073C  22294A  16 (64Mb)   present  315-6206  317-0316-JPN  requires 837-13844 JVS IO with DIPSW 1 ON
262Inu No Osanpo / Dog Walking (Rev A)           840-0073C  22294A  16 (64Mb)   present  315-6206  317-0316-JPN  requires 837-13844 JVS IO with special jumpers settings enabling rotary
263263Maze of the Kings The (prototype)               no cart  *       21 (64Mb)   present  315-6206  FRI           * flash-PCB, not dumped but known to exist
264264Samba de Amigo (prototype)                      no cart  *       21 (64Mb)   present  315-6206  317-0270-COM  * instead of EPROM have tiny PCB with 2 flashroms on it
265265Soul Surfer (Rev A)                           840-0095C  23838C  21 (64Mb)   present  315-6206  not present
r242208r242209
335335Puyo Puyo Da!                                   841-0006C    22206   20 (64Mb)   ?           315-6213  ?
336336Ring Out 4x4                                    840-0004C    21779   10 (64Mb)   present     315-6213  317-0250-COM   requires 2 JVS boards
337337Samba de Amigo (Rev B)                          840-0020C    22966B  16 (64Mb)   present     315-6213  317-0270-COM   will boot but requires special controller to play it
338Sega Marine Fishing                             840-0027C    22221   10 (64Mb)   ?           315-6213  not present    ROM 3&4 not present. Requires 837-13844 JVS IO with all DIPSW Off and fishing controller
338Sega Marine Fishing                             840-0027C    22221   10 (64Mb)   ?           315-6213  not present    ROM 3&4 not present. Requires fishing controller
339339Sega Strike Fighter (Rev A, set 1)              840-0035C    23323A  20 (64Mb)   present     315-6213  317-0281-COM   have "Rev. A" label on case
340340Sega Strike Fighter (Rev A, set 2)              840-0035C    23786A  20 (64Mb)   present     315-6213  317-0281-COM   have "Rev. A" label on PCB
341341Sega Tetris                                     840-0018C    22909    6 (64Mb)   present     315-6213  317-0268-COM
r242208r242209
343343Spawn In the Demon's Hand (Rev B)               841-0005C    22977B  10 (64Mb)   ?           315-6213  317-5051-COM   joystick + 4 buttons
344344Super Major League '99                          840-0012C    22059   21 (64Mb)   ?           315-6213  ?
345345The Typing of the Dead (Rev A)                  840-0026C    23021A  20 (64Mb)   present     315-6213  not present
346Touch de UNO! / Unou Nouryoku Check Machine     840-0008C    22073    4 (64Mb)   present     315-6213  317-0255-JPN   requires 837-13844 JVS IO with DIPSW 5 On, ELO AccuTouch-compatible touch screen controller and special printer.
346Touch de UNO! / Unou Nouryoku Check Machine     840-0008C    22073    4 (64Mb)   present     315-6213  317-0255-JPN   requires special JVS board with touch input and printer
347347Toy Fighter / Waffupu                           840-0011C    22035   10 (64Mb)   present     315-6212  317-0257-COM   joystick + 3 buttons
348348Virtua NBA                                      840-0021C-01 23073   21 (64Mb)   present     315-6213  not present
349349Virtua NBA (original)                           840-0021C    22949   21 (64Mb)   present     315-6213  317-0271-COM
r242208r242209
460460Shootout Pool Prize / The Medal (Rev A)        840-0128C    24065A   4 (64Mb)   present  317-0367-COM  requires Naomi-based hopper controller
461461Shootout Pool Prize / The Medal Ver. B         840-0136C    24148    4 (64Mb)   present  317-0367-COM  requires Naomi-based or 837-14438 hopper controller
462462SWP Hopper Board                               840-0130C    24083   20 (64Mb)   present  317-0339-COM  Maskroms are not really used, they are recycled from other games; there is an additional 837-14381 IO board
463Touch de UNO! 2                                840-0022C    23071    6 (64Mb)   present  317-0276-JPN  requires 837-13844 JVS IO with DIPSW 5 On, ELO AccuTouch-compatible touch screen controller and special printer.
463Touch de UNO! 2                                840-0022C    23071    6 (64Mb)   present  317-0276-JPN  requires special JVS board with touch input and printer
464464Virtua Fighter 4 Evolution                     840-0106B    23934   20 (64Mb)   present  317-0339-COM
465465Virtua Tennis 2 / Power Smash 2 (Rev A)        840-0084C    22327A  18 (64Mb)   present  317-0320-COM
466466
r242208r242209
888888|-----------------------------|
889889Notes: (most info taken from poor quality pics/scans, better info is needed)
890890
891             JVS I/O board 2. Supports digital and analogue inputs, rotary input,
892             touch screens (ELO AccuTouch-compatible) and printer output using
893             extended JVS commands. This features can be enabled or disabled
894             by switching DIPSW 1-5.
891             JVS I/O board 2. Has both digital and analogue inputs.
895892             This board is used with F355, Ghost Squad, and many
896893             others including network/satellite games.
897894
r242208r242209
912909      IC7  - 27C512 EPROM with label 'EPR-22082' (DIP28)
913910             On plain 837-13844 (no -02) this is 'EPR-21868' (DIP28)
914911      IC8  - Sharp LH52256 32k x8 SRAM (SOP28)
915      IC10 - NEC D71054GB programmable counter/timer (QFP44)
912      IC10 - Something by NEC? (QFP44)
916913      OSC1 - 14.7456MHz
917914      OSC2 - 32MHz
918915      CNx  - 6 pin connector
r242208r242209
56345631   ROM_LOAD( "fpr-24333.ic8", 0x0000000, 0x4000000, CRC(a467b69c) SHA1(66a841b72ef1bb8cbabbfb1d14081b4dff14b1d3) )
56355632   ROM_LOAD( "fpr-24334.ic9", 0x4000000, 0x4000000, CRC(13d2d1dc) SHA1(6a47cfaddf006e6ff46837fac956fbcc20619d79) )
56365633
5637   ROM_REGION( 0x800, "pic_readout", 0 )
5638   ROM_LOAD( "317-0437-com.ic3", 0, 0x800, BAD_DUMP CRC(b6e4f61a) SHA1(b5cae574170afa3889e01517f1c4429e207042b9) )
5634   // ROM_REGION( 4, "rom_key", 0 )
5635   // ROM_LOAD( "mushik2e-key.bin", 0, 4, CRC(b32a0633) SHA1(984c01e43cf359d8e8a0c6cb1a04c5dc3da47d39) )
5636   ROM_REGION( 20, "pic_readout", 0 ) // data obtained using a custom PIC reader
5637   ROM_LOAD( "317-0437-com.ic3", 0, 20, NO_DUMP )
56395638
56405639   ROM_REGION(0x4, "boardid", ROMREGION_ERASEVAL(0x02))
56415640ROM_END
r242208r242209
56495648   ROM_LOAD( "epr-24357.ic7", 0x0000000, 0x0400000, CRC(a2236d58) SHA1(3746b9d3c0f7ecf6340619bb8bf01f170ac4efb7) ) // EPR mode, overwrite FPR data
56505649   ROM_LOAD( "fpr-24334.ic9", 0x4000000, 0x4000000, CRC(13d2d1dc) SHA1(6a47cfaddf006e6ff46837fac956fbcc20619d79) )
56515650
5652   ROM_REGION( 0x800, "pic_readout", 0 )
5653   ROM_LOAD( "317-0437-com.ic3", 0, 0x800, BAD_DUMP CRC(b6e4f61a) SHA1(b5cae574170afa3889e01517f1c4429e207042b9) )
5651   // ROM_REGION( 4, "rom_key", 0 )
5652   // ROM_LOAD( "mushik2e-key.bin", 0, 4, CRC(b32a0633) SHA1(984c01e43cf359d8e8a0c6cb1a04c5dc3da47d39) )
5653   ROM_REGION( 20, "pic_readout", 0 ) // data obtained using a custom PIC reader
5654   ROM_LOAD( "317-0437-com.ic3", 0, 20, NO_DUMP )
56545655
56555656   ROM_REGION(0x4, "boardid", ROMREGION_ERASEVAL(0x82))
56565657ROM_END
r242208r242209
56635664   ROM_LOAD( "fpr-24338.ic8", 0x0000000, 0x4000000, CRC(1423c374) SHA1(e6a3f0eaccd13c161d07705bcd00f447f08fc186) )
56645665   ROM_LOAD( "fpr-24339.ic9", 0x4000000, 0x4000000, CRC(11883792) SHA1(1782db04f74394f981f887ab1a95d687eb2c0b35) )
56655666
5666   ROM_REGION( 0x800, "pic_readout", 0 )
5667   ROM_LOAD( "317-0435-jpn.ic3", 0, 0x800, BAD_DUMP CRC(b553d900) SHA1(ed1c3c2053f2c0e98cb5c4d99f93143a66c29e5c) )
5667   // ROM_REGION( 4, "rom_key", 0 )
5668   // ROM_LOAD( "zunou-key.bin", 0, 4, CRC(cbe35afb) SHA1(78877655800aae27661bf720e1c37d6c6f2e3d1c) )
5669   ROM_REGION( 20, "pic_readout", 0 ) // data obtained using a custom PIC reader
5670   ROM_LOAD( "317-0435-jpn.ic3", 0, 20, NO_DUMP )
56685671
56695672   ROM_REGION(0x4, "boardid", ROMREGION_ERASEVAL(0x02))
56705673ROM_END
r242208r242209
56795682   ROM_LOAD( "fpr-24415.ic10", 0x8000000, 0x4000000, CRC(133c742c) SHA1(89f857a31731dc918afc72b6cb716f5c77cb9d6e) )
56805683   ROM_LOAD( "fpr-24416.ic11", 0xc000000, 0x4000000, CRC(562fb88e) SHA1(172678e3e27cfad7f7e6217c4653a4ba119bfbdf) )
56815684
5682   ROM_REGION( 0x800, "pic_readout", 0 )
5683   ROM_LOAD( "317-5129-jpn.ic3", 0, 0x800, CRC(432ba30f) SHA1(4935a16d1075430799269ac7ac990066d44d815b) )
5685   ROM_REGION( 20, "pic_readout", 0 ) // data obtained using a custom PIC reader
5686   ROM_LOAD( "317-5129-jpn.ic3", 0, 20, CRC(b6191cea) SHA1(13e14ff013bf2728203641303141c016e82b10a3) )
56845687
56855688   ROM_REGION(0x4, "boardid", ROMREGION_ERASEVAL(0x04))
56865689ROM_END
r242208r242209
56955698   ROM_LOAD( "fpr-24384.ic10", 0x8000000, 0x4000000, CRC(2e9116c4) SHA1(58903a33c4ce72a1f75aefcab94393fc2e8bd2d9) )
56965699   ROM_LOAD( "fpr-24385.ic11", 0xc000000, 0x4000000, CRC(2b79f45d) SHA1(db97d980bf1590df4b983a4b7786977687238ef5) )
56975700
5698   ROM_REGION( 0x800, "pic_readout", 0 )
5699   ROM_LOAD( "317-0495-com.ic3", 0, 0x800, CRC(c229a59b) SHA1(497dcc1e4e52eb044a8b709edbd00126cef212b1) )
5701   ROM_REGION( 20, "pic_readout", 0 ) // data obtained using a custom PIC reader
5702   ROM_LOAD( "317-0495-com.ic3", 0, 20, CRC(675aca7b) SHA1(5127189e1f960abf9ed3f643158747d9abcaee1c) )
57005703
57015704   ROM_REGION(0x4, "boardid", ROMREGION_ERASEVAL(0x04))
57025705ROM_END
r242208r242209
57115714   ROM_LOAD( "fpr-24439.ic10", 0x8000000, 0x4000000, CRC(c02040f9) SHA1(27ad2cb45e8a516433917f060ca9798412bb95f7) )
57125715   // IC11 Populated, Empty
57135716
5714   ROM_REGION( 0x800, "pic_readout", 0 )
5715   ROM_LOAD( "317-5131-jpn.ic3", 0, 0x800, CRC(af4b38f2) SHA1(9b82f16a258854d7d618d60f9a610f7d47d67a78) )
5717   ROM_REGION( 20, "pic_readout", 0 ) // data obtained using a custom PIC reader
5718   ROM_LOAD( "317-5131-jpn.ic3", 0, 20, CRC(44ab8ca9) SHA1(c17b10041e70590547ed010dc16a4dd2510fcc80) )
57165719
57175720   ROM_REGION(0x4, "boardid", ROMREGION_ERASEVAL(0x04))
57185721ROM_END
r242208r242209
57275730   ROM_LOAD( "ic10.bin", 0x8000000, 0x4000000, CRC(76fb945f) SHA1(448be0c3d9a7c3956dd51aca3c4d8d28f8cec227) )
57285731   // IC11 Populated, Empty
57295732
5730   ROM_REGION( 0x800, "pic_readout", 0 )
5731   ROM_LOAD( "317-5132-jpn.ic3", 0, 0x800, CRC(d56e70a1) SHA1(fda1a2989f0fa3b0edeb292cdd4537d9b86af6f2) )
5733   ROM_REGION( 20, "pic_readout", 0 ) // data obtained using a custom PIC reader
5734   ROM_LOAD( "317-5132-jpn.ic3", 0, 20, CRC(f2089de5) SHA1(12af0681decb22bbfa4b3e01037c3503846f265a) )
57325735
57335736   ROM_REGION(0x4, "boardid", ROMREGION_ERASEVAL(0x04))
57345737ROM_END
r242208r242209
57455748   ROM_LOAD( "ic12.bin",     0x10000000, 0x4000000, CRC(b8a6bff2) SHA1(befbc2e917b3107f1c4bfb9169623282ff97bfb2) )
57465749   ROM_LOAD( "ic13.bin",     0x14000000, 0x4000000, CRC(4886329f) SHA1(6ccf6fb83cfdbef3f85f6c06e641c38ff434d605) )
57475750
5748   ROM_REGION( 0x800, "pic_readout", 0 )
5749   ROM_LOAD( "317-5133-jpn.ic3", 0, 0x800, CRC(0f16d180) SHA1(9d4ae15aa54752cdbd8e279388b7f3ae20777172) )
5751   ROM_REGION( 20, "pic_readout", 0 ) // data obtained using a custom PIC reader
5752   ROM_LOAD( "317-5133-jpn.ic3", 0, 20, CRC(3dc7d902) SHA1(bb70e80dff878bca3652088f3333079e0781f482) )
57505753
57515754   ROM_REGION(0x4, "boardid", ROMREGION_ERASEVAL(0x06))
57525755ROM_END
r242208r242209
57645767   ROM_LOAD( "ic12.bin",     0x10000000, 0x4000000, CRC(b8a6bff2) SHA1(befbc2e917b3107f1c4bfb9169623282ff97bfb2) )
57655768   ROM_LOAD( "ic13.bin",     0x14000000, 0x4000000, CRC(4886329f) SHA1(6ccf6fb83cfdbef3f85f6c06e641c38ff434d605) )
57665769
5767   ROM_REGION( 0x800, "pic_readout", 0 )
5768   ROM_LOAD( "317-5133-jpn.ic3", 0, 0x800, CRC(0f16d180) SHA1(9d4ae15aa54752cdbd8e279388b7f3ae20777172) )
5770   ROM_REGION( 20, "pic_readout", 0 ) // data obtained using a custom PIC reader
5771   ROM_LOAD( "317-5133-jpn.ic3", 0, 20, CRC(3dc7d902) SHA1(bb70e80dff878bca3652088f3333079e0781f482) )
57695772
57705773   ROM_REGION(0x4, "boardid", ROMREGION_ERASEVAL(0x86))
57715774ROM_END
r242208r242209
57795782   ROM_LOAD( "ic9.bin", 0x4000000, 0x4000000, CRC(16cf2e7a) SHA1(ff7c6540e4507f84e3128ba03be4826ba504678c) )
57805783   // IC10 and IC11 Populated, Empty
57815784
5782   ROM_REGION( 0x800, "pic_readout", 0 )
5783   ROM_LOAD( "317-5138-jpn.ic3", 0, 0x800, CRC(93b7a03d) SHA1(7af7c8d436f61e57b9d5957431c6fc745442f74f) )
5785   ROM_REGION( 20, "pic_readout", 0 ) // data obtained using a custom PIC reader
5786   ROM_LOAD( "317-5138-jpn.ic3", 0, 20, CRC(babcc420) SHA1(653cdcfa388426f4ce03c76506046ec6fd070562) )
57845787
57855788   ROM_REGION(0x4, "boardid", ROMREGION_ERASEVAL(0x04))
57865789ROM_END
r242208r242209
57945797   ROM_LOAD( "ic9.bin",    0x4000000, 0x4000000, CRC(18c994d7) SHA1(159e1425b2fc645133814b0d26d93a90e9849b1a) )
57955798   // IC10 and IC11 Populated, Empty
57965799
5797   ROM_REGION( 0x800, "pic_readout", 0 )
5798   ROM_LOAD( "317-05130-jpn.ic3", 0, 0x800, CRC(eccdcd59) SHA1(9f374e0b37f18591c92c38c83c9310f2db0abf9c) )
5800   ROM_REGION( 20, "pic_readout", 0 ) // data obtained using a custom PIC reader
5801   ROM_LOAD( "317-5130-jpn.ic3", 0, 20, CRC(3e0c010b) SHA1(b6da97d4ecb228e73fb9a5ada837d0d6699ab0f1) )
57995802
58005803   ROM_REGION(0x4, "boardid", ROMREGION_ERASEVAL(0x04))
58015804ROM_END
r242208r242209
58145817   ROM_REGION( 0x200000, "ioboard", 0) // touch screen I/O board, program disassembles as little-endian SH-4
58155818   ROM_LOAD( "fpr24351.ic14", 0x000000, 0x200000, CRC(4d1b7b89) SHA1(965b8c6b5a2e7b3f1b1e2eac19c86000c3b66754) )
58165819
5817   ROM_REGION( 0x800, "pic_readout", 0 )
5818   ROM_LOAD( "317-0461-com.ic3", 0, 0x800, BAD_DUMP CRC(c9282cdd) SHA1(23933e489d763515428e2714cc6e7676df1d5323) )
5820   // ROM_REGION( 4, "rom_key", 0 )
5821   // ROM_LOAD( "pokasuka-key.bin", 0, 4, CRC(f00bcd61) SHA1(b8315b851656c2e0b7853979988d1c44eab0886b) )
5822   ROM_REGION( 20, "pic_readout", 0 ) // data obtained using a custom PIC reader
5823   ROM_LOAD( "317-0461-com.ic3", 0, 20, NO_DUMP )
58195824
58205825   ROM_REGION(0x4, "boardid", ROMREGION_ERASEVAL(0x05))
58215826ROM_END
r242208r242209
58345839   ROM_REGION( 0x200000, "ioboard", 0) // touch screen I/O board, program disassembles as little-endian SH-4
58355840   ROM_LOAD( "fpr24351.ic14", 0x000000, 0x200000, CRC(4d1b7b89) SHA1(965b8c6b5a2e7b3f1b1e2eac19c86000c3b66754) )
58365841
5837   ROM_REGION( 0x800, "pic_readout", 0 )
5838   ROM_LOAD( "317-0461-com.ic3", 0, 0x800, BAD_DUMP CRC(c9282cdd) SHA1(23933e489d763515428e2714cc6e7676df1d5323) )
5842   // ROM_REGION( 4, "rom_key", 0 )
5843   // ROM_LOAD( "pokasuka-key.bin", 0, 4, CRC(f00bcd61) SHA1(b8315b851656c2e0b7853979988d1c44eab0886b) )
5844   ROM_REGION( 20, "pic_readout", 0 ) // data obtained using a custom PIC reader
5845   ROM_LOAD( "317-0461-com.ic3", 0, 20, NO_DUMP )
58395846
58405847   ROM_REGION(0x4, "boardid", ROMREGION_ERASEVAL(0x05))
58415848ROM_END
r242208r242209
58535860   ROM_LOAD( "fpr-24425.ic10", 0x08000000, 0x4000000, CRC(6223ebac) SHA1(64c0ec61c108acbb557e7d3837f578deba832cb6) )
58545861   ROM_LOAD( "fpr-24426.ic11", 0x0c000000, 0x4000000, CRC(c78b0981) SHA1(f889acf9065566e11ff985a3b6c4824e364d57ae) )
58555862
5856   ROM_REGION( 0x800, "pic_readout", 0 )
5857   ROM_LOAD( "317-0503-jpn.ic3", 0, 0x800, CRC(6eb0976b) SHA1(d5d0fc09a0c0e3a8f2703c450f05f5082317fbe4) )
5863   ROM_REGION( 20, "pic_readout", 0 ) // data obtained using a custom PIC reader
5864   ROM_LOAD( "317-0503-jpn.ic3", 0, 20, CRC(69fc3f47) SHA1(3a887c62e93fa264b307c954eb39a4fca1bdfad6) )
58585865
58595866   ROM_REGION(0x4, "boardid", ROMREGION_ERASEVAL(0x04))
58605867ROM_END
trunk/src/mame/includes/chihiro.h
r0r242209
1/*
2 * geforce 3d (NV2A) vertex program disassembler
3 */
4class vertex_program_disassembler {
5   static const char *srctypes[];
6   static const char *scaops[];
7   static const int scapar2[];
8   static const char *vecops[];
9   static const int vecpar2[];
10   static const char *vecouts[];
11   static const char compchar[];
12   int o[6];
13   int state;
14
15   struct sourcefields
16   {
17      int Sign;
18      int SwizzleX;
19      int SwizzleY;
20      int SwizzleZ;
21      int SwizzleW;
22      int TempIndex;
23      int ParameterType;
24   };
25
26   struct fields
27   {
28      int ScaOperation;
29      int VecOperation;
30      int SourceConstantIndex;
31      int InputIndex;
32      sourcefields src[3];
33      int VecTempWriteMask;
34      int VecTempIndex;
35      int ScaTempWriteMask;
36      int OutputWriteMask;
37      int OutputSelect;
38      int OutputIndex;
39      int MultiplexerControl;
40      int Usea0x;
41      int EndOfProgram;
42   };
43   fields f;
44
45   void decodefields(unsigned int *dwords, int offset, fields &decoded);
46   int disassemble_mask(int mask, char *s);
47   int disassemble_swizzle(sourcefields f, char *s);
48   int disassemble_source(sourcefields f, fields fi, char *s);
49   int disassemble_output(fields f, char *s);
50   int output_types(fields f, int *o);
51public:
52   vertex_program_disassembler() { state = 0; }
53   int disassemble(unsigned int *instruction, char *line);
54};
55
56/*
57 * geforce 3d (NV2A) vertex structure
58 */
59struct vertex_nv {
60   union {
61      float fv[4];
62      UINT32 iv[4];
63   } attribute[16];
64};
65
66/*
67 * geforce 3d (NV2A) vertex program simulator
68 */
69class vertex_program_simulator {
70public:
71   vertex_program_simulator();
72   // input vertex
73   vertex_nv *input;
74   // input parameters
75   union constant {
76      float fv[4];
77      unsigned int iv[4];
78   } c_constant[192];
79   union temp {
80      float fv[4];
81      unsigned int iv[4];
82   } r_temp[32];
83   // output vertex
84   vertex_nv *output;
85   // instructions
86   struct instruction {
87      unsigned int i[4];
88      int modified;
89      struct decoded {
90         int SwizzleA[4], SignA, ParameterTypeA, TempIndexA;
91         int SwizzleB[4], SignB, ParameterTypeB, TempIndexB;
92         int SwizzleC[4], SignC, ParameterTypeC, TempIndexC;
93         int VecOperation, ScaOperation;
94         int OutputWriteMask, MultiplexerControl;
95         int VecTempWriteMask, ScaTempWriteMask;
96         int VecTempIndex, OutputIndex;
97         int InputIndex;
98         int SourceConstantIndex;
99         int OutputSelect;
100         int Usea0x;
101         int EndOfProgram;
102      } d;
103   } op[256];
104public:
105   void set_data(vertex_nv *in, vertex_nv *out);
106   void reset();
107   int step();
108   void decode_instruction(int address);
109   void execute();
110   void jump(int address);
111   void process(int address, vertex_nv *in, vertex_nv *out, int count);
112   int status();
113private:
114   void initialize_outputs();
115   void initialize_temps();
116   void initialize_constants();
117   void generate_input(float t[4], int sign, int type, int temp, int swizzle[4]);
118   void compute_vectorial_operation(float t[4], int instruction, float par[3 * 4]);
119   void compute_scalar_operation(float t[4], int instruction, float par[3 * 4]);
120
121   int ip;
122   int a0x;
123};
124
125class nv2a_renderer; // forward declaration
126struct nvidia_object_data
127{
128   nv2a_renderer *data;
129};
130
131/*
132 * geforce 3d (NV2A) accellerator
133 */
134/* very simplified view
135there is a set of context objects
136
137context objects are stored in RAMIN
138each context object is identified by an handle stored in RAMHT
139
140each context object can be assigned to a channel
141to assign you give to the channel an handle for the object
142
143offset in ramht=(((((handle >> 11) xor handle) >> 11) xor handle) & 0x7ff)*8
144offset in ramht contains the handle itself
145offset in ramht+4 contains in the lower 16 bits the offset in RAMIN divided by 16
146
147objects have methods used to do drawing
148most methods set parameters, others actually draw
149*/
150class nv2a_renderer : public poly_manager<float, nvidia_object_data, 12, 8192>
151{
152public:
153   nv2a_renderer(running_machine &machine) : poly_manager<float, nvidia_object_data, 12, 8192>(machine)
154   {
155      memset(channel, 0, sizeof(channel));
156      memset(pfifo, 0, sizeof(pfifo));
157      memset(pcrtc, 0, sizeof(pcrtc));
158      memset(pmc, 0, sizeof(pmc));
159      memset(ramin, 0, sizeof(ramin));
160      computedilated();
161      fb.allocate(640, 480);
162      objectdata = &(object_data_alloc());
163      objectdata->data = this;
164      combiner.used = 0;
165      combiner.lock = osd_lock_alloc();
166      enabled_vertex_attributes = 0;
167      indexesleft_count = 0;
168      vertex_pipeline = 4;
169      alpha_test_enabled = false;
170      alpha_reference = 0;
171      alpha_func = nv2a_renderer::ALWAYS;
172      blending_enabled = false;
173      blend_equation = nv2a_renderer::FUNC_ADD;
174      blend_color = 0;
175      blend_function_destination = nv2a_renderer::ZERO;
176      blend_function_source = nv2a_renderer::ONE;
177      logical_operation_enabled = false;
178      logical_operation = nv2a_renderer::COPY;
179      debug_grab_texttype = -1;
180      debug_grab_textfile = NULL;
181      memset(vertex_attribute_words, 0, sizeof(vertex_attribute_words));
182      memset(vertex_attribute_offset, 0, sizeof(vertex_attribute_offset));
183   }
184   DECLARE_READ32_MEMBER(geforce_r);
185   DECLARE_WRITE32_MEMBER(geforce_w);
186   bool vblank_callback(screen_device &screen, bool state);
187   UINT32 screen_update_callback(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
188
189   void render_texture_simple(INT32 scanline, const extent_t &extent, const nvidia_object_data &extradata, int threadid);
190   void render_color(INT32 scanline, const extent_t &extent, const nvidia_object_data &extradata, int threadid);
191   void render_register_combiners(INT32 scanline, const extent_t &extent, const nvidia_object_data &objectdata, int threadid);
192
193   int geforce_commandkind(UINT32 word);
194   UINT32 geforce_object_offset(UINT32 handle);
195   void geforce_read_dma_object(UINT32 handle, UINT32 &offset, UINT32 &size);
196   void geforce_exec_method(address_space &space, UINT32 channel, UINT32 subchannel, UINT32 method, UINT32 address, int &countlen);
197   UINT32 texture_get_texel(int number, int x, int y);
198   void write_pixel(int x, int y, UINT32 color);
199   void combiner_initialize_registers(UINT32 argb8[6]);
200   void combiner_initialize_stage(int stage_number);
201   void combiner_initialize_final();
202   void combiner_map_input(int stage_number); // map combiner registers to variables A..D
203   void combiner_map_output(int stage_number); // map combiner calculation results to combiner registers
204   void combiner_map_final_input(); // map final combiner registers to variables A..F
205   void combiner_final_output(); // generate final combiner output
206   float combiner_map_input_select(int code, int index); // get component index in register code
207   float *combiner_map_input_select3(int code); // get pointer to register code
208   float *combiner_map_output_select3(int code); // get pointer to register code for output
209   float combiner_map_input_function(int code, float value); // apply input mapping function code to value
210   void combiner_map_input_function3(int code, float *data); // apply input mapping function code to data
211   void combiner_function_AB(float result[4]);
212   void combiner_function_AdotB(float result[4]);
213   void combiner_function_CD(float result[4]);
214   void combiner_function_CdotD(float result[4]);
215   void combiner_function_ABmuxCD(float result[4]);
216   void combiner_function_ABsumCD(float result[4]);
217   void combiner_compute_rgb_outputs(int index);
218   void combiner_compute_a_outputs(int index);
219   void combiner_argb8_float(UINT32 color, float reg[4]);
220   UINT32 combiner_float_argb8(float reg[4]);
221   UINT32 dilate0(UINT32 value, int bits);
222   UINT32 dilate1(UINT32 value, int bits);
223   void computedilated(void);
224   void putpixtex(int xp, int yp, int up, int vp);
225   int toggle_register_combiners_usage();
226   void debug_grab_texture(int type, const char *filename);
227   void debug_grab_vertex_program_slot(int slot, UINT32 *instruction);
228   void savestate_items();
229
230   void read_vertex(address_space & space, offs_t address, vertex_nv &vertex, int attrib);
231   int read_vertices_0x1810(address_space & space, vertex_nv *destination, int offset, int limit);
232   int read_vertices_0x1800(address_space & space, vertex_nv *destination, UINT32 address, int limit);
233   int read_vertices_0x1818(address_space & space, vertex_nv *destination, UINT32 address, int limit);
234   void convert_vertices_poly(vertex_nv *source, vertex_t *destination, int count);
235
236   struct {
237      UINT32 regs[0x80 / 4];
238      struct {
239         UINT32 objhandle;
240         UINT32 objclass;
241         UINT32 method[0x2000 / 4];
242      } object;
243   } channel[32][8];
244   UINT32 pfifo[0x2000 / 4];
245   UINT32 pcrtc[0x1000 / 4];
246   UINT32 pmc[0x1000 / 4];
247   UINT32 ramin[0x100000 / 4];
248   UINT32 dma_offset[2];
249   UINT32 dma_size[2];
250   UINT32 vertexbuffer_address[16];
251   int vertexbuffer_stride[16];
252   int vertexbuffer_kind[16];
253   int vertexbuffer_size[16];
254   struct {
255      int enabled;
256      int sizeu;
257      int sizev;
258      int sizew;
259      int dilate;
260      int format;
261      int rectangle_pitch;
262      void *buffer;
263   } texture[4];
264   int primitives_count;
265   int indexesleft_count;
266   int indexesleft_first;
267   UINT32 indexesleft[8];
268   struct {
269      float variable_A[4]; // 0=R 1=G 2=B 3=A
270      float variable_B[4];
271      float variable_C[4];
272      float variable_D[4];
273      float variable_E[4];
274      float variable_F[4];
275      float variable_G;
276      float variable_EF[4];
277      float variable_sumclamp[4];
278      float function_RGBop1[4]; // 0=R 1=G 2=B
279      float function_RGBop2[4];
280      float function_RGBop3[4];
281      float function_Aop1;
282      float function_Aop2;
283      float function_Aop3;
284      float register_primarycolor[4]; // rw
285      float register_secondarycolor[4];
286      float register_texture0color[4];
287      float register_texture1color[4];
288      float register_texture2color[4];
289      float register_texture3color[4];
290      float register_color0[4];
291      float register_color1[4];
292      float register_spare0[4];
293      float register_spare1[4];
294      float register_fogcolor[4]; // ro
295      float register_zero[4];
296      float output[4];
297      struct {
298         float register_constantcolor0[4];
299         float register_constantcolor1[4];
300         int mapin_aA_input;
301         int mapin_aA_component;
302         int mapin_aA_mapping;
303         int mapin_aB_input;
304         int mapin_aB_component;
305         int mapin_aB_mapping;
306         int mapin_aC_input;
307         int mapin_aC_component;
308         int mapin_aC_mapping;
309         int mapin_aD_input;
310         int mapin_aD_component;
311         int mapin_aD_mapping;
312         int mapin_rgbA_input;
313         int mapin_rgbA_component;
314         int mapin_rgbA_mapping;
315         int mapin_rgbB_input;
316         int mapin_rgbB_component;
317         int mapin_rgbB_mapping;
318         int mapin_rgbC_input;
319         int mapin_rgbC_component;
320         int mapin_rgbC_mapping;
321         int mapin_rgbD_input;
322         int mapin_rgbD_component;
323         int mapin_rgbD_mapping;
324         int mapout_aCD_output;
325         int mapout_aAB_output;
326         int mapout_aSUM_output;
327         int mapout_aCD_dotproduct;
328         int mapout_aAB_dotproduct;
329         int mapout_a_muxsum;
330         int mapout_a_bias;
331         int mapout_a_scale;
332         int mapout_rgbCD_output;
333         int mapout_rgbAB_output;
334         int mapout_rgbSUM_output;
335         int mapout_rgbCD_dotproduct;
336         int mapout_rgbAB_dotproduct;
337         int mapout_rgb_muxsum;
338         int mapout_rgb_bias;
339         int mapout_rgb_scale;
340      } stage[8];
341      struct {
342         float register_constantcolor0[4];
343         float register_constantcolor1[4];
344         int color_sum_clamp;
345         int mapin_rgbA_input;
346         int mapin_rgbA_component;
347         int mapin_rgbA_mapping;
348         int mapin_rgbB_input;
349         int mapin_rgbB_component;
350         int mapin_rgbB_mapping;
351         int mapin_rgbC_input;
352         int mapin_rgbC_component;
353         int mapin_rgbC_mapping;
354         int mapin_rgbD_input;
355         int mapin_rgbD_component;
356         int mapin_rgbD_mapping;
357         int mapin_rgbE_input;
358         int mapin_rgbE_component;
359         int mapin_rgbE_mapping;
360         int mapin_rgbF_input;
361         int mapin_rgbF_component;
362         int mapin_rgbF_mapping;
363         int mapin_aG_input;
364         int mapin_aG_component;
365         int mapin_aG_mapping;
366      } final;
367      int stages;
368      int used;
369      osd_lock *lock;
370   } combiner;
371   bool alpha_test_enabled;
372   int alpha_func;
373   int alpha_reference;
374   bool blending_enabled;
375   int blend_equation;
376   int blend_function_source;
377   int blend_function_destination;
378   UINT32 blend_color;
379   bool logical_operation_enabled;
380   int logical_operation;
381   struct {
382      float modelview[16];
383      float modelview_inverse[16];
384      float projection[16];
385      float translate[4];
386      float scale[4];
387   } matrix;
388   struct {
389      vertex_program_simulator exec;
390      int instructions;
391      int upload_instruction_index;
392      int upload_instruction_component;
393      int start_instruction;
394      int upload_parameter_index;
395      int upload_parameter_component;
396   } vertexprogram;
397   int vertex_pipeline;
398   int enabled_vertex_attributes;
399   int vertex_attribute_words[16];
400   int vertex_attribute_offset[16];
401   bitmap_rgb32 fb;
402   UINT32 dilated0[16][2048];
403   UINT32 dilated1[16][2048];
404   int dilatechose[256];
405   nvidia_object_data *objectdata;
406   int debug_grab_texttype;
407   char *debug_grab_textfile;
408
409   enum NV2A_BEGIN_END {
410      STOP = 0,
411      POINTS = 1,
412      LINES = 2,
413      LINE_LOOP = 3,
414      LINE_STRIP = 4,
415      TRIANGLES = 5,
416      TRIANGLE_STRIP = 6,
417      TRIANGLE_FAN = 7,
418      QUADS = 8,
419      QUAD_STRIP = 9,
420      POLYGON = 10
421   };
422   enum NV2A_VERTEX_ATTR {
423      POS = 0,
424      WEIGHT = 1,
425      NORMAL = 2,
426      COLOR0 = 3, // diffuse
427      COLOR1 = 4, // specular
428      FOG = 5,
429      BACKCOLOR0 = 7, // diffuse
430      BACKCOLOR1 = 8, // specular
431      TEX0 = 9,
432      TEX1 = 10,
433      TEX2 = 11,
434      TEX3 = 12
435   };
436   enum NV2A_VTXBUF_TYPE {
437      NV2A_VTXBUF_TYPE_UNKNOWN_0 = 0, // used for vertex color ?
438      NV2A_VTXBUF_TYPE_FLOAT = 2,
439      NV2A_VTXBUF_TYPE_UBYTE = 4,
440      NV2A_VTXBUF_TYPE_USHORT = 5,
441      NV2A_VTXBUF_TYPE_UNKNOWN_6 = 6 // used for vertex color
442   };
443   enum NV2A_TEX_FORMAT {
444      L8 = 0x0,
445      I8 = 0x1,
446      A1R5G5B5 = 0x2,
447      A4R4G4B4 = 0x4,
448      R5G6B5 = 0x5,
449      A8R8G8B8 = 0x6,
450      X8R8G8B8 = 0x7,
451      INDEX8 = 0xb,
452      DXT1 = 0xc,
453      DXT3 = 0xe,
454      DXT5 = 0xf,
455      A1R5G5B5_RECT = 0x10,
456      R5G6B5_RECT = 0x11,
457      A8R8G8B8_RECT = 0x12,
458      L8_RECT = 0x13,
459      DSDT8_RECT = 0x17,
460      A8L8 = 0x1a,
461      I8_RECT = 0x1b,
462      A4R4G4B4_RECT = 0x1d,
463      R8G8B8_RECT = 0x1e,
464      A8L8_RECT = 0x20,
465      Z24 = 0x2a,
466      Z24_RECT = 0x2b,
467      Z16 = 0x2c,
468      Z16_RECT = 0x2d,
469      DSDT8 = 0x28,
470      HILO16 = 0x33,
471      HILO16_RECT = 0x36,
472      HILO8 = 0x44,
473      SIGNED_HILO8 = 0x45,
474      HILO8_RECT = 0x46,
475      SIGNED_HILO8_RECT = 0x47
476   };
477   enum NV2A_LOGIC_OP {
478      CLEAR = 0x1500,
479      AND = 0x1501,
480      AND_REVERSE = 0x1502,
481      COPY = 0x1503,
482      AND_INVERTED = 0x1504,
483      NOOP = 0x1505,
484      XOR = 0x1506,
485      OR = 0x1507,
486      NOR = 0x1508,
487      EQUIV = 0x1509,
488      INVERT = 0x150a,
489      OR_REVERSE = 0x150b,
490      COPY_INVERTED = 0x150c,
491      OR_INVERTED = 0x150d,
492      NAND = 0x150e,
493      SET = 0x150f
494   };
495   enum NV2A_BLEND_EQUATION {
496      FUNC_ADD = 0x8006,
497      MIN = 0x8007,
498      MAX = 0x8008,
499      FUNC_SUBTRACT = 0x800a,
500      FUNC_REVERSE_SUBTRACT = 0x80b
501   };
502   enum NV2A_BLEND_FACTOR {
503      ZERO = 0x0000,
504      ONE = 0x0001,
505      SRC_COLOR = 0x0300,
506      ONE_MINUS_SRC_COLOR = 0x0301,
507      SRC_ALPHA = 0x0302,
508      ONE_MINUS_SRC_ALPHA = 0x0303,
509      DST_ALPHA = 0x0304,
510      ONE_MINUS_DST_ALPHA = 0x0305,
511      DST_COLOR = 0x0306,
512      ONE_MINUS_DST_COLOR = 0x0307,
513      SRC_ALPHA_SATURATE = 0x0308,
514      CONSTANT_COLOR = 0x8001,
515      ONE_MINUS_CONSTANT_COLOR = 0x8002,
516      CONSTANT_ALPHA = 0x8003,
517      ONE_MINUS_CONSTANT_ALPHA = 0x8004
518   };
519   enum NV2A_COMPARISON_OP {
520      NEVER = 0x0200,
521      LESS = 0x0201,
522      EQUAL = 0x0202,
523      LEQUAL = 0x0203,
524      GREATER = 0x0204,
525      NOTEQUAL = 0x0205,
526      GEQUAL = 0x0206,
527      ALWAYS = 0x0207
528   };
529   enum NV2A_STENCIL_OP {
530      ZEROOP = 0x0000,
531      INVERTOP = 0x150a,
532      KEEP = 0x1e00,
533      REPLACE = 0x1e01,
534      INCR = 0x1e02,
535      DECR = 0x1e03,
536      INCR_WRAP = 0x8507,
537      DECR_WRAP = 0x8508
538   };
539};
trunk/src/mame/machine/mie.c
r242208r242209
357357
358358void mie_device::maple_reset()
359359{
360   // ignoring reset maple pattern is HUGE HACK
361   // current implementation works only because of in such case procedure of firmware upload by games will be skipped at all
362   // so in better case - inputs doesnt work if game uses very different firmware version than already uploaded by BIOS, in worst case - game hang/reboot
363   // TODO: figure out why game code doesn't wait long enough for internal firmware's RAM test completed in the case of proper reset
364360}
trunk/src/mame/machine/naomim4.c
r242208r242209
6060{
6161   naomi_board::device_start();
6262
63#if USE_NAOMICRYPT
64   UINT32 tempkey = get_naomi_key(machine());
65   iv = (tempkey >> 16) &0xffff;
66   key = tempkey & 0xffff;
67#else
6368   const UINT8 *key_data = memregion(key_tag)->base();
64   subkey1 = (key_data[0x5e2] << 8) | key_data[0x5e0];
65   subkey2 = (key_data[0x5e6] << 8) | key_data[0x5e4];
66
69   subkey1 = (key_data[17] << 8) | key_data[16];
70   subkey2 = (key_data[19] << 8) | key_data[18];
71#endif
6772   buffer = auto_alloc_array(machine(), UINT8, BUFFER_SIZE);
6873   enc_init();
6974
trunk/src/mame/mame.mak
r242208r242209
16951695   $(DRIVERS)/bingoc.o \
16961696   $(DRIVERS)/blockade.o $(AUDIO)/blockade.o $(VIDEO)/blockade.o \
16971697   $(DRIVERS)/calorie.o \
1698   $(DRIVERS)/chihiro.o \
1698   $(DRIVERS)/chihiro.o $(VIDEO)/chihiro.o  \
16991699   $(DRIVERS)/coolridr.o \
17001700   $(DRIVERS)/deniam.o $(VIDEO)/deniam.o \
17011701   $(DRIVERS)/dotrikun.o \
trunk/src/mame/video/btime.c
r242208r242209
303303
304304      if (flip_screen())
305305      {
306         x = 31 - x;
307         y = 31 - y;
306         x = 31 + 16 - x;
307         y = 33 - y;
308308      }
309309
310310      m_gfxdecode->gfx(0)->transpen(bitmap,cliprect,
r242208r242209
339339
340340      if (flip_screen())
341341      {
342         x = 240 - x;
343         y = 240 - y + sprite_y_adjust_flip_screen;
342         x = 240 + 128 - x;
343         y = 256 - y + sprite_y_adjust_flip_screen;
344344
345345         flipx = !flipx;
346346         flipy = !flipy;
r242208r242209
391391
392392         if (flip_screen())
393393         {
394            x = 240 - x;
395            y = 240 - y;
394            x = 240 + 128 - x;
395            y = 256 - y;
396396         }
397397
398398         m_gfxdecode->gfx(2)->opaque(bitmap,cliprect,
r242208r242209
488488         if (flip_screen())
489489         {
490490            sx = 496 - sx;
491            sy = 240 - sy;
491            sy = 256 - sy;
492492         }
493493
494494         m_gfxdecode->gfx(2)->opaque(*m_background_bitmap,m_background_bitmap->cliprect(),
r242208r242209
534534      if (flip_screen())
535535      {
536536         sx = 31 - sx;
537         sy = 31 - sy;
537         sy = 33 - sy;
538538      }
539539
540540      m_gfxdecode->gfx(2)->opaque(bitmap,cliprect,
trunk/src/mame/video/chihiro.c
r0r242209
1#include "emu.h"
2#include "video/poly.h"
3#include "bitmap.h"
4#include "includes/chihiro.h"
5
6//#define LOG_NV2A
7
8const char *vertex_program_disassembler::srctypes[] = { "??", "Rn", "Vn", "Cn" };
9const char *vertex_program_disassembler::scaops[] = { "NOP", "IMV", "RCP", "RCC", "RSQ", "EXP", "LOG", "LIT", "???", "???", "???", "???", "???", "???", "???", "???", "???" };
10const int vertex_program_disassembler::scapar2[] = { 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
11const char *vertex_program_disassembler::vecops[] = { "NOP", "MOV", "MUL", "ADD", "MAD", "DP3", "DPH", "DP4", "DST", "MIN", "MAX", "SLT", "SGE", "ARL", "???", "???", "???" };
12const int vertex_program_disassembler::vecpar2[] = { 0, 4, 6, 5, 7, 6, 6, 6, 6, 6, 6, 6, 6, 4, 0, 0, 0 };
13const char *vertex_program_disassembler::vecouts[] = { "oPos", "???", "???", "oD0", "oD1", "oFog", "oPts", "oB0", "oB1", "oT0", "oT1", "oT2", "oT3" };
14const char vertex_program_disassembler::compchar[] = { 'x', 'y', 'z', 'w' };
15
16/*
17Each vertex program instruction is a 128 bit word made of the fields:
18d         f
19w   b     i
20o   i     e
21r   t     l
22d   s     d
23+-+-----+-------
24|0|31-0 |not used
25+-+-----+-------
26| |31-29|not used
27| +-----+-------
28| |28-25|scalar operation
29| +-----+-------
30| |24-21|vectorial operation
31| +-----+-------
32| |20-13|index for source constant C[]
33| +-----+-------
34| |12-9 |input vector index
35| +-----+-------
36|1|  8  |parameter A:sign
37| +-----+-------
38| | 7-6 |parameter A:swizzle x
39| +-----+-------
40| | 5-4 |parameter A:swizzle y
41| +-----+-------
42| | 3-2 |parameter A:swizzle z
43| +-----+-------
44| | 1-0 |parameter A:swizzle w
45|-+-----+-------
46| |31-28|parameter A:parameter Rn index
47| +-----+-------
48| |27-26|parameter A:input type 1:Rn 2:Vn 3:C[n]
49| +-----+-------
50| | 25  |parameter B:sign
51| +-----+-------
52| |24-23|parameter B:swizzle x
53| +-----+-------
54| |22-21|parameter B:swizzle y
55| +-----+-------
56| |20-19|parameter B:swizzle z
57| +-----+-------
58|2|18-17|parameter B:swizzle w
59| +-----+-------
60| |16-13|parameter B:parameter Rn index
61| +-----+-------
62| |12-11|parameter B:input type 1:Rn 2:Vn 3:C[n]
63| +-----+-------
64| | 10  |parameter C:sign
65| +-----+-------
66| | 9-8 |parameter C:swizzle x
67| +-----+-------
68| | 7-6 |parameter C:swizzle y
69| +-----+-------
70| | 5-4 |parameter C:swizzle z
71| +-----+-------
72| | 3-2 |parameter C:swizzle w
73| +-----+-------
74| | 1-0 |
75|-+     |parameter C:parameter Rn index
76| |31-30|
77| +-----+-------
78| |29-28|parameter C:input type 1:Rn 2:Vn 3:C[n]
79| +-----+-------
80| |27-24|output Rn mask from vectorial operation
81| +-----+-------
82| |23-20|output Rn index from vectorial operation
83| +-----+-------
84| |19-16|output Rn mask from scalar operation
85| +-----+-------
86|3|15-12|output vector write mask
87| +-----+-------
88| | 11  |1:output is output vector 0:output is constant C[]
89| +-----+-------
90| |10-3 |output vector/constant index
91| +-----+-------
92| |  2  |0:output Rn from vectorial operation 1:output Rn from scalar operation
93| +-----+-------
94| |  1  |1:add a0x to index for source constant C[]
95| +-----+-------
96| |  0  |1:end of program
97+-+-----+-------
98Each vertex program instruction can generate up to three destination values using up to three source values.
99The first possible destination is to Rn from a vectorial operation.
100The second possible destination is to a vertex shader output or C[n] from a vectorial or scalar operation.
101The third possible destination is to Rn from a scalar operation.
102*/
103void vertex_program_disassembler::decodefields(unsigned int *dwords, int offset, fields &decoded)
104{
105   unsigned int srcbits[3];
106   int a;
107
108   srcbits[0] = ((dwords[1 + offset] & 0x1ff) << 6) | (dwords[2 + offset] >> 26);
109   srcbits[1] = (dwords[2 + offset] >> 11) & 0x7fff;
110   srcbits[2] = ((dwords[2 + offset] & 0x7ff) << 4) | (dwords[3 + offset] >> 28);
111   decoded.ScaOperation = (int)(dwords[1 + offset] >> 25) & 0xf;
112   decoded.VecOperation = (int)(dwords[1 + offset] >> 21) & 0xf;
113   decoded.SourceConstantIndex = (int)(dwords[1 + offset] >> 13) & 0xff;
114   decoded.InputIndex = (int)(dwords[1 + offset] >> 9) & 0xf;
115   for (a = 0; a < 3; a++)
116   {
117      decoded.src[a].Sign = (int)(srcbits[a] >> 14) & 1;
118      decoded.src[a].SwizzleX = (int)(srcbits[a] >> 12) & 3;
119      decoded.src[a].SwizzleY = (int)(srcbits[a] >> 10) & 3;
120      decoded.src[a].SwizzleZ = (int)(srcbits[a] >> 8) & 3;
121      decoded.src[a].SwizzleW = (int)(srcbits[a] >> 6) & 3;
122      decoded.src[a].TempIndex = (int)(srcbits[a] >> 2) & 0xf;
123      decoded.src[a].ParameterType = (int)(srcbits[a] >> 0) & 3;
124   }
125
126   decoded.VecTempWriteMask = (int)(dwords[3 + offset] >> 24) & 0xf;
127   decoded.VecTempIndex = (int)(dwords[3 + offset] >> 20) & 0xf;
128   decoded.ScaTempWriteMask = (int)(dwords[3 + offset] >> 16) & 0xf;
129   decoded.OutputWriteMask = (int)(dwords[3 + offset] >> 12) & 0xf;
130   decoded.OutputSelect = (int)(dwords[3 + offset] >> 11) & 0x1;
131   decoded.OutputIndex = (int)(dwords[3 + offset] >> 3) & 0xff;
132   decoded.MultiplexerControl = (int)(dwords[3 + offset] >> 2) & 0x1;
133   decoded.Usea0x = (int)(dwords[3 + offset] >> 1) & 0x1;
134   decoded.EndOfProgram = (int)(dwords[3 + offset] >> 0) & 0x1;
135}
136
137int vertex_program_disassembler::disassemble_mask(int mask, char *s)
138{
139   int l;
140
141   *s = 0;
142   if (mask == 15)
143      return 0;
144   s[0] = '.';
145   l = 1;
146   if ((mask & 8) != 0) {
147      s[l] = 'x';
148      l++;
149   }
150   if ((mask & 4) != 0){
151      s[l] = 'y';
152      l++;
153   }
154   if ((mask & 2) != 0){
155      s[l] = 'z';
156      l++;
157   }
158   if ((mask & 1) != 0){
159      s[l] = 'w';
160      l++;
161   }
162   s[l] = 0;
163   return l;
164}
165
166int vertex_program_disassembler::disassemble_swizzle(sourcefields f, char *s)
167{
168   int t, l;
169
170   t = 4;
171   if (f.SwizzleW == 3)
172   {
173      t = t - 1;
174      if (f.SwizzleZ == 2)
175      {
176         t = t - 1;
177         if (f.SwizzleY == 1)
178         {
179            t = t - 1;
180            if (f.SwizzleX == 0)
181            {
182               t = t - 1;
183            }
184         }
185      }
186   }
187   *s = 0;
188   if (t == 0)
189      return 0;
190   s[0] = '.';
191   l = 1;
192   if (t > 0)
193   {
194      s[l] = compchar[f.SwizzleX];
195      l++;
196   }
197   if (t > 1)
198   {
199      s[l] = compchar[f.SwizzleY];
200      l++;
201   }
202   if (t > 2)
203   {
204      s[l] = compchar[f.SwizzleZ];
205      l++;
206   }
207   if (t > 3)
208   {
209      s[l] = compchar[f.SwizzleW];
210      l++;
211   }
212   s[l] = 0;
213   return l;
214}
215
216int vertex_program_disassembler::disassemble_source(sourcefields f, fields fi, char *s)
217{
218   int l;
219
220   if (f.ParameterType == 0) {
221      strcpy(s, ",???");
222      return 4;
223   }
224   l = 0;
225   if (f.Sign != 0) {
226      s[l] = '-';
227      l++;
228   }
229   if (f.ParameterType == 1) {
230      s[l] = 'r';
231      l = l + 1 + sprintf(s + l + 1, "%d", f.TempIndex);
232   }
233   else if (f.ParameterType == 2){
234      s[l] = 'v';
235      l = l + 1 + sprintf(s + l + 1, "%d", fi.InputIndex);
236   }
237   else
238   {
239      if (fi.Usea0x != 0)
240      {
241         if (fi.SourceConstantIndex >= 96) {
242            strcpy(s + l, "c[");
243            l = l + 2;
244            l = l + sprintf(s + l, "%d", fi.SourceConstantIndex - 96);
245            strcpy(s + l, "+a0.x]");
246            l = l + 6;
247         }
248         else {
249            strcpy(s + l, "c[a0.x");
250            l = l + 6;
251            l = l + sprintf(s + l, "%d", fi.SourceConstantIndex - 96);
252            s[l] = ']';
253            l++;
254         }
255      }
256      else {
257         strcpy(s + l, "c[");
258         l = l + 2;
259         l = l + sprintf(s + l, "%d", fi.SourceConstantIndex - 96);
260         s[l] = ']';
261         l++;
262      }
263   }
264   l = l + disassemble_swizzle(f, s + l);
265   s[l] = 0;
266   return l;
267}
268
269int vertex_program_disassembler::disassemble_output(fields f, char *s)
270{
271   int l;
272
273   if (f.OutputSelect == 1) {
274      strcpy(s, vecouts[f.OutputIndex]);
275      return strlen(s);
276   }
277   else {
278      strcpy(s, "c[");
279      l = 2;
280      l = l + sprintf(s + l, "%d", f.OutputIndex - 96);
281      s[l] = ']';
282      l++;
283   }
284   s[l] = 0;
285   return l;
286}
287
288int vertex_program_disassembler::output_types(fields f, int *o)
289{
290   o[0] = o[1] = o[2] = o[3] = o[4] = o[5] = 0;
291   if ((f.VecOperation > 0) && (f.VecTempWriteMask != 0))
292      o[0] = 1;
293   if ((f.VecOperation > 0) && (f.OutputWriteMask != 0) && (f.MultiplexerControl == 0))
294      o[1] = 1;
295   if ((f.ScaOperation > 0) && (f.OutputWriteMask != 0) && (f.MultiplexerControl == 1))
296      o[2] = 1;
297   if ((f.ScaOperation > 0) && (f.ScaTempWriteMask != 0))
298      o[3] = 1;
299   if (f.VecOperation == 13)
300      o[4] = 1;
301   if (f.EndOfProgram == 1)
302      o[5] = 1;
303   return o[0] + o[1] + o[2] + o[3] + o[4] + o[5];
304}
305
306int vertex_program_disassembler::disassemble(unsigned int *instruction, char *line)
307{
308   int b, p;
309   char *c;
310
311   if (state == 0) {
312      decodefields(instruction, 0, f);
313      output_types(f, o);
314      state = 1;
315   }
316   if (o[0] != 0)
317   {
318      o[0] = 0;
319      c = line;
320      strcpy(c, vecops[f.VecOperation]);
321      c = c + strlen(c);
322      strcpy(c, " r");
323      c = c + 2;
324      c = c + sprintf(c, "%d", f.VecTempIndex);
325      c = c + disassemble_mask(f.VecTempWriteMask, c);
326      b = 0;
327      for (p = 4; p != 0; p = p >> 1)
328      {
329         if ((vecpar2[f.VecOperation] & p) != 0) {
330            c[0] = ',';
331            c++;
332            c = c + disassemble_source(f.src[b], f, c);
333         }
334         b++;
335      }
336      *c = 0;
337      return 1;
338   }
339   if (o[1] != 0)
340   {
341      o[1] = 0;
342      c = line;
343      strcpy(c, vecops[f.VecOperation]);
344      c = c + strlen(c);
345      *c = ' ';
346      c++;
347      c = c + disassemble_output(f, c);
348      c = c + disassemble_mask(f.OutputWriteMask, c);
349      b = 0;
350      for (p = 4; p != 0; p = p >> 1)
351      {
352         if ((vecpar2[f.VecOperation] & p) != 0) {
353            *c = ',';
354            c++;
355            c = c + disassemble_source(f.src[b], f, c);
356         }
357         b++;
358      }
359      *c = 0;
360      return 1;
361   }
362   if (o[2] != 0)
363   {
364      o[2] = 0;
365      c = line;
366      strcpy(c, scaops[f.ScaOperation]);
367      c = c + strlen(c);
368      *c = ' ';
369      c++;
370      c = c + disassemble_output(f, c);
371      c = c + disassemble_mask(f.OutputWriteMask, c);
372      b = 0;
373      for (p = 4; p != 0; p = p >> 1)
374      {
375         if ((scapar2[f.ScaOperation] & p) != 0) {
376            *c = ',';
377            c++;
378            c = c + disassemble_source(f.src[b], f, c);
379         }
380         b++;
381      }
382      *c = 0;
383      return 1;
384   }
385   if (o[3] != 0)
386   {
387      if (f.VecOperation > 0)
388         b = 1;
389      else
390         b = f.VecTempIndex;
391      o[3] = 0;
392      c = line;
393      strcpy(c, scaops[f.ScaOperation]);
394      c = c + strlen(c);
395      strcpy(c, " r");
396      c = c + 2;
397      c = c + sprintf(c, "%d", b);
398      c = c + disassemble_mask(f.ScaTempWriteMask, c);
399      b = 0;
400      for (p = 4; p != 0; p = p >> 1)
401      {
402         if ((scapar2[f.ScaOperation] & p) != 0) {
403            *c = ',';
404            c++;
405            c = c + disassemble_source(f.src[b], f, c);
406         }
407         b++;
408      }
409      *c = 0;
410      return 1;
411   }
412   if (o[4] != 0)
413   {
414      o[4] = 0;
415      c = line;
416      c = c + sprintf(c, "MOV a0.x,");
417      c = c + disassemble_source(f.src[0], f, c);
418      *c = 0;
419      return 1;
420   }
421   if (o[5] != 0)
422   {
423      o[5] = 0;
424      strcpy(line, "END");
425      return 1;
426   }
427   state = 0;
428   return 0;
429}
430
431vertex_program_simulator::vertex_program_simulator()
432{
433   for (int i = 0; i < 256; i++)
434      op[i].modified = 0;
435   initialize_constants();
436}
437
438void vertex_program_simulator::set_data(vertex_nv *in, vertex_nv *out)
439{
440   input = in;
441   output = out;
442}
443
444void vertex_program_simulator::reset()
445{
446   ip = 0;
447   a0x = 0;
448   initialize_outputs();
449   initialize_temps();
450}
451
452void vertex_program_simulator::decode_instruction(int address)
453{
454   instruction *i;
455
456   i = &op[address];
457   i->d.SignA = i->i[1] & (1 << 8);
458   i->d.ParameterTypeA = (i->i[2] >> 26) & 3;
459   i->d.TempIndexA = (i->i[2] >> 28) & 15;
460   i->d.SwizzleA[0] = (i->i[1] >> 6) & 3;
461   i->d.SwizzleA[1] = (i->i[1] >> 4) & 3;
462   i->d.SwizzleA[2] = (i->i[1] >> 2) & 3;
463   i->d.SwizzleA[3] = (i->i[1] >> 0) & 3;
464   i->d.SignB = i->i[2] & (1 << 25);
465   i->d.ParameterTypeB = (i->i[2] >> 11) & 3;
466   i->d.TempIndexB = (i->i[2] >> 13) & 15;
467   i->d.SwizzleB[0] = (i->i[2] >> 23) & 3;
468   i->d.SwizzleB[1] = (i->i[2] >> 21) & 3;
469   i->d.SwizzleB[2] = (i->i[2] >> 19) & 3;
470   i->d.SwizzleB[3] = (i->i[2] >> 17) & 3;
471   i->d.SignC = i->i[2] & (1 << 10);
472   i->d.ParameterTypeC = (i->i[3] >> 28) & 3;
473   i->d.TempIndexC = ((i->i[2] & 3) << 2) + (i->i[3] >> 30);
474   i->d.SwizzleC[0] = (i->i[2] >> 8) & 3;
475   i->d.SwizzleC[1] = (i->i[2] >> 6) & 3;
476   i->d.SwizzleC[2] = (i->i[2] >> 4) & 3;
477   i->d.SwizzleC[3] = (i->i[2] >> 2) & 3;
478   i->d.VecOperation = (i->i[1] >> 21) & 15;
479   i->d.ScaOperation = (i->i[1] >> 25) & 15;
480   i->d.OutputWriteMask = ((i->i[3] >> 12) & 15);
481   i->d.MultiplexerControl = i->i[3] & 4; // 0 : output Rn from vectorial operation 4 : output Rn from scalar operation
482   i->d.VecTempIndex = (i->i[3] >> 20) & 15;
483   i->d.OutputIndex = (i->i[3] >> 3) & 255;
484   i->d.OutputSelect = i->i[3] & 0x800;
485   i->d.VecTempWriteMask = (i->i[3] >> 24) & 15;
486   i->d.ScaTempWriteMask = (i->i[3] >> 16) & 15;
487   i->d.InputIndex = (i->i[1] >> 9) & 15;
488   i->d.SourceConstantIndex = (i->i[1] >> 13) & 255;
489   i->d.Usea0x = i->i[3] & 2;
490   i->d.EndOfProgram = i->i[3] & 1;
491}
492
493int vertex_program_simulator::step()
494{
495   int p1, p2;
496   float tmp[3 * 4];
497   float tmpv[4];
498   float tmps[4];
499   instruction::decoded *d;
500
501#if 0 // useful while debugging to see what instrucion is being executed
502   static int debugvpi = 0;
503   char disbuffer[256];
504   if (debugvpi) {
505      char *pp;
506      vertex_program_disassembler vdis;
507
508      pp = disbuffer;
509      while (vdis.disassemble(op[ip].i, pp) != 0) {
510         pp = pp + strlen(pp);
511         *pp = '\n';
512         pp++;
513         *pp = 0;
514      }
515   }
516#endif
517
518   if (op[ip].modified)
519      decode_instruction(ip);
520   d = &(op[ip].d);
521   // prepare inputs
522   //  input A
523   generate_input(&tmp[0], d->SignA, d->ParameterTypeA, d->TempIndexA, d->SwizzleA);
524   //  input B
525   generate_input(&tmp[4], d->SignB, d->ParameterTypeB, d->TempIndexB, d->SwizzleB);
526   //  input C
527   generate_input(&tmp[8], d->SignC, d->ParameterTypeC, d->TempIndexC, d->SwizzleC);
528   // compute 2 instructions
529   //  vectorial
530   compute_vectorial_operation(tmpv, d->VecOperation, tmp);
531   //  scalar
532   compute_scalar_operation(tmps, d->ScaOperation, tmp);
533   // assign destinations
534   if (d->VecOperation > 0) {
535      if (d->VecOperation == 13)
536         //o[4] = 1;
537         a0x = (int)tmpv[0];
538      else {
539         if (d->VecTempWriteMask != 0) { // assign to Rn
540            //o[0] = 1;
541            int wm = d->VecTempWriteMask;
542            for (p1 = 0; p1 < 4; p1++) {
543               if (wm & 8)
544                  r_temp[d->VecTempIndex].fv[p1] = tmpv[p1];
545               wm = wm << 1;
546            }
547         }
548         if ((d->OutputWriteMask != 0) && (d->MultiplexerControl == 0)) {
549            //o[1] = 1;
550            if (d->OutputSelect) { // assign to output
551               int wm = d->OutputWriteMask;
552               for (p1 = 0; p1 < 4; p1++) {
553                  if (wm & 8)
554                     output->attribute[d->OutputIndex].fv[p1] = tmpv[p1];
555                  wm = wm << 1;
556               }
557               // remeber, output position == r12
558               if (d->OutputIndex == 0)
559                  for (p1 = 0; p1 < 4; p1++) {
560                     r_temp[12].fv[p1] = output->attribute[d->OutputIndex].fv[p1];
561                  }
562            }
563            else { // assign to constant
564               int wm = d->OutputWriteMask;
565               for (p1 = 0; p1 < 4; p1++) {
566                  if (wm & 8)
567                     c_constant[d->OutputIndex].fv[p1] = tmpv[p1];
568                  wm = wm << 1;
569               }
570            }
571         }
572      }
573   }
574   if (d->ScaOperation > 0) {
575      if (d->ScaTempWriteMask != 0) { // assign to Rn
576         //o[3] = 1;
577         if (d->VecOperation > 0)
578            p2 = 1;
579         else
580            p2 = d->VecTempIndex;
581         int wm = d->ScaTempWriteMask;
582         for (p1 = 0; p1 < 4; p1++) {
583            if (wm & 8)
584               r_temp[p2].fv[p1] = tmps[p1];
585            wm = wm << 1;
586         }
587      }
588      if ((d->OutputWriteMask != 0) && (d->MultiplexerControl != 0)) { // assign to output
589         //o[2] = 1;
590         int wm = d->OutputWriteMask;
591         for (p1 = 0; p1 < 4; p1++) {
592            if (wm & 8)
593               output->attribute[d->OutputIndex].fv[p1] = tmps[p1];
594            wm = wm << 1;
595         }
596         // remeber, output position == r12
597         if (d->OutputIndex == 0) {
598            for (p1 = 0; p1 < 4; p1++) {
599               r_temp[12].fv[p1] = output->attribute[d->OutputIndex].fv[p1];
600            }
601         }
602      }
603   }
604   return d->EndOfProgram;
605}
606
607void vertex_program_simulator::execute()
608{
609   int c;
610
611   c = 0;
612   do {
613      c = step();
614      ip++;
615   } while (c == 0);
616}
617
618void vertex_program_simulator::jump(int address)
619{
620   ip = address;
621}
622
623void vertex_program_simulator::process(int address, vertex_nv *in, vertex_nv *out, int count)
624{
625#if 0 // useful while debugging to see what is being executed
626   static int debugvps = 0;
627   if (debugvps) {
628      char *pp;
629      vertex_program_disassembler vdis;
630      char disbuffer[128];
631
632      jump(address);
633      debugvps--;
634      for (int t = 0; t < 128; t++) {
635         pp = disbuffer;
636         while (vdis.disassemble(op[ip + t].i, pp) != 0) {
637            pp = pp + strlen(pp);
638            *pp = '\n';
639            pp++;
640            *pp = 0;
641         }
642         printf("%08X %08X %08X %s", op[ip + t].i[1], op[ip + t].i[2], op[ip + t].i[3], disbuffer);
643         if (op[ip + t].i[3] & 1)
644            break;
645      }
646   }
647#endif
648   set_data(in, out);
649   while (count > 0) {
650      reset();
651      jump(address);
652      execute();
653      input++;
654      output++;
655      count--;
656   }
657}
658
659int vertex_program_simulator::status()
660{
661   return ip;
662}
663
664void vertex_program_simulator::initialize_outputs()
665{
666   for (int n = 0; n < 16; n++) {
667      output->attribute[n].fv[0] = output->attribute[n].fv[1] = output->attribute[n].fv[2] = 0;
668      output->attribute[n].fv[3] = 1;
669   }
670}
671
672void vertex_program_simulator::initialize_temps()
673{
674   for (int n = 0; n < 32; n++) {
675      for (int m = 0; m < 4; m++)
676         r_temp[n].fv[m] = 0;
677   }
678}
679
680void vertex_program_simulator::initialize_constants()
681{
682   for (int n = 0; n < 192; n++) {
683      for (int m = 0; m < 4;m++)
684         c_constant[n].fv[m] = 0;
685   }
686}
687
688void vertex_program_simulator::generate_input(float t[4], int sign, int type, int temp, int swizzle[4])
689{
690   float sgn = 1;
691
692   if (sign)
693      sgn = -1;
694   if (type == 1) {
695      t[0] = sgn*r_temp[temp].fv[swizzle[0]];
696      t[1] = sgn*r_temp[temp].fv[swizzle[1]];
697      t[2] = sgn*r_temp[temp].fv[swizzle[2]];
698      t[3] = sgn*r_temp[temp].fv[swizzle[3]];
699   }
700   else if (type == 2) {
701      int InputIndex = op[ip].d.InputIndex;
702      t[0] = sgn*input->attribute[InputIndex].fv[swizzle[0]];
703      t[1] = sgn*input->attribute[InputIndex].fv[swizzle[1]];
704      t[2] = sgn*input->attribute[InputIndex].fv[swizzle[2]];
705      t[3] = sgn*input->attribute[InputIndex].fv[swizzle[3]];
706   }
707   else if (type == 3) {
708      int SourceConstantIndex = op[ip].d.SourceConstantIndex;
709      if (op[ip].d.Usea0x)
710         SourceConstantIndex = SourceConstantIndex + a0x;
711      t[0] = sgn*c_constant[SourceConstantIndex].fv[swizzle[0]];
712      t[1] = sgn*c_constant[SourceConstantIndex].fv[swizzle[1]];
713      t[2] = sgn*c_constant[SourceConstantIndex].fv[swizzle[2]];
714      t[3] = sgn*c_constant[SourceConstantIndex].fv[swizzle[3]];
715   }
716}
717
718void vertex_program_simulator::compute_vectorial_operation(float t_out[4], int instruction, float par_in[3 * 4])
719{
720   const int p1_A = 0;
721   const int p2_B = 4;
722   const int p3_C = 8;
723
724   // t_out <= instruction(par_in)
725   switch (instruction) {
726   case 0: // "NOP"
727      break;
728   case 1: // "MOV"
729      t_out[0] = par_in[p1_A + 0];
730      t_out[1] = par_in[p1_A + 1];
731      t_out[2] = par_in[p1_A + 2];
732      t_out[3] = par_in[p1_A + 3];
733      break;
734   case 2: // "MUL"
735      t_out[0] = par_in[p1_A + 0] * par_in[p2_B + 0];
736      t_out[1] = par_in[p1_A + 1] * par_in[p2_B + 1];
737      t_out[2] = par_in[p1_A + 2] * par_in[p2_B + 2];
738      t_out[3] = par_in[p1_A + 3] * par_in[p2_B + 3];
739      break;
740   case 3: // "ADD"
741      t_out[0] = par_in[p1_A + 0] + par_in[p3_C + 0];
742      t_out[1] = par_in[p1_A + 1] + par_in[p3_C + 1];
743      t_out[2] = par_in[p1_A + 2] + par_in[p3_C + 2];
744      t_out[3] = par_in[p1_A + 3] + par_in[p3_C + 3];
745      break;
746   case 4: // "MAD"
747      t_out[0] = par_in[p1_A + 0] * par_in[p2_B + 0] + par_in[p3_C + 0];
748      t_out[1] = par_in[p1_A + 1] * par_in[p2_B + 1] + par_in[p3_C + 1];
749      t_out[2] = par_in[p1_A + 2] * par_in[p2_B + 2] + par_in[p3_C + 2];
750      t_out[3] = par_in[p1_A + 3] * par_in[p2_B + 3] + par_in[p3_C + 3];
751      break;
752   case 5: // "DP3"
753      t_out[0] = par_in[p1_A + 0] * par_in[p2_B + 0] + par_in[p1_A + 1] * par_in[p2_B + 1] + par_in[p1_A + 2] * par_in[p2_B + 2];
754      t_out[1] = t_out[2] = t_out[3] = t_out[0];
755      break;
756   case 6: // "DPH"
757      t_out[0] = par_in[p1_A + 0] * par_in[p2_B + 0] + par_in[p1_A + 1] * par_in[p2_B + 1] + par_in[p1_A + 2] * par_in[p2_B + 2] + par_in[p2_B + 3];
758      t_out[1] = t_out[2] = t_out[3] = t_out[0];
759      break;
760   case 7: // "DP4"
761      t_out[0] = par_in[p1_A + 0] * par_in[p2_B + 0] + par_in[p1_A + 1] * par_in[p2_B + 1] + par_in[p1_A + 2] * par_in[p2_B + 2] + par_in[p1_A + 3] * par_in[p2_B + 3];
762      t_out[1] = t_out[2] = t_out[3] = t_out[0];
763      break;
764   case 8: // "DST"
765      t_out[0] = 1.0;
766      t_out[1] = par_in[p1_A + 1] * par_in[p2_B + 1];
767      t_out[2] = par_in[p1_A + 2];
768      t_out[3] = par_in[p2_B + 3];
769      break;
770   case 9: // "MIN"
771      t_out[0] = fmin(par_in[p1_A + 0], par_in[p2_B + 0]);
772      t_out[1] = fmin(par_in[p1_A + 1], par_in[p2_B + 1]);
773      t_out[2] = fmin(par_in[p1_A + 2], par_in[p2_B + 2]);
774      t_out[3] = fmin(par_in[p1_A + 3], par_in[p2_B + 3]);
775      break;
776   case 10: // "MAX"
777      t_out[0] = fmax(par_in[p1_A + 0], par_in[p2_B + 0]);
778      t_out[1] = fmax(par_in[p1_A + 1], par_in[p2_B + 1]);
779      t_out[2] = fmax(par_in[p1_A + 2], par_in[p2_B + 2]);
780      t_out[3] = fmax(par_in[p1_A + 3], par_in[p2_B + 3]);
781      break;
782   case 11: // "SLT"
783      t_out[0] = (par_in[p1_A + 0] < par_in[p2_B + 0]) ? 1.0 : 0;
784      t_out[1] = (par_in[p1_A + 1] < par_in[p2_B + 1]) ? 1.0 : 0;
785      t_out[2] = (par_in[p1_A + 2] < par_in[p2_B + 2]) ? 1.0 : 0;
786      t_out[3] = (par_in[p1_A + 3] < par_in[p2_B + 3]) ? 1.0 : 0;
787      break;
788   case 12: // "SGE"
789      t_out[0] = (par_in[p1_A + 0] >= par_in[p2_B + 0]) ? 1.0 : 0;
790      t_out[1] = (par_in[p1_A + 1] >= par_in[p2_B + 1]) ? 1.0 : 0;
791      t_out[2] = (par_in[p1_A + 2] >= par_in[p2_B + 2]) ? 1.0 : 0;
792      t_out[3] = (par_in[p1_A + 3] >= par_in[p2_B + 3]) ? 1.0 : 0;
793      break;
794   case 13: // "ARL"
795      t_out[0] = par_in[p1_A + 0];
796   }
797}
798
799void vertex_program_simulator::compute_scalar_operation(float t_out[4], int instruction, float par_in[3 * 4])
800{
801   //const int p1_A = 0;
802   //const int p2_B = 4;
803   const int p3_C = 8;
804   union {
805      float f;
806      unsigned int i;
807   } t;
808   int e;
809
810   // t_out <= instruction(par_in)
811   switch (instruction) {
812   case 0: // "NOP"
813      break;
814   case 1: // "IMV"
815      t_out[0] = par_in[p3_C + 0];
816      t_out[1] = par_in[p3_C + 1];
817      t_out[2] = par_in[p3_C + 2];
818      t_out[3] = par_in[p3_C + 3];
819      break;
820   case 2:   // "RCP"
821      t_out[0] = t_out[1] = t_out[2] = t_out[3] = 1.0 / par_in[p3_C + 0];
822      break;
823   case 3:   // "RCC"
824      t_out[0] = t_out[1] = t_out[2] = t_out[3] = 1.0 / par_in[p3_C + 0]; // ?
825      break;
826   case 4: // "RSQ"
827      t_out[0] = t_out[1] = t_out[2] = t_out[3] = 1.0 / sqrt(abs(par_in[p3_C + 0]));
828      break;
829   case 5: // "EXP"
830      t_out[0] = pow(2, floor(par_in[p3_C + 0]));
831      t_out[1] = par_in[p3_C + 0] - floor(par_in[p3_C + 0]);
832      t.f = pow(2, par_in[p3_C + 0]);
833      t.i = t.i & 0xffffff00;
834      t_out[2] = t.f;
835      t_out[3] = 1.0;
836      break;
837   case 6: // "LOG"
838      t_out[1] = frexp(par_in[p3_C + 0], &e)*2.0; // frexp gives mantissa as 0.5....1
839      t_out[0] = e - 1;
840      t.f = log2(abs(par_in[p3_C + 0]));
841      t.i = t.i & 0xffffff00;
842      t_out[2] = t.f;
843      t_out[3] = 1.0;
844      break;
845   case 7: // "LIT"
846      t_out[0] = 1.0;
847      t_out[1] = fmax(0, fmin(par_in[p3_C + 0], 1.0f));
848      t_out[2] = par_in[p3_C + 0] > 0 ? pow(fmax(par_in[p3_C + 1], 0), par_in[p3_C + 3]) : 0;
849      t_out[3] = 1.0;
850      break;
851   }
852}
853
854/*
855 * Graphics
856 */
857
858UINT32 nv2a_renderer::dilate0(UINT32 value, int bits) // dilate first "bits" bits in "value"
859{
860   UINT32 x, m1, m2, m3;
861   int a;
862
863   x = value;
864   for (a = 0; a < bits; a++)
865   {
866      m2 = 1 << (a << 1);
867      m1 = m2 - 1;
868      m3 = (~m1) << 1;
869      x = (x & m1) + (x & m2) + ((x & m3) << 1);
870   }
871   return x;
872}
873
874UINT32 nv2a_renderer::dilate1(UINT32 value, int bits) // dilate first "bits" bits in "value"
875{
876   UINT32 x, m1, m2, m3;
877   int a;
878
879   x = value;
880   for (a = 0; a < bits; a++)
881   {
882      m2 = 1 << (a << 1);
883      m1 = m2 - 1;
884      m3 = (~m1) << 1;
885      x = (x & m1) + ((x & m2) << 1) + ((x & m3) << 1);
886   }
887   return x;
888}
889
890void nv2a_renderer::computedilated(void)
891{
892   int a, b;
893
894   for (b = 0; b < 16; b++)
895      for (a = 0; a < 2048; a++) {
896      dilated0[b][a] = dilate0(a, b);
897      dilated1[b][a] = dilate1(a, b);
898      }
899   for (b = 0; b < 16; b++)
900      for (a = 0; a < 16; a++)
901         dilatechose[(b << 4) + a] = (a < b ? a : b);
902}
903
904int nv2a_renderer::geforce_commandkind(UINT32 word)
905{
906   if ((word & 0x00000003) == 0x00000002)
907      return 7; // call
908   if ((word & 0x00000003) == 0x00000001)
909      return 6; // jump
910   if ((word & 0xE0030003) == 0x40000000)
911      return 5; // non increasing
912   if ((word & 0xE0000003) == 0x20000000)
913      return 4; // old jump
914   if ((word & 0xFFFF0003) == 0x00030000)
915      return 3; // long non icreasing
916   if ((word & 0xFFFFFFFF) == 0x00020000)
917      return 2; // return
918   if ((word & 0xFFFF0003) == 0x00010000)
919      return 1; // sli conditional
920   if ((word & 0xE0030003) == 0x00000000)
921      return 0; // increasing
922   return -1;
923}
924
925UINT32 nv2a_renderer::geforce_object_offset(UINT32 handle)
926{
927   UINT32 h = ((((handle >> 11) ^ handle) >> 11) ^ handle) & 0x7ff;
928   UINT32 o = (pfifo[0x210 / 4] & 0x1f) << 8; // or 12 ?
929   UINT32 e = o + h * 8; // at 0xfd000000+0x00700000
930   UINT32 w;
931
932   if (ramin[e / 4] != handle)
933      e = 0;
934   w = ramin[e / 4 + 1];
935   return (w & 0xffff) * 0x10;
936}
937
938void nv2a_renderer::geforce_read_dma_object(UINT32 handle, UINT32 &offset, UINT32 &size)
939{
940   //UINT32 objclass,pt_present,pt_linear,access,target,rorw;
941   UINT32 dma_adjust, dma_frame;
942   UINT32 o = geforce_object_offset(handle);
943
944   o = o / 4;
945   //objclass=ramin[o] & 0xfff;
946   //pt_present=(ramin[o] >> 12) & 1;
947   //pt_linear=(ramin[o] >> 13) & 1;
948   //access=(ramin[o] >> 14) & 3;
949   //target=(ramin[o] >> 16) & 3;
950   dma_adjust = (ramin[o] >> 20) & 0xfff;
951   size = ramin[o + 1];
952   //rorw=ramin[o+2] & 1;
953   dma_frame = ramin[o + 2] & 0xfffff000;
954   offset = dma_frame + dma_adjust;
955}
956
957/*void myline(bitmap_rgb32 &bmp,float x1,float y1,float x2,float y2)
958{
959int xx1,yy1,xx2,yy2;
960
961   xx1=x1;
962   xx2=x2;
963   yy1=y1;
964   yy2=y2;
965   if (xx1 == xx2) {
966      if (yy1 > yy2) {
967         int t=yy1;
968         yy1=yy2;
969         yy2=t;
970      }
971      for (int y=yy1;y <= yy2;y++)
972         *((UINT32 *)bmp.raw_pixptr(y,xx1))= -1;
973      } else if (yy1 == yy2) {
974      if (xx1 > xx2) {
975         int t=xx1;
976         xx1=xx2;
977         xx2=t;
978      }
979      for (int x=xx1;x <= xx2;x++)
980         *((UINT32 *)bmp.raw_pixptr(yy1,x))= -1;
981   }
982}*/
983
984inline UINT32 convert_a4r4g4b4_a8r8g8b8(UINT32 a4r4g4b4)
985{
986   UINT32 a8r8g8b8;
987   int ca, cr, cg, cb;
988
989   cb = pal4bit(a4r4g4b4 & 0x000f);
990   cg = pal4bit((a4r4g4b4 & 0x00f0) >> 4);
991   cr = pal4bit((a4r4g4b4 & 0x0f00) >> 8);
992   ca = pal4bit((a4r4g4b4 & 0xf000) >> 12);
993   a8r8g8b8 = (ca << 24) | (cr << 16) | (cg << 8) | (cb); // color converted to 8 bits per component
994   return a8r8g8b8;
995}
996
997inline UINT32 convert_a1r5g5b5_a8r8g8b8(UINT32 a1r5g5b5)
998{
999   UINT32 a8r8g8b8;
1000   int ca, cr, cg, cb;
1001
1002   cb = pal5bit(a1r5g5b5 & 0x001f);
1003   cg = pal5bit((a1r5g5b5 & 0x03e0) >> 5);
1004   cr = pal5bit((a1r5g5b5 & 0x7c00) >> 10);
1005   ca = a1r5g5b5 & 0x8000 ? 0xff : 0;
1006   a8r8g8b8 = (ca << 24) | (cr << 16) | (cg << 8) | (cb); // color converted to 8 bits per component
1007   return a8r8g8b8;
1008}
1009
1010inline UINT32 convert_r5g6b5_r8g8b8(UINT32 r5g6b5)
1011{
1012   UINT32 r8g8b8;
1013   int cr, cg, cb;
1014
1015   cb = pal5bit(r5g6b5 & 0x001f);
1016   cg = pal6bit((r5g6b5 & 0x07e0) >> 5);
1017   cr = pal5bit((r5g6b5 & 0xf800) >> 11);
1018   r8g8b8 = (cr << 16) | (cg << 8) | (cb); // color converted to 8 bits per component
1019   return r8g8b8;
1020}
1021
1022UINT32 nv2a_renderer::texture_get_texel(int number, int x, int y)
1023{
1024   UINT32 to, s, c, sa, ca;
1025   UINT32 a4r4g4b4, a1r5g5b5, r5g6b5;
1026   int bx, by;
1027   int color0, color1, color0m2, color1m2, alpha0, alpha1;
1028   UINT32 codes;
1029   UINT64 alphas;
1030   int cr, cg, cb;
1031
1032   // force to [0,size-1]
1033   x = (unsigned int)x & (texture[number].sizeu - 1);
1034   y = (unsigned int)y & (texture[number].sizev - 1);
1035   switch (texture[number].format) {
1036   case A8R8G8B8:
1037      to = dilated0[texture[number].dilate][x] + dilated1[texture[number].dilate][y]; // offset of texel in texture memory
1038      return *(((UINT32 *)texture[number].buffer) + to); // get texel color
1039   case DXT1:
1040      bx = x >> 2;
1041      by = y >> 2;
1042      x = x & 3;
1043      y = y & 3;
1044      to = bx + by*(texture[number].sizeu >> 2);
1045      color0 = *((UINT16 *)(((UINT64 *)texture[number].buffer) + to) + 0);
1046      color1 = *((UINT16 *)(((UINT64 *)texture[number].buffer) + to) + 1);
1047      codes = *((UINT32 *)(((UINT64 *)texture[number].buffer) + to) + 1);
1048      s = (y << 3) + (x << 1);
1049      c = (codes >> s) & 3;
1050      c = c + (color0 > color1 ? 0 : 4);
1051      color0m2 = color0 << 1;
1052      color1m2 = color1 << 1;
1053      switch (c) {
1054      case 0:
1055         return 0xff000000 + convert_r5g6b5_r8g8b8(color0);
1056      case 1:
1057         return 0xff000000 + convert_r5g6b5_r8g8b8(color1);
1058      case 2:
1059         cb = pal5bit(((color0m2 & 0x003e) + (color1 & 0x001f)) / 3);
1060         cg = pal6bit(((color0m2 & 0x0fc0) + (color1 & 0x07e0)) / 3 >> 5);
1061         cr = pal5bit(((color0m2 & 0x1f000) + color1) / 3 >> 11);
1062         return 0xff000000 | (cr << 16) | (cg << 8) | (cb);
1063      case 3:
1064         cb = pal5bit(((color1m2 & 0x003e) + (color0 & 0x001f)) / 3);
1065         cg = pal6bit(((color1m2 & 0x0fc0) + (color0 & 0x07e0)) / 3 >> 5);
1066         cr = pal5bit(((color1m2 & 0x1f000) + color0) / 3 >> 11);
1067         return 0xff000000 | (cr << 16) | (cg << 8) | (cb);
1068      case 4:
1069         return 0xff000000 + convert_r5g6b5_r8g8b8(color0);
1070      case 5:
1071         return 0xff000000 + convert_r5g6b5_r8g8b8(color1);
1072      case 6:
1073         cb = pal5bit(((color0 & 0x001f) + (color1 & 0x001f)) / 2);
1074         cg = pal6bit(((color0 & 0x07e0) + (color1 & 0x07e0)) / 2 >> 5);
1075         cr = pal5bit(((color0 & 0xf800) + (color1 & 0xf800)) / 2 >> 11);
1076         return 0xff000000 | (cr << 16) | (cg << 8) | (cb);
1077      default:
1078         return 0xff000000;
1079      }
1080   case DXT3:
1081      bx = x >> 2;
1082      by = y >> 2;
1083      x = x & 3;
1084      y = y & 3;
1085      to = (bx + by*(texture[number].sizeu >> 2)) << 1;
1086      color0 = *((UINT16 *)(((UINT64 *)texture[number].buffer) + to) + 4);
1087      color1 = *((UINT16 *)(((UINT64 *)texture[number].buffer) + to) + 5);
1088      codes = *((UINT32 *)(((UINT64 *)texture[number].buffer) + to) + 3);
1089      alphas = *(((UINT64 *)texture[number].buffer) + to);
1090      s = (y << 3) + (x << 1);
1091      sa = ((y << 2) + x) << 2;
1092      c = (codes >> s) & 3;
1093      ca = (alphas >> sa) & 15;
1094      switch (c) {
1095      case 0:
1096         return ((ca + (ca << 4)) << 24) + convert_r5g6b5_r8g8b8(color0);
1097      case 1:
1098         return ((ca + (ca << 4)) << 24) + convert_r5g6b5_r8g8b8(color1);
1099      case 2:
1100         cb = pal5bit((2 * (color0 & 0x001f) + (color1 & 0x001f)) / 3);
1101         cg = pal6bit((2 * (color0 & 0x07e0) + (color1 & 0x07e0)) / 3 >> 5);
1102         cr = pal5bit((2 * (color0 & 0xf800) + (color1 & 0xf800)) / 3 >> 11);
1103         return ((ca + (ca << 4)) << 24) | (cr << 16) | (cg << 8) | (cb);
1104      default:
1105         cb = pal5bit(((color0 & 0x001f) + 2 * (color1 & 0x001f)) / 3);
1106         cg = pal6bit(((color0 & 0x07e0) + 2 * (color1 & 0x07e0)) / 3 >> 5);
1107         cr = pal5bit(((color0 & 0xf800) + 2 * (color1 & 0xf800)) / 3 >> 11);
1108         return ((ca + (ca << 4)) << 24) | (cr << 16) | (cg << 8) | (cb);
1109      }
1110   case A4R4G4B4:
1111      to = dilated0[texture[number].dilate][x] + dilated1[texture[number].dilate][y]; // offset of texel in texture memory
1112      a4r4g4b4 = *(((UINT16 *)texture[number].buffer) + to); // get texel color
1113      return convert_a4r4g4b4_a8r8g8b8(a4r4g4b4);
1114   case A1R5G5B5:
1115      to = dilated0[texture[number].dilate][x] + dilated1[texture[number].dilate][y]; // offset of texel in texture memory
1116      a1r5g5b5 = *(((UINT16 *)texture[number].buffer) + to); // get texel color
1117      return convert_a1r5g5b5_a8r8g8b8(a1r5g5b5);
1118   case R5G6B5:
1119      to = dilated0[texture[number].dilate][x] + dilated1[texture[number].dilate][y]; // offset of texel in texture memory
1120      r5g6b5 = *(((UINT16 *)texture[number].buffer) + to); // get texel color
1121      return 0xff000000 + convert_r5g6b5_r8g8b8(r5g6b5);
1122   case R8G8B8_RECT:
1123      to = texture[number].rectangle_pitch*y + (x << 2);
1124      return *((UINT32 *)(((UINT8 *)texture[number].buffer) + to));
1125   case A8R8G8B8_RECT:
1126      to = texture[number].rectangle_pitch*y + (x << 2);
1127      return *((UINT32 *)(((UINT8 *)texture[number].buffer) + to));
1128   case DXT5:
1129      bx = x >> 2;
1130      by = y >> 2;
1131      x = x & 3;
1132      y = y & 3;
1133      to = (bx + by*(texture[number].sizeu >> 2)) << 1;
1134      color0 = *((UINT16 *)(((UINT64 *)texture[number].buffer) + to) + 4);
1135      color1 = *((UINT16 *)(((UINT64 *)texture[number].buffer) + to) + 5);
1136      codes = *((UINT32 *)(((UINT64 *)texture[number].buffer) + to) + 3);
1137      alpha0 = *((UINT8 *)(((UINT64 *)texture[number].buffer) + to) + 0);
1138      alpha1 = *((UINT8 *)(((UINT64 *)texture[number].buffer) + to) + 1);
1139      alphas = *(((UINT64 *)texture[number].buffer) + to);
1140      s = (y << 3) + (x << 1);
1141      sa = ((y << 2) + x) * 3;
1142      c = (codes >> s) & 3;
1143      ca = (alphas >> sa) & 7;
1144      ca = ca + (alpha0 > alpha1 ? 0 : 8);
1145      switch (ca) {
1146      case 0:
1147         ca = alpha0;
1148         break;
1149      case 1:
1150         ca = alpha1;
1151         break;
1152      case 2:
1153         ca = (6 * alpha0 + 1 * alpha1) / 7;
1154         break;
1155      case 3:
1156         ca = (5 * alpha0 + 2 * alpha1) / 7;
1157         break;
1158      case 4:
1159         ca = (4 * alpha0 + 3 * alpha1) / 7;
1160         break;
1161      case 5:
1162         ca = (3 * alpha0 + 4 * alpha1) / 7;
1163         break;
1164      case 6:
1165         ca = (2 * alpha0 + 5 * alpha1) / 7;
1166         break;
1167      case 7:
1168         ca = (1 * alpha0 + 6 * alpha1) / 7;
1169         break;
1170      case 8:
1171         ca = alpha0;
1172         break;
1173      case 9:
1174         ca = alpha1;
1175         break;
1176      case 10:
1177         ca = (4 * alpha0 + 1 * alpha1) / 5;
1178         break;
1179      case 11:
1180         ca = (3 * alpha0 + 2 * alpha1) / 5;
1181         break;
1182      case 12:
1183         ca = (2 * alpha0 + 3 * alpha1) / 5;
1184         break;
1185      case 13:
1186         ca = (1 * alpha0 + 4 * alpha1) / 5;
1187         break;
1188      case 14:
1189         ca = 0;
1190         break;
1191      case 15:
1192         ca = 255;
1193         break;
1194      }
1195      switch (c) {
1196      case 0:
1197         return (ca << 24) + convert_r5g6b5_r8g8b8(color0);
1198      case 1:
1199         return (ca << 24) + convert_r5g6b5_r8g8b8(color1);
1200      case 2:
1201         cb = pal5bit((2 * (color0 & 0x001f) + (color1 & 0x001f)) / 3);
1202         cg = pal6bit((2 * (color0 & 0x07e0) + (color1 & 0x07e0)) / 3 >> 5);
1203         cr = pal5bit((2 * (color0 & 0xf800) + (color1 & 0xf800)) / 3 >> 11);
1204         return (ca << 24) | (cr << 16) | (cg << 8) | (cb);
1205      default:
1206         cb = pal5bit(((color0 & 0x001f) + 2 * (color1 & 0x001f)) / 3);
1207         cg = pal6bit(((color0 & 0x07e0) + 2 * (color1 & 0x07e0)) / 3 >> 5);
1208         cr = pal5bit(((color0 & 0xf800) + 2 * (color1 & 0xf800)) / 3 >> 11);
1209         return (ca << 24) | (cr << 16) | (cg << 8) | (cb);
1210      }
1211   default:
1212      return 0xff00ff00;
1213   }
1214}
1215
1216void nv2a_renderer::write_pixel(int x, int y, UINT32 color)
1217{
1218   void *addr;
1219   UINT32 fbcolor;
1220   UINT32 c[4], fb[4], s[4], d[4], cc[4];
1221
1222   addr = this->fb.raw_pixptr(y, x);
1223   fbcolor = *((UINT32 *)addr);
1224   c[3] = color >> 24;
1225   c[2] = (color >> 16) & 255;
1226   c[1] = (color >> 8) & 255;
1227   c[0] = color & 255;
1228   fb[3] = fbcolor >> 24;
1229   fb[2] = (fbcolor >> 16) & 255;
1230   fb[1] = (fbcolor >> 8) & 255;
1231   fb[0] = fbcolor & 255;
1232   cc[3] = blend_color >> 24;
1233   cc[2] = (blend_color >> 16) & 255;
1234   cc[1] = (blend_color >> 8) & 255;
1235   cc[0] = blend_color & 255;
1236   // ownership test and scissor test not done
1237   // alpha test
1238   if (alpha_test_enabled) {
1239      switch (alpha_func) {
1240      case nv2a_renderer::NEVER:
1241         return;
1242      case nv2a_renderer::ALWAYS:
1243      default:
1244         break;
1245      case nv2a_renderer::LESS:
1246         if (c[3] >= alpha_reference)
1247            return;
1248         break;
1249      case nv2a_renderer::LEQUAL:
1250         if (c[3] > alpha_reference)
1251            return;
1252         break;
1253      case nv2a_renderer::EQUAL:
1254         if (c[3] != alpha_reference)
1255            return;
1256         break;
1257      case nv2a_renderer::GEQUAL:
1258         if (c[3] < alpha_reference)
1259            return;
1260         break;
1261      case nv2a_renderer::GREATER:
1262         if (c[3] <= alpha_reference)
1263            return;
1264         break;
1265      case nv2a_renderer::NOTEQUAL:
1266         if (c[3] == alpha_reference)
1267            return;
1268         break;
1269      }
1270   }
1271   // stencil test not done
1272   // depth buffer test not done
1273   // blending
1274   if (blending_enabled) {
1275      switch (blend_function_source) {
1276      case nv2a_renderer::ZERO:
1277         s[3] = s[2] = s[1] = s[0] = 0;
1278         break;
1279      case nv2a_renderer::ONE:
1280      default:
1281         s[3] = s[2] = s[1] = s[0] = 255;
1282         break;
1283      case nv2a_renderer::DST_COLOR:
1284         s[3] = fb[3];
1285         s[2] = fb[2];
1286         s[1] = fb[1];
1287         s[0] = fb[0];
1288         break;
1289      case nv2a_renderer::ONE_MINUS_DST_COLOR:
1290         s[3] = fb[3] ^ 255;
1291         s[2] = fb[2] ^ 255;
1292         s[1] = fb[1] ^ 255;
1293         s[0] = fb[0] ^ 255;
1294         break;
1295      case nv2a_renderer::SRC_ALPHA:
1296         s[3] = s[2] = s[1] = s[0] = c[3];
1297         break;
1298      case nv2a_renderer::ONE_MINUS_SRC_ALPHA:
1299         s[3] = s[2] = s[1] = s[0] = c[3] ^ 255;
1300         break;
1301      case nv2a_renderer::DST_ALPHA:
1302         s[3] = s[2] = s[1] = s[0] = fb[3];
1303         break;
1304      case nv2a_renderer::ONE_MINUS_DST_ALPHA:
1305         s[3] = s[2] = s[1] = s[0] = fb[3] ^ 255;
1306         break;
1307      case nv2a_renderer::CONSTANT_COLOR:
1308         s[3] = cc[3];
1309         s[2] = cc[2];
1310         s[1] = cc[1];
1311         s[0] = cc[0];
1312         break;
1313      case nv2a_renderer::ONE_MINUS_CONSTANT_COLOR:
1314         s[3] = cc[3] ^ 255;
1315         s[2] = cc[2] ^ 255;
1316         s[1] = cc[1] ^ 255;
1317         s[0] = cc[0] ^ 255;
1318         break;
1319      case nv2a_renderer::CONSTANT_ALPHA:
1320         s[3] = s[2] = s[1] = s[0] = cc[3];
1321         break;
1322      case nv2a_renderer::ONE_MINUS_CONSTANT_ALPHA:
1323         s[3] = s[2] = s[1] = s[0] = cc[3] ^ 255;
1324         break;
1325      case nv2a_renderer::SRC_ALPHA_SATURATE:
1326         s[3] = 255;
1327         if (c[3] < (fb[3] ^ 255))
1328            s[2] = c[3];
1329         else
1330            s[2] = fb[3];
1331         s[1] = s[0] = s[2];
1332         break;
1333      }
1334      switch (blend_function_destination) {
1335      case nv2a_renderer::ZERO:
1336      default:
1337         d[3] = d[2] = d[1] = d[0] = 0;
1338         break;
1339      case nv2a_renderer::ONE:
1340         d[3] = d[2] = d[1] = d[0] = 255;
1341         break;
1342      case nv2a_renderer::SRC_COLOR:
1343         d[3] = c[3];
1344         d[2] = c[2];
1345         d[1] = c[1];
1346         d[0] = c[0];
1347         break;
1348      case nv2a_renderer::ONE_MINUS_SRC_COLOR:
1349         d[3] = c[3] ^ 255;
1350         d[2] = c[2] ^ 255;
1351         d[1] = c[1] ^ 255;
1352         d[0] = c[0] ^ 255;
1353         break;
1354      case nv2a_renderer::SRC_ALPHA:
1355         d[3] = d[2] = d[1] = d[0] = c[3];
1356         break;
1357      case nv2a_renderer::ONE_MINUS_SRC_ALPHA:
1358         d[3] = d[2] = d[1] = d[0] = c[3] ^ 255;
1359         break;
1360      case nv2a_renderer::DST_ALPHA:
1361         d[3] = d[2] = d[1] = d[0] = fb[3];
1362         break;
1363      case nv2a_renderer::ONE_MINUS_DST_ALPHA:
1364         d[3] = d[2] = d[1] = d[0] = fb[3] ^ 255;
1365         break;
1366      case nv2a_renderer::CONSTANT_COLOR:
1367         d[3] = cc[3];
1368         d[2] = cc[2];
1369         d[1] = cc[1];
1370         d[0] = cc[0];
1371         break;
1372      case nv2a_renderer::ONE_MINUS_CONSTANT_COLOR:
1373         d[3] = cc[3] ^ 255;
1374         d[2] = cc[2] ^ 255;
1375         d[1] = cc[1] ^ 255;
1376         d[0] = cc[0] ^ 255;
1377         break;
1378      case nv2a_renderer::CONSTANT_ALPHA:
1379         d[3] = d[2] = d[1] = d[0] = cc[3];
1380         break;
1381      case nv2a_renderer::ONE_MINUS_CONSTANT_ALPHA:
1382         d[3] = d[2] = d[1] = d[0] = cc[3] ^ 255;
1383         break;
1384      }
1385      switch (blend_equation) {
1386      case nv2a_renderer::FUNC_ADD:
1387         c[3] = (c[3] * s[3] + fb[3] * d[3]) / 255;
1388         if (c[3] > 255)
1389            c[3] = 255;
1390         c[2] = (c[2] * s[2] + fb[2] * d[2]) / 255;
1391         if (c[2] > 255)
1392            c[2] = 255;
1393         c[1] = (c[1] * s[1] + fb[1] * d[1]) / 255;
1394         if (c[1] > 255)
1395            c[1] = 255;
1396         c[0] = (c[0] * s[0] + fb[0] * d[0]) / 255;
1397         if (c[0] > 255)
1398            c[0] = 255;
1399         break;
1400      case nv2a_renderer::FUNC_SUBTRACT:
1401         c[3] = (c[3] * s[3] - fb[3] * d[3]) / 255;
1402         if (c[3] < 0)
1403            c[3] = 255;
1404         c[2] = (c[2] * s[2] - fb[2] * d[2]) / 255;
1405         if (c[2] < 0)
1406            c[2] = 255;
1407         c[1] = (c[1] * s[1] - fb[1] * d[1]) / 255;
1408         if (c[1] < 0)
1409            c[1] = 255;
1410         c[0] = (c[0] * s[0] - fb[0] * d[0]) / 255;
1411         if (c[0] < 0)
1412            c[0] = 255;
1413         break;
1414      case nv2a_renderer::FUNC_REVERSE_SUBTRACT:
1415         c[3] = (fb[3] * d[3] - c[3] * s[3]) / 255;
1416         if (c[3] < 0)
1417            c[3] = 255;
1418         c[2] = (fb[2] * d[2] - c[2] * s[2]) / 255;
1419         if (c[2] < 0)
1420            c[2] = 255;
1421         c[1] = (fb[1] * d[1] - c[1] * s[1]) / 255;
1422         if (c[1] < 0)
1423            c[1] = 255;
1424         c[0] = (fb[0] * d[0] - c[0] * s[0]) / 255;
1425         if (c[0] < 0)
1426            c[0] = 255;
1427         break;
1428      case nv2a_renderer::MIN:
1429         c[3] = s[3];
1430         if (d[3] < c[3])
1431            c[3] = d[3];
1432         c[2] = s[2];
1433         if (d[2] < c[2])
1434            c[2] = d[2];
1435         c[1] = s[1];
1436         if (d[1] < c[1])
1437            c[1] = d[1];
1438         c[0] = s[0];
1439         if (d[0] < c[0])
1440            c[0] = d[0];
1441         break;
1442      case nv2a_renderer::MAX:
1443         c[3] = s[3];
1444         if (d[3] > c[3])
1445            c[3] = d[3];
1446         c[2] = s[2];
1447         if (d[2] > c[2])
1448            c[2] = d[2];
1449         c[1] = s[1];
1450         if (d[1] > c[1])
1451            c[1] = d[1];
1452         c[0] = s[0];
1453         if (d[0] > c[0])
1454            c[0] = d[0];
1455         break;
1456      }
1457   }
1458   // dithering not done
1459   // logical operation
1460   if (logical_operation_enabled) {
1461      switch (logical_operation) {
1462      case  nv2a_renderer::CLEAR:
1463         c[3] = 0;
1464         c[2] = 0;
1465         c[1] = 0;
1466         c[0] = 0;
1467         break;
1468      case  nv2a_renderer::AND:
1469         c[3] = c[3] & fb[3];
1470         c[2] = c[2] & fb[2];
1471         c[1] = c[1] & fb[1];
1472         c[0] = c[0] & fb[0];
1473         break;
1474      case  nv2a_renderer::AND_REVERSE:
1475         c[3] = c[3] & (fb[3] ^ 255);
1476         c[2] = c[2] & (fb[2] ^ 255);
1477         c[1] = c[1] & (fb[1] ^ 255);
1478         c[0] = c[0] & (fb[0] ^ 255);
1479         break;
1480      case  nv2a_renderer::COPY:
1481      default:
1482         break;
1483      case  nv2a_renderer::AND_INVERTED:
1484         c[3] = (c[3] ^ 255) & fb[3];
1485         c[2] = (c[2] ^ 255) & fb[2];
1486         c[1] = (c[1] ^ 255) & fb[1];
1487         c[0] = (c[0] ^ 255) & fb[0];
1488         break;
1489      case  nv2a_renderer::NOOP:
1490         c[3] = fb[3];
1491         c[2] = fb[2];
1492         c[1] = fb[1];
1493         c[0] = fb[0];
1494         break;
1495      case  nv2a_renderer::XOR:
1496         c[3] = c[3] ^ fb[3];
1497         c[2] = c[2] ^ fb[2];
1498         c[1] = c[1] ^ fb[1];
1499         c[0] = c[0] ^ fb[0];
1500         break;
1501      case  nv2a_renderer::OR:
1502         c[3] = c[3] | fb[3];
1503         c[2] = c[2] | fb[2];
1504         c[1] = c[1] | fb[1];
1505         c[0] = c[0] | fb[0];
1506         break;
1507      case  nv2a_renderer::NOR:
1508         c[3] = (c[3] | fb[3]) ^ 255;
1509         c[2] = (c[2] | fb[2]) ^ 255;
1510         c[1] = (c[1] | fb[1]) ^ 255;
1511         c[0] = (c[0] | fb[0]) ^ 255;
1512         break;
1513      case  nv2a_renderer::EQUIV:
1514         c[3] = (c[3] ^ fb[3]) ^ 255;
1515         c[2] = (c[2] ^ fb[2]) ^ 255;
1516         c[1] = (c[1] ^ fb[1]) ^ 255;
1517         c[0] = (c[0] ^ fb[0]) ^ 255;
1518         break;
1519      case  nv2a_renderer::INVERT:
1520         c[3] = fb[3] ^ 255;
1521         c[2] = fb[2] ^ 255;
1522         c[1] = fb[1] ^ 255;
1523         c[0] = fb[0] ^ 255;
1524         break;
1525      case  nv2a_renderer::OR_REVERSE:
1526         c[3] = c[3] | (fb[3] ^ 255);
1527         c[2] = c[2] | (fb[2] ^ 255);
1528         c[1] = c[1] | (fb[1] ^ 255);
1529         c[0] = c[0] | (fb[0] ^ 255);
1530         break;
1531      case  nv2a_renderer::COPY_INVERTED:
1532         c[3] = c[3] ^ 255;
1533         c[2] = c[2] ^ 255;
1534         c[1] = c[1] ^ 255;
1535         c[0] = c[0] ^ 255;
1536         break;
1537      case  nv2a_renderer::OR_INVERTED:
1538         c[3] = (c[3] ^ 255) | fb[3];
1539         c[2] = (c[2] ^ 255) | fb[2];
1540         c[1] = (c[1] ^ 255) | fb[1];
1541         c[0] = (c[0] ^ 255) | fb[0];
1542         break;
1543      case  nv2a_renderer::NAND:
1544         c[3] = (c[3] & fb[3]) ^ 255;
1545         c[2] = (c[2] & fb[2]) ^ 255;
1546         c[1] = (c[1] & fb[1]) ^ 255;
1547         c[0] = (c[0] & fb[0]) ^ 255;
1548         break;
1549      case  nv2a_renderer::SET:
1550         c[3] = 255;
1551         c[2] = 255;
1552         c[1] = 255;
1553         c[0] = 255;
1554         break;
1555      }
1556   }
1557   fbcolor = (c[3] << 24) | (c[2] << 16) | (c[1] << 8) | c[0];
1558   *((UINT32 *)addr) = fbcolor;
1559}
1560
1561void nv2a_renderer::render_color(INT32 scanline, const extent_t &extent, const nvidia_object_data &objectdata, int threadid)
1562{
1563   int x;
1564
1565   if ((extent.startx < 0) || (extent.stopx > 640))
1566      return;
1567   x = extent.stopx - extent.startx - 1; // number of pixels to draw
1568   while (x >= 0) {
1569      UINT32 a8r8g8b8;
1570      int ca, cr, cg, cb;
1571      int xp = extent.startx + x; // x coordinate of current pixel
1572
1573      cb = ((extent.param[0].start + (float)x*extent.param[0].dpdx))*255.0;
1574      cg = ((extent.param[1].start + (float)x*extent.param[1].dpdx))*255.0;
1575      cr = ((extent.param[2].start + (float)x*extent.param[2].dpdx))*255.0;
1576      ca = ((extent.param[3].start + (float)x*extent.param[3].dpdx))*255.0;
1577      a8r8g8b8 = (ca << 24) + (cr << 16) + (cg << 8) + cb; // pixel color obtained by interpolating the colors of the vertices
1578      write_pixel(xp, scanline, a8r8g8b8);
1579      x--;
1580   }
1581}
1582
1583void nv2a_renderer::render_texture_simple(INT32 scanline, const extent_t &extent, const nvidia_object_data &objectdata, int threadid)
1584{
1585   int x;
1586   UINT32 a8r8g8b8;
1587
1588   if (!objectdata.data->texture[0].enabled) {
1589      return;
1590   }
1591   if ((extent.startx < 0) || (extent.stopx > 640))
1592      return;
1593   x = extent.stopx - extent.startx - 1;
1594   while (x >= 0) {
1595      int up, vp;
1596      int xp = extent.startx + x; // x coordinate of current pixel
1597
1598      up = (extent.param[4].start + (float)x*extent.param[4].dpdx)*(float)(objectdata.data->texture[0].sizeu - 1); // x coordinate of texel in texture
1599      vp = extent.param[5].start*(float)(objectdata.data->texture[0].sizev - 1); // y coordinate of texel in texture
1600      a8r8g8b8 = texture_get_texel(0, up, vp);
1601      write_pixel(xp, scanline, a8r8g8b8);
1602      x--;
1603   }
1604}
1605
1606void nv2a_renderer::render_register_combiners(INT32 scanline, const extent_t &extent, const nvidia_object_data &objectdata, int threadid)
1607{
1608   int x, xp;
1609   int up, vp;
1610   int ca, cr, cg, cb;
1611   UINT32 color[6];
1612   UINT32 a8r8g8b8;
1613   int n;//,m,i,j,k;
1614
1615   color[0] = color[1] = color[2] = color[3] = color[4] = color[5] = 0;
1616
1617   if ((extent.startx < 0) || (extent.stopx > 640))
1618      return;
1619   osd_lock_acquire(combiner.lock); // needed since multithreading is not supported yet
1620   x = extent.stopx - extent.startx - 1; // number of pixels to draw
1621   while (x >= 0) {
1622      xp = extent.startx + x;
1623      // 1: fetch data
1624      // 1.1: interpolated color from vertices
1625      cb = ((extent.param[0].start + (float)x*extent.param[0].dpdx))*255.0;
1626      cg = ((extent.param[1].start + (float)x*extent.param[1].dpdx))*255.0;
1627      cr = ((extent.param[2].start + (float)x*extent.param[2].dpdx))*255.0;
1628      ca = ((extent.param[3].start + (float)x*extent.param[3].dpdx))*255.0;
1629      color[0] = (ca << 24) + (cr << 16) + (cg << 8) + cb; // pixel color obtained by interpolating the colors of the vertices
1630      color[1] = 0; // lighting not yet
1631      // 1.2: color for each of the 4 possible textures
1632      for (n = 0; n < 4; n++) {
1633         if (texture[n].enabled) {
1634            up = (extent.param[4 + n * 2].start + (float)x*extent.param[4 + n * 2].dpdx)*(float)(objectdata.data->texture[n].sizeu - 1);
1635            vp = extent.param[5 + n * 2].start*(float)(objectdata.data->texture[n].sizev - 1);
1636            color[n + 2] = texture_get_texel(n, up, vp);
1637         }
1638      }
1639      // 2: compute
1640      // 2.1: initialize
1641      combiner_initialize_registers(color);
1642      // 2.2: general cmbiner stages
1643      for (n = 0; n < combiner.stages; n++) {
1644         // 2.2.1 initialize
1645         combiner_initialize_stage(n);
1646         // 2.2.2 map inputs
1647         combiner_map_input(n);
1648         // 2.2.3 compute possible outputs
1649         combiner_compute_rgb_outputs(n);
1650         combiner_compute_a_outputs(n);
1651         // 2.2.4 map outputs to registers
1652         combiner_map_output(n);
1653      }
1654      // 2.3: final cmbiner stage
1655      combiner_initialize_final();
1656      combiner_map_final_input();
1657      combiner_final_output();
1658      a8r8g8b8 = combiner_float_argb8(combiner.output);
1659      // 3: write pixel
1660      write_pixel(xp, scanline, a8r8g8b8);
1661      x--;
1662   }
1663   osd_lock_release(combiner.lock);
1664}
1665
1666#if 0
1667const char *rc_mapping_str[] = {
1668   "UNSIGNED_IDENTITY",
1669   "UNSIGNED_INVERT",
1670   "EXPAND_NORMAL",
1671   "EXPAND_NEGATE",
1672   "HALF_BIAS_NORMAL",
1673   "HALF_BIAS_NEGATE",
1674   "SIGNED_IDENTITY",
1675   "SIGNED_NEGATE"
1676};
1677
1678const char *rc_usage_rgb_str[] = {
1679   "RGB",
1680   "ALPHA"
1681};
1682
1683const char *rc_usage_alpha_str[] = {
1684   "BLUE",
1685   "ALPHA"
1686};
1687
1688const char *rc_variable_str[] = {
1689   "ZERO",
1690   "CONSTANT_COLOR0",
1691   "CONSTANT_COLOR1",
1692   "FOG",
1693   "PRIMARY_COLOR",
1694   "SECONDARY_COLOR",
1695   "???",
1696   "???",
1697   "TEXTURE0",
1698   "TEXTURE1",
1699   "TEXTURE2",
1700   "TEXTURE3",
1701   "SPARE0",
1702   "SPARE1",
1703   "SPARE0_PLUS_SECONDARY_COLOR",
1704   "E_TIMES_F"
1705};
1706
1707const char *rc_bias_str[] = {
1708   "NONE",
1709   "BIAS_BY_NEGATIVE_ONE_HALF"
1710};
1711
1712const char *rc_scale_str[] = {
1713   "NONE",
1714   "SCALE_BY_TWO",
1715   "SCALE_BY_FOUR",
1716   "SCALE_BY_ONE_HALF"
1717};
1718
1719/* Dump the current setup of the register combiners */
1720void dumpcombiners(UINT32 *m)
1721{
1722   int a, b, n, v;
1723
1724   n = m[0x1e60 / 4] & 0xf;
1725   printf("Combiners active: %d\n\r", n);
1726   for (a = 0; a < n; a++) {
1727      printf("Combiner %d\n\r", a + 1);
1728      printf(" RC_IN_ALPHA %08X\n\r", m[0x0260 / 4 + a]);
1729      for (b = 24; b >= 0; b = b - 8) {
1730         v = (m[0x0260 / 4 + a] >> b) & 0xf;
1731         printf("  %c_INPUT %s\n\r", 'A' + 3 - b / 8, rc_variable_str[v]);
1732         v = (m[0x0260 / 4 + a] >> (b + 4)) & 1;
1733         printf("  %c_COMPONENT_USAGE %s\n\r", 'A' + 3 - b / 8, rc_usage_alpha_str[v]);
1734         v = (m[0x0260 / 4 + a] >> (b + 5)) & 7;
1735         printf("  %c_MAPPING %s\n\r", 'A' + 3 - b / 8, rc_mapping_str[v]);
1736      }
1737      printf(" RC_IN_RGB %08X\n\r", m[0x0ac0 / 4 + a]);
1738      for (b = 24; b >= 0; b = b - 8) {
1739         v = (m[0x0ac0 / 4 + a] >> b) & 0xf;
1740         printf("  %c_INPUT %s\n\r", 'A' + 3 - b / 8, rc_variable_str[v]);
1741         v = (m[0x0ac0 / 4 + a] >> (b + 4)) & 1;
1742         printf("  %c_COMPONENT_USAGE %s\n\r", 'A' + 3 - b / 8, rc_usage_rgb_str[v]);
1743         v = (m[0x0ac0 / 4 + a] >> (b + 5)) & 7;
1744         printf("  %c_MAPPING %s\n\r", 'A' + 3 - b / 8, rc_mapping_str[v]);
1745      }
1746      printf(" RC_OUT_ALPHA %08X\n\r", m[0x0aa0 / 4 + a]);
1747      v = m[0x0aa0 / 4 + a] & 0xf;
1748      printf("  CD_OUTPUT %s\n\r", rc_variable_str[v]);
1749      v = (m[0x0aa0 / 4 + a] >> 4) & 0xf;
1750      printf("  AB_OUTPUT %s\n\r", rc_variable_str[v]);
1751      v = (m[0x0aa0 / 4 + a] >> 8) & 0xf;
1752      printf("  SUM_OUTPUT %s\n\r", rc_variable_str[v]);
1753      v = (m[0x0aa0 / 4 + a] >> 12) & 1;
1754      printf("  CD_DOT_PRODUCT %d\n\r", v);
1755      v = (m[0x0aa0 / 4 + a] >> 13) & 1;
1756      printf("  AB_DOT_PRODUCT %d\n\r", v);
1757      v = (m[0x0aa0 / 4 + a] >> 14) & 1;
1758      printf("  MUX_SUM %d\n\r", v);
1759      v = (m[0x0aa0 / 4 + a] >> 15) & 1;
1760      printf("  BIAS %s\n\r", rc_bias_str[v]);
1761      v = (m[0x0aa0 / 4 + a] >> 16) & 3;
1762      printf("  SCALE %s\n\r", rc_scale_str[v]);
1763      //v=(m[0x0aa0/4+a] >> 27) & 7;
1764      printf(" RC_OUT_RGB %08X\n\r", m[0x1e40 / 4 + a]);
1765      v = m[0x1e40 / 4 + a] & 0xf;
1766      printf("  CD_OUTPUT %s\n\r", rc_variable_str[v]);
1767      v = (m[0x1e40 / 4 + a] >> 4) & 0xf;
1768      printf("  AB_OUTPUT %s\n\r", rc_variable_str[v]);
1769      v = (m[0x1e40 / 4 + a] >> 8) & 0xf;
1770      printf("  SUM_OUTPUT %s\n\r", rc_variable_str[v]);
1771      v = (m[0x1e40 / 4 + a] >> 12) & 1;
1772      printf("  CD_DOT_PRODUCT %d\n\r", v);
1773      v = (m[0x1e40 / 4 + a] >> 13) & 1;
1774      printf("  AB_DOT_PRODUCT %d\n\r", v);
1775      v = (m[0x1e40 / 4 + a] >> 14) & 1;
1776      printf("  MUX_SUM %d\n\r", v);
1777      v = (m[0x1e40 / 4 + a] >> 15) & 1;
1778      printf("  BIAS %s\n\r", rc_bias_str[v]);
1779      v = (m[0x1e40 / 4 + a] >> 16) & 3;
1780      printf("  SCALE %s\n\r", rc_scale_str[v]);
1781      //v=(m[0x1e40/4+a] >> 27) & 7;
1782      printf("\n\r");
1783   }
1784   printf("Combiner final %08X %08X\n\r", m[0x0288 / 4], m[0x028c / 4]);
1785   for (a = 24; a >= 0; a = a - 8) {
1786      n = (m[0x0288 / 4] >> a) & 0xf;
1787      printf("  %c_INPUT %s\n\r", 'A' + 3 - a / 8, rc_variable_str[n]);
1788      n = (m[0x0288 / 4] >> (a + 4)) & 1;
1789      printf("  %c_COMPONENT_USAGE %s\n\r", 'A' + 3 - a / 8, rc_usage_rgb_str[n]);
1790      n = (m[0x0288 / 4] >> (a + 5)) & 7;
1791      printf("  %c_MAPPING %s\n\r", 'A' + 3 - a / 8, rc_mapping_str[n]);
1792   }
1793   for (a = 24; a >= 8; a = a - 8) {
1794      n = (m[0x028c / 4] >> a) & 0xf;
1795      printf("  %c_INPUT %s\n\r", 'E' + 3 - a / 8, rc_variable_str[n]);
1796      n = (m[0x028c / 4] >> (a + 4)) & 1;
1797      printf("  %c_COMPONENT_USAGE %s\n\r", 'E' + 3 - a / 8, rc_usage_rgb_str[n]);
1798      n = (m[0x028c / 4] >> (a + 5)) & 7;
1799      printf("  %c_MAPPING %s\n\r", 'E' + 3 - a / 8, rc_mapping_str[n]);
1800   }
1801   n = (m[0x028c / 4] >> 7) & 1;
1802   printf(" color sum clamp: %d\n\r", n);
1803}
1804#endif
1805
1806void nv2a_renderer::read_vertex(address_space & space, offs_t address, vertex_nv &vertex, int attrib)
1807{
1808   UINT32 u;
1809   int c, d, l;
1810
1811   l = vertexbuffer_size[attrib];
1812   switch (vertexbuffer_kind[attrib]) {
1813   case NV2A_VTXBUF_TYPE_FLOAT:
1814   default:
1815      vertex.attribute[attrib].fv[0] = 0;
1816      vertex.attribute[attrib].fv[1] = 0;
1817      vertex.attribute[attrib].fv[2] = 0;
1818      vertex.attribute[attrib].fv[3] = 1.0;
1819      for (c = d = 0; c < l; c++) {
1820         vertex.attribute[attrib].iv[c] = space.read_dword(address + d);
1821         d = d + 4;
1822      }
1823      break;
1824   case NV2A_VTXBUF_TYPE_UBYTE:
1825      break;
1826   case  NV2A_VTXBUF_TYPE_UNKNOWN_0:
1827      u = space.read_dword(address + 0);
1828      for (c = 0; c < l; c++) {
1829         vertex.attribute[attrib].fv[c] = (u & 0xff) / 255.0;
1830         u = u >> 8;
1831      }
1832      break;
1833   case NV2A_VTXBUF_TYPE_UNKNOWN_6: // ???
1834      u = space.read_dword(address + 0);
1835      vertex.attribute[attrib].fv[0] = (u & 0xff) / 255.0; // b
1836      vertex.attribute[attrib].fv[1] = ((u & 0xff00) >> 8) / 255.0;  // g
1837      vertex.attribute[attrib].fv[2] = ((u & 0xff0000) >> 16) / 255.0;  // r
1838      vertex.attribute[attrib].fv[3] = ((u & 0xff000000) >> 24) / 255.0;  // a
1839      break;
1840   }
1841}
1842
1843/* Read vertices data from system memory. Method 0x1810 */
1844int nv2a_renderer::read_vertices_0x1810(address_space & space, vertex_nv *destination, int offset, int limit)
1845{
1846   UINT32 m;
1847   int a, b;
1848
1849#ifdef MAME_DEBUG
1850   memset(destination, 0, sizeof(vertex_nv)*limit);
1851#endif
1852   for (m = 0; m < limit; m++) {
1853      b = enabled_vertex_attributes;
1854      for (a = 0; a < 16; a++) {
1855         if (b & 1) {
1856            read_vertex(space, vertexbuffer_address[a] + (m + offset)*vertexbuffer_stride[a], destination[m], a);
1857         }
1858         b = b >> 1;
1859      }
1860   }
1861   return m;
1862}
1863
1864/* Read vertices data from system memory. Method 0x1800 */
1865int nv2a_renderer::read_vertices_0x1800(address_space & space, vertex_nv *destination, UINT32 address, int limit)
1866{
1867   UINT32 data;
1868   UINT32 m, i, c;
1869   int a, b;
1870
1871#ifdef MAME_DEBUG
1872   memset(destination, 0, sizeof(vertex_nv)*limit);
1873#endif
1874   c = 0;
1875   for (m = 0; m < limit; m++) {
1876      if (indexesleft_count == 0) {
1877         data = space.read_dword(address);
1878         i = (indexesleft_first + indexesleft_count) & 7;
1879         indexesleft[i] = data & 0xffff;
1880         indexesleft[(i + 1) & 7] = (data >> 16) & 0xffff;
1881         indexesleft_count = indexesleft_count + 2;
1882         address += 4;
1883         c++;
1884      }
1885      b = enabled_vertex_attributes;
1886      for (a = 0; a < 16; a++) {
1887         if (b & 1) {
1888            read_vertex(space, vertexbuffer_address[a] + indexesleft[indexesleft_first] * vertexbuffer_stride[a], destination[m], a);
1889         }
1890         b = b >> 1;
1891      }
1892      indexesleft_first = (indexesleft_first + 1) & 7;
1893      indexesleft_count--;
1894   }
1895   return (int)c;
1896}
1897
1898/* Read vertices data from system memory. Method 0x1818 */
1899int nv2a_renderer::read_vertices_0x1818(address_space & space, vertex_nv *destination, UINT32 address, int limit)
1900{
1901   UINT32 m, vwords;
1902   int a, b;
1903
1904#ifdef MAME_DEBUG
1905   memset(destination, 0, sizeof(vertex_nv)*limit);
1906#endif
1907   vwords = vertex_attribute_words[15] + vertex_attribute_offset[15];
1908   for (m = 0; m < limit; m++) {
1909      b = enabled_vertex_attributes;
1910      for (a = 0; a < 16; a++) {
1911         if (b & 1) {
1912            read_vertex(space, address + vertex_attribute_offset[a] * 4, destination[m], a);
1913         }
1914         b = b >> 1;
1915      }
1916      address = address + vwords * 4;
1917   }
1918   return (int)(m*vwords);
1919}
1920
1921void nv2a_renderer::convert_vertices_poly(vertex_nv *source, vertex_t *destination, int count)
1922{
1923   int m, u;
1924
1925   // take each vertex with its attributes and obtain data for drawing
1926   // should use either the vertex program or transformation matrices
1927   if (vertex_pipeline == 4) {
1928      // transformation matrices
1929      // it is not implemented, so we pretend its always using screen coordinates
1930      for (m = 0; m < count; m++) {
1931         destination[m].x = source[m].attribute[0].fv[0];
1932         destination[m].y = source[m].attribute[0].fv[1];
1933         for (u = 0; u < 4; u++) // 0=b 1=g 2=r 3=a
1934            destination[m].p[u] = source[m].attribute[3].fv[u];
1935         for (u = 0; u < 4; u++) {
1936            destination[m].p[4 + u * 2] = source[m].attribute[9 + u].fv[0];
1937            destination[m].p[5 + u * 2] = source[m].attribute[9 + u].fv[1];
1938         }
1939      }
1940   }
1941   else {
1942      // vertex program
1943      vertex_nv vert[4];
1944      // run vertex program
1945      vertexprogram.exec.process(vertexprogram.start_instruction, source, vert, count);
1946      // copy data for poly.c
1947      for (m = 0; m < count; m++) {
1948         destination[m].x = vert[m].attribute[0].fv[0];
1949         destination[m].y = vert[m].attribute[0].fv[1];
1950         for (u = 0; u < 4; u++) // 0=b 1=g 2=r 3=a
1951            destination[m].p[u] = vert[m].attribute[3].fv[u];
1952         for (u = 0; u < 4; u++) {
1953            destination[m].p[4 + u * 2] = vert[m].attribute[9 + u].fv[0];
1954            destination[m].p[5 + u * 2] = vert[m].attribute[9 + u].fv[1];
1955         }
1956      }
1957   }
1958}
1959
1960void nv2a_renderer::geforce_exec_method(address_space & space, UINT32 chanel, UINT32 subchannel, UINT32 method, UINT32 address, int &countlen)
1961{
1962   UINT32 maddress;
1963   UINT32 data;
1964
1965   maddress = method * 4;
1966   data = space.read_dword(address);
1967   channel[chanel][subchannel].object.method[method] = data;
1968   if (maddress == 0x17fc) {
1969      indexesleft_count = 0;
1970      indexesleft_first = 0;
1971      primitives_count = 0;
1972      countlen--;
1973   }
1974   if (maddress == 0x1810) {
1975      // draw vertices
1976      int offset, count, type;
1977      UINT32 n;
1978      render_delegate renderspans;
1979
1980      offset = data & 0xffffff;
1981      count = (data >> 24) & 0xff;
1982      type = channel[chanel][subchannel].object.method[0x17fc / 4];
1983      if (((channel[chanel][subchannel].object.method[0x1e60 / 4] & 7) > 0) && (combiner.used != 0)) {
1984         renderspans = render_delegate(FUNC(nv2a_renderer::render_register_combiners), this);
1985      }
1986      else if (texture[0].enabled) {
1987         renderspans = render_delegate(FUNC(nv2a_renderer::render_texture_simple), this);
1988      }
1989      else
1990         renderspans = render_delegate(FUNC(nv2a_renderer::render_color), this);
1991#ifdef LOG_NV2A
1992      printf("vertex %d %d %d\n\r", type, offset, count);
1993#endif
1994      if (type == nv2a_renderer::QUADS) {
1995         for (n = 0; n <= count; n += 4) {
1996            vertex_nv vert[4];
1997            vertex_t xy[4];
1998
1999            read_vertices_0x1810(space, vert, n + offset, 4);
2000            convert_vertices_poly(vert, xy, 4);
2001            render_polygon<4>(fb.cliprect(), renderspans, 4 + 4 * 2, xy); // 4 rgba, 4 texture units 2 uv
2002         }
2003         wait();
2004      }
2005      else if (type == nv2a_renderer::TRIANGLE_STRIP) {
2006         vertex_nv vert[4];
2007         vertex_t xy[4];
2008
2009         read_vertices_0x1810(space, vert, offset, 2);
2010         convert_vertices_poly(vert, xy, 2);
2011         count = count - 2;
2012         offset = offset + 2;
2013         for (n = 0; n <= count; n++) {
2014            read_vertices_0x1810(space, vert + ((n + 2) & 3), offset + n, 1);
2015            convert_vertices_poly(vert + ((n + 2) & 3), xy + ((n + 2) & 3), 1);
2016            render_triangle(fb.cliprect(), renderspans, 4 + 4 * 2, xy[((n & 1) + n) & 3], xy[((~n & 1) + n) & 3], xy[(2 + n) & 3]);
2017         }
2018         wait();
2019      }
2020      else {
2021         logerror("Unsupported primitive %d for method 0x1810\n", type);
2022      }
2023      countlen--;
2024   }
2025   if (maddress == 0x1800) {
2026      UINT32 type, n;
2027      render_delegate renderspans;
2028
2029      if (((channel[chanel][subchannel].object.method[0x1e60 / 4] & 7) > 0) && (combiner.used != 0)) {
2030         renderspans = render_delegate(FUNC(nv2a_renderer::render_register_combiners), this);
2031      }
2032      else if (texture[0].enabled) {
2033         renderspans = render_delegate(FUNC(nv2a_renderer::render_texture_simple), this);
2034      }
2035      else
2036         renderspans = render_delegate(FUNC(nv2a_renderer::render_color), this);
2037      // vertices are selected from the vertex buffer using an array of indexes
2038      // each dword after 1800 contains two 16 bit index values to select the vartices
2039      type = channel[chanel][subchannel].object.method[0x17fc / 4];
2040#ifdef LOG_NV2A
2041      printf("vertex %d %d %d\n\r", type, offset, count);
2042#endif
2043      if (type == nv2a_renderer::QUADS) {
2044         while (1) {
2045            vertex_nv vert[4];
2046            vertex_t xy[4];
2047            int c;
2048
2049            if ((countlen * 2 + indexesleft_count) < 4)
2050               break;
2051            c = read_vertices_0x1800(space, vert, address, 4);
2052            address = address + c * 4;
2053            countlen = countlen - c;
2054            convert_vertices_poly(vert, xy, 4);
2055            render_polygon<4>(fb.cliprect(), renderspans, 4 + 4 * 2, xy); // 4 rgba, 4 texture units 2 uv
2056         }
2057         while (countlen > 0) {
2058            data = space.read_dword(address);
2059            n = (indexesleft_first + indexesleft_count) & 7;
2060            indexesleft[n] = data & 0xffff;
2061            indexesleft[(n + 1) & 7] = (data >> 16) & 0xffff;
2062            indexesleft_count = indexesleft_count + 2;
2063            address += 4;
2064            countlen--;
2065         }
2066         wait();
2067      }
2068      else if (type == nv2a_renderer::TRIANGLES) {
2069         while (1) {
2070            vertex_nv vert[3];
2071            vertex_t xy[3];
2072            int c;
2073
2074            if ((countlen * 2 + indexesleft_count) < 3)
2075               break;
2076            c = read_vertices_0x1800(space, vert, address, 3);
2077            address = address + c * 4;
2078            countlen = countlen - c;
2079            convert_vertices_poly(vert, xy, 3);
2080            render_triangle(fb.cliprect(), renderspans, 4 + 4 * 2, xy[0], xy[1], xy[2]); // 4 rgba, 4 texture units 2 uv
2081         }
2082         while (countlen > 0) {
2083            data = space.read_dword(address);
2084            n = (indexesleft_first + indexesleft_count) & 7;
2085            indexesleft[n] = data & 0xffff;
2086            indexesleft[(n + 1) & 7] = (data >> 16) & 0xffff;
2087            indexesleft_count = indexesleft_count + 2;
2088            address += 4;
2089            countlen--;
2090         }
2091         wait();
2092      }
2093      else if (type == nv2a_renderer::TRIANGLE_STRIP) {
2094         if ((countlen * 2 + indexesleft_count) >= 3) {
2095            vertex_nv vert[4];
2096            vertex_t xy[4];
2097            int c, count;
2098
2099            c = read_vertices_0x1800(space, vert, address, 2);
2100            convert_vertices_poly(vert, xy, 2);
2101            address = address + c * 4;
2102            countlen = countlen - c;
2103            count = countlen * 2 + indexesleft_count;
2104            for (n = 0; n < count; n++) { // <=
2105               c = read_vertices_0x1800(space, vert + ((n + 2) & 3), address, 1);
2106               address = address + c * 4;
2107               countlen = countlen - c;
2108               convert_vertices_poly(vert + ((n + 2) & 3), xy + ((n + 2) & 3), 1);
2109               if (xy[(n + 2) & 3].y > 293800000.0)
2110                  xy[(n + 2) & 3].y = xy[(n + 2) & 3].y + 1.0;
2111               render_triangle(fb.cliprect(), renderspans, 4 + 4 * 2, xy[((n & 1) + n) & 3], xy[((~n & 1) + n) & 3], xy[(2 + n) & 3]);
2112            }
2113         }
2114         while (countlen > 0) {
2115            data = space.read_dword(address);
2116            n = (indexesleft_first + indexesleft_count) & 7;
2117            indexesleft[n] = data & 0xffff;
2118            indexesleft[(n + 1) & 7] = (data >> 16) & 0xffff;
2119            indexesleft_count = indexesleft_count + 2;
2120            address += 4;
2121            countlen--;
2122         }
2123         wait();
2124      }
2125      else {
2126         logerror("Unsupported primitive %d for method 0x1800\n", type);
2127         countlen = 0;
2128      }
2129   }
2130   if (maddress == 0x1818) {
2131      int n;
2132      int type;
2133      render_delegate renderspans;
2134
2135      if (((channel[chanel][subchannel].object.method[0x1e60 / 4] & 7) > 0) && (combiner.used != 0)) {
2136         renderspans = render_delegate(FUNC(nv2a_renderer::render_register_combiners), this);
2137      }
2138      else if (texture[0].enabled) {
2139         renderspans = render_delegate(FUNC(nv2a_renderer::render_texture_simple), this);
2140      }
2141      else
2142         renderspans = render_delegate(FUNC(nv2a_renderer::render_color), this);
2143      // vertices are taken from the next words, not from a vertex buffer
2144      // first send primitive type with 17fc
2145      // then countlen number of dwords with 1818
2146      // end with 17fc primitive type 0
2147      // at 1760 16 words specify the vertex format:for each possible vertex attribute the number of components (0=not present) and type of each
2148      type = channel[chanel][subchannel].object.method[0x17fc / 4];
2149      if (type == nv2a_renderer::TRIANGLE_FAN) {
2150         vertex_nv vert[3];
2151         vertex_t xy[3];
2152         int c;
2153
2154         c = read_vertices_0x1818(space, vert, address, 2);
2155         convert_vertices_poly(vert, xy, 2);
2156         countlen = countlen - c;
2157         if (countlen < 0) {
2158            logerror("Method 0x1818 missing %d words to draw a complete primitive\n", -countlen);
2159            countlen = 0;
2160            return;
2161         }
2162         address = address + c * 4;
2163         for (n = 1; countlen > 0; n++) {
2164            c = read_vertices_0x1818(space, vert + ((n & 1) + 1), address, 1);
2165            countlen = countlen - c;
2166            if (countlen < 0) {
2167               logerror("Method 0x1818 missing %d words to draw a complete primitive\n", -countlen);
2168               countlen = 0;
2169               break;
2170            }
2171            address = address + c * 4;
2172            convert_vertices_poly(vert + ((n & 1) + 1), xy + ((n & 1) + 1), 1);
2173            render_triangle(fb.cliprect(), renderspans, 4 + 4 * 2, xy[0], xy[(~n & 1) + 1], xy[(n & 1) + 1]);
2174         }
2175         wait();
2176      }
2177      else if (type == nv2a_renderer::TRIANGLE_STRIP) {
2178         vertex_nv vert[4];
2179         vertex_t xy[4];
2180         int c;
2181
2182         c = read_vertices_0x1818(space, vert, address, 2);
2183         convert_vertices_poly(vert, xy, 2);
2184         countlen = countlen - c;
2185         if (countlen < 0) {
2186            logerror("Method 0x1818 missing %d words to draw a complete primitive\n", -countlen);
2187            countlen = 0;
2188            return;
2189         }
2190         address = address + c * 4;
2191         for (n = 0; countlen > 0; n++) {
2192            c = read_vertices_0x1818(space, vert + ((n + 2) & 3), address, 1);
2193            convert_vertices_poly(vert + ((n + 2) & 3), xy + ((n + 2) & 3), 1);
2194            countlen = countlen - c;
2195            if (countlen < 0) {
2196               logerror("Method 0x1818 missing %d words to draw a complete primitive\n", -countlen);
2197               countlen = 0;
2198               break;
2199            }
2200            address = address + c * 4;
2201            render_triangle(fb.cliprect(), renderspans, 4 + 4 * 2, xy[((n & 1) + n) & 3], xy[((~n & 1) + n) & 3], xy[(2 + n) & 3]);
2202         }
2203         wait();
2204      }
2205      else if (type == nv2a_renderer::QUADS) {
2206         while (countlen > 0) {
2207            vertex_nv vert[4];
2208            vertex_t xy[4];
2209            int c;
2210
2211            c = read_vertices_0x1818(space, vert, address, 4);
2212            convert_vertices_poly(vert, xy, 4);
2213            countlen = countlen - c;
2214            if (countlen < 0) {
2215               logerror("Method 0x1818 missing %d words to draw a complete primitive\n", -countlen);
2216               countlen = 0;
2217               break;
2218            }
2219            address = address + c * 4;
2220            render_polygon<4>(fb.cliprect(), renderspans, 4 + 4 * 2, xy); // 4 rgba, 4 texture units 2 uv
2221         }
2222         wait();
2223      }
2224      else if (type == nv2a_renderer::QUAD_STRIP) {
2225         vertex_nv vert[4];
2226         vertex_t xy[4];
2227         int c;
2228
2229         c = read_vertices_0x1818(space, vert, address, 2);
2230         convert_vertices_poly(vert, xy, 2);
2231         countlen = countlen - c;
2232         if (countlen < 0) {
2233            logerror("Method 0x1818 missing %d words to draw a complete primitive\n", -countlen);
2234            countlen = 0;
2235            return;
2236         }
2237         address = address + c * 4;
2238         for (n = 0; countlen > 0; n += 2) {
2239            c = read_vertices_0x1818(space, vert + ((n + 2) & 3), address + ((n + 2) & 3), 2);
2240            convert_vertices_poly(vert + ((n + 2) & 3), xy + ((n + 2) & 3), 2);
2241            countlen = countlen - c;
2242            if (countlen < 0) {
2243               logerror("Method 0x1818 missing %d words to draw a complete primitive\n", -countlen);
2244               countlen = 0;
2245               return;
2246            }
2247            address = address + c * 4;
2248            render_triangle(fb.cliprect(), renderspans, 4 + 4 * 2, xy[n & 3], xy[(n + 1) & 3], xy[(n + 2) & 3]);
2249            render_triangle(fb.cliprect(), renderspans, 4 + 4 * 2, xy[(n + 2) & 3], xy[(n + 1) & 3], xy[(n + 3) & 3]);
2250         }
2251         wait();
2252      }
2253      else {
2254         logerror("Unsupported primitive %d for method 0x1818\n", type);
2255         countlen = 0;
2256      }
2257   }
2258   if ((maddress >= 0x1720) && (maddress < 0x1760)) {
2259      int bit = method - 0x1720 / 4;
2260
2261      if (data & 0x80000000)
2262         vertexbuffer_address[bit] = (data & 0x0fffffff) + dma_offset[1];
2263      else
2264         vertexbuffer_address[bit] = (data & 0x0fffffff) + dma_offset[0];
2265   }
2266   if ((maddress >= 0x1760) && (maddress < 0x17A0)) {
2267      int bit = method - 0x1760 / 4;
2268
2269      vertexbuffer_stride[bit] = (data >> 8) & 255;
2270      vertexbuffer_kind[bit] = data & 15;
2271      vertexbuffer_size[bit] = (data >> 4) & 15;
2272      switch (vertexbuffer_kind[bit]) {
2273      case NV2A_VTXBUF_TYPE_UNKNOWN_0:
2274         vertex_attribute_words[bit] = (vertexbuffer_size[bit] * 1) >> 2;
2275         break;
2276      case NV2A_VTXBUF_TYPE_FLOAT:
2277         vertex_attribute_words[bit] = (vertexbuffer_size[bit] * 4) >> 2;
2278         break;
2279      case NV2A_VTXBUF_TYPE_UBYTE:
2280         vertex_attribute_words[bit] = (vertexbuffer_size[bit] * 1) >> 2;
2281         break;
2282      case NV2A_VTXBUF_TYPE_USHORT:
2283         vertex_attribute_words[bit] = (vertexbuffer_size[bit] * 2) >> 2;
2284         break;
2285      case NV2A_VTXBUF_TYPE_UNKNOWN_6:
2286         vertex_attribute_words[bit] = (vertexbuffer_size[bit] * 4) >> 2;
2287         break;
2288      default:
2289         vertex_attribute_words[bit] = 0;
2290      }
2291      if (vertexbuffer_size[bit] > 0)
2292         enabled_vertex_attributes |= (1 << bit);
2293      else
2294         enabled_vertex_attributes &= ~(1 << bit);
2295      for (int n = bit + 1; n < 16; n++) {
2296         if ((enabled_vertex_attributes & (1 << (n - 1))) != 0)
2297            vertex_attribute_offset[n] = vertex_attribute_offset[n - 1] + vertex_attribute_words[n - 1];
2298         else
2299            vertex_attribute_offset[n] = vertex_attribute_offset[n - 1];
2300      }
2301      countlen--;
2302   }
2303   if ((maddress == 0x1d6c) || (maddress == 0x1d70) || (maddress == 0x1a4))
2304      countlen--;
2305   if (maddress == 0x019c) {
2306      geforce_read_dma_object(data, dma_offset[0], dma_size[0]);
2307   }
2308   if (maddress == 0x01a0) {
2309      geforce_read_dma_object(data, dma_offset[1], dma_size[1]);
2310   }
2311   if (maddress == 0x1d70) {
2312      // with 1d70 write the value at offest [1d6c] inside dma object [1a4]
2313      UINT32 offset, base;
2314      UINT32 dmahand, dmaoff, smasiz;
2315
2316      offset = channel[chanel][subchannel].object.method[0x1d6c / 4];
2317      dmahand = channel[chanel][subchannel].object.method[0x1a4 / 4];
2318      geforce_read_dma_object(dmahand, dmaoff, smasiz);
2319      base = dmaoff;
2320      space.write_dword(base + offset, data);
2321      countlen--;
2322   }
2323   if (maddress == 0x1d94) {
2324      // possible buffers: color, depth, stencil, and accumulation
2325      // clear framebuffer
2326      if (data & 0xf0) {
2327         // clear colors
2328         UINT32 color = channel[chanel][subchannel].object.method[0x1d90 / 4];
2329         fb.fill(color);
2330         //printf("clearscreen\n\r");
2331      }
2332      if (data & 0x03) {
2333         // clear stencil+zbuffer
2334      }
2335      countlen--;
2336   }
2337   if (maddress == 0x0210) {
2338      // framebuffer offset ?
2339      countlen--;
2340   }
2341   if (maddress == 0x0214) {
2342      // zbuffer offset ?
2343      countlen--;
2344   }
2345   if (maddress == 0x0300) {
2346      alpha_test_enabled = data != 0;
2347   }
2348   if (maddress == 0x033c) {
2349      alpha_func = data;
2350   }
2351   if (maddress == 0x0340) {
2352      alpha_reference = data;
2353   }
2354   if (maddress == 0x0304) {
2355      if (logical_operation_enabled)
2356         blending_enabled = false;
2357      else
2358         blending_enabled = data != 0;
2359   }
2360   if (maddress == 0x0344) {
2361      blend_function_source = data;
2362   }
2363   if (maddress == 0x0348) {
2364      blend_function_destination = data;
2365   }
2366   if (maddress == 0x034c) {
2367      blend_color = data;
2368   }
2369   if (maddress == 0x0350) {
2370      blend_equation = data;
2371   }
2372   if (maddress == 0x0d40) {
2373      if (data != 0)
2374         blending_enabled = false;
2375      else
2376         blending_enabled = channel[chanel][subchannel].object.method[0x0304 / 4] != 0;
2377      logical_operation_enabled = data != 0;
2378   }
2379   if (maddress == 0x0d44) {
2380      logical_operation = data;
2381   }
2382   // Texture Units
2383   if ((maddress >= 0x1b00) && (maddress < 0x1c00)) {
2384      int unit;//,off;
2385
2386      unit = (maddress >> 6) & 3;
2387      //off=maddress & 0xc0;
2388      maddress = maddress & ~0xc0;
2389      if (maddress == 0x1b00) {
2390         UINT32 offset;//,base;
2391         //UINT32 dmahand,dmaoff,dmasiz;
2392
2393         offset = data;
2394         texture[unit].buffer = space.get_read_ptr(offset);
2395         /*if (dma0 != 0) {
2396         dmahand=channel[channel][subchannel].object.method[0x184/4];
2397         geforce_read_dma_object(dmahand,dmaoff,smasiz);
2398         } else if (dma1 != 0) {
2399         dmahand=channel[channel][subchannel].object.method[0x188/4];
2400         geforce_read_dma_object(dmahand,dmaoff,smasiz);
2401         }*/
2402      }
2403      if (maddress == 0x1b04) {
2404         //int dma0,dma1,cubic,noborder,dims,mipmap;
2405         int basesizeu, basesizev, basesizew, format;
2406
2407         //dma0=(data >> 0) & 1;
2408         //dma1=(data >> 1) & 1;
2409         //cubic=(data >> 2) & 1;
2410         //noborder=(data >> 3) & 1;
2411         //dims=(data >> 4) & 15;
2412         //mipmap=(data >> 19) & 1;
2413         format = (data >> 8) & 255;
2414         basesizeu = (data >> 20) & 15;
2415         basesizev = (data >> 24) & 15;
2416         basesizew = (data >> 28) & 15;
2417         texture[unit].sizeu = 1 << basesizeu;
2418         texture[unit].sizev = 1 << basesizev;
2419         texture[unit].sizew = 1 << basesizew;
2420         texture[unit].dilate = dilatechose[(basesizeu << 4) + basesizev];
2421         texture[unit].format = format;
2422         if (debug_grab_texttype == format) {
2423            FILE *f;
2424            int written;
2425
2426            debug_grab_texttype = -1;
2427            f = fopen(debug_grab_textfile, "wb");
2428            if (f) {
2429               written = (int)fwrite(texture[unit].buffer, texture[unit].sizeu*texture[unit].sizev * 4, 1, f);
2430               fclose(f);
2431               logerror("Written %d bytes of texture to specified file\n", written);
2432            }
2433            else
2434               logerror("Unable to save texture to specified file\n");
2435         }
2436      }
2437      if (maddress == 0x1b0c) {
2438         // enable texture
2439         int enable;
2440
2441         enable = (data >> 30) & 1;
2442         texture[unit].enabled = enable;
2443      }
2444      if (maddress == 0x1b10) {
2445         texture[unit].rectangle_pitch = data >> 16;
2446      }
2447      countlen--;
2448   }
2449   // modelview matrix
2450   if ((maddress >= 0x0480) && (maddress < 0x04c0)) {
2451      maddress = (maddress - 0x0480) / 4;
2452      *(UINT32 *)(&matrix.modelview[maddress]) = data;
2453      countlen--;
2454   }
2455   // inverse modelview matrix
2456   if ((maddress >= 0x0580) && (maddress < 0x05c0)) {
2457      maddress = (maddress - 0x0580) / 4;
2458      *(UINT32 *)(&matrix.modelview_inverse[maddress]) = data;
2459      countlen--;
2460   }
2461   // projection matrix
2462   if ((maddress >= 0x0680) && (maddress < 0x06c0)) {
2463      maddress = (maddress - 0x0680) / 4;
2464      *(UINT32 *)(&matrix.projection[maddress]) = data;
2465      countlen--;
2466   }
2467   // viewport translate
2468   if ((maddress >= 0x0a20) && (maddress < 0x0a30)) {
2469      maddress = (maddress - 0x0a20) / 4;
2470      *(UINT32 *)(&matrix.translate[maddress]) = data;
2471      // set corresponding vertex shader constant too
2472      vertexprogram.exec.c_constant[59].iv[maddress] = data; // constant -37
2473      countlen--;
2474   }
2475   // viewport scale
2476   if ((maddress >= 0x0af0) && (maddress < 0x0b00)) {
2477      maddress = (maddress - 0x0af0) / 4;
2478      *(UINT32 *)(&matrix.scale[maddress]) = data;
2479      // set corresponding vertex shader constant too
2480      vertexprogram.exec.c_constant[58].iv[maddress] = data; // constant -38
2481      countlen--;
2482   }
2483   // Vertex program (shader)
2484   if (maddress == 0x1e94) {
2485      /*if (data == 2)
2486      logerror("Enabled vertex program\n");
2487      else if (data == 4)
2488      logerror("Enabled fixed function pipeline\n");
2489      else if (data == 6)
2490      logerror("Enabled both fixed function pipeline and vertex program ?\n");
2491      else
2492      logerror("Unknown value %d to method 0x1e94\n",data);*/
2493      vertex_pipeline = data & 6;
2494      countlen--;
2495   }
2496   if (maddress == 0x1e9c) {
2497      //logerror("VP_UPLOAD_FROM_ID %d\n",data);
2498      vertexprogram.upload_instruction_index = data;
2499      vertexprogram.upload_instruction_component = 0;
2500      countlen--;
2501   }
2502   if (maddress == 0x1ea0) {
2503      //logerror("VP_START_FROM_ID %d\n",data);
2504      vertexprogram.instructions = vertexprogram.upload_instruction_index;
2505      vertexprogram.start_instruction = data;
2506      countlen--;
2507   }
2508   if (maddress == 0x1ea4) {
2509      //logerror("VP_UPLOAD_CONST_ID %d\n",data);
2510      vertexprogram.upload_parameter_index = data;
2511      vertexprogram.upload_parameter_component = 0;
2512      countlen--;
2513   }
2514   if ((maddress >= 0x0b00) && (maddress < 0x0b80)) {
2515      //logerror("VP_UPLOAD_INST\n");
2516      if (vertexprogram.upload_instruction_index < 192) {
2517         vertexprogram.exec.op[vertexprogram.upload_instruction_index].i[vertexprogram.upload_instruction_component] = data;
2518         vertexprogram.exec.op[vertexprogram.upload_instruction_index].modified |= (1 << vertexprogram.upload_instruction_component);
2519      }
2520      else
2521         logerror("Need to increase size of vertexprogram.instruction to %d\n\r", vertexprogram.upload_instruction_index);
2522      if (vertexprogram.exec.op[vertexprogram.upload_instruction_index].modified == 15) {
2523         vertexprogram.exec.op[vertexprogram.upload_instruction_index].modified = 0;
2524         vertexprogram.exec.decode_instruction(vertexprogram.upload_instruction_index);
2525      }
2526      vertexprogram.upload_instruction_component++;
2527      if (vertexprogram.upload_instruction_component >= 4) {
2528         vertexprogram.upload_instruction_component = 0;
2529         vertexprogram.upload_instruction_index++;
2530      }
2531   }
2532   if ((maddress >= 0x0b80) && (maddress < 0x0c00)) {
2533      //logerror("VP_UPLOAD_CONST\n");
2534      if (vertexprogram.upload_parameter_index < 256)
2535         vertexprogram.exec.c_constant[vertexprogram.upload_parameter_index].iv[vertexprogram.upload_parameter_component] = data;
2536      else
2537         logerror("Need to increase size of vertexprogram.parameter to %d\n\r", vertexprogram.upload_parameter_index);
2538      vertexprogram.upload_parameter_component++;
2539      if (vertexprogram.upload_parameter_component >= 4) {
2540         vertexprogram.upload_parameter_component = 0;
2541         vertexprogram.upload_parameter_index++;
2542      }
2543   }
2544   // Register combiners
2545   if (maddress == 0x1e60) {
2546      combiner.stages = data & 15;
2547      countlen--;
2548   }
2549   if (maddress == 0x0288) {
2550      combiner.final.mapin_rgbD_input = data & 15;
2551      combiner.final.mapin_rgbD_component = (data >> 4) & 1;
2552      combiner.final.mapin_rgbD_mapping = (data >> 5) & 7;
2553      combiner.final.mapin_rgbC_input = (data >> 8) & 15;
2554      combiner.final.mapin_rgbC_component = (data >> 12) & 1;
2555      combiner.final.mapin_rgbC_mapping = (data >> 13) & 7;
2556      combiner.final.mapin_rgbB_input = (data >> 16) & 15;
2557      combiner.final.mapin_rgbB_component = (data >> 20) & 1;
2558      combiner.final.mapin_rgbB_mapping = (data >> 21) & 7;
2559      combiner.final.mapin_rgbA_input = (data >> 24) & 15;
2560      combiner.final.mapin_rgbA_component = (data >> 28) & 1;
2561      combiner.final.mapin_rgbA_mapping = (data >> 29) & 7;
2562      countlen--;
2563   }
2564   if (maddress == 0x028c) {
2565      combiner.final.color_sum_clamp = (data >> 7) & 1;
2566      combiner.final.mapin_aG_input = (data >> 8) & 15;
2567      combiner.final.mapin_aG_component = (data >> 12) & 1;
2568      combiner.final.mapin_aG_mapping = (data >> 13) & 7;
2569      combiner.final.mapin_rgbF_input = (data >> 16) & 15;
2570      combiner.final.mapin_rgbF_component = (data >> 20) & 1;
2571      combiner.final.mapin_rgbF_mapping = (data >> 21) & 7;
2572      combiner.final.mapin_rgbE_input = (data >> 24) & 15;
2573      combiner.final.mapin_rgbE_component = (data >> 28) & 1;
2574      combiner.final.mapin_rgbE_mapping = (data >> 29) & 7;
2575      countlen--;
2576   }
2577   if (maddress == 0x1e20) {
2578      combiner_argb8_float(data, combiner.final.register_constantcolor0);
2579      countlen--;
2580   }
2581   if (maddress == 0x1e24) {
2582      combiner_argb8_float(data, combiner.final.register_constantcolor1);
2583      countlen--;
2584   }
2585   if ((maddress >= 0x0260) && (maddress < 0x0280)) {
2586      int n;
2587
2588      n = (maddress - 0x0260) >> 2;
2589      combiner.stage[n].mapin_aD_input = data & 15;
2590      combiner.stage[n].mapin_aD_component = (data >> 4) & 1;
2591      combiner.stage[n].mapin_aD_mapping = (data >> 5) & 7;
2592      combiner.stage[n].mapin_aC_input = (data >> 8) & 15;
2593      combiner.stage[n].mapin_aC_component = (data >> 12) & 1;
2594      combiner.stage[n].mapin_aC_mapping = (data >> 13) & 7;
2595      combiner.stage[n].mapin_aB_input = (data >> 16) & 15;
2596      combiner.stage[n].mapin_aB_component = (data >> 20) & 1;
2597      combiner.stage[n].mapin_aB_mapping = (data >> 21) & 7;
2598      combiner.stage[n].mapin_aA_input = (data >> 24) & 15;
2599      combiner.stage[n].mapin_aA_component = (data >> 28) & 1;
2600      combiner.stage[n].mapin_aA_mapping = (data >> 29) & 7;
2601      countlen--;
2602   }
2603   if ((maddress >= 0x0ac0) && (maddress < 0x0ae0)) {
2604      int n;
2605
2606      n = (maddress - 0x0ac0) >> 2;
2607      combiner.stage[n].mapin_rgbD_input = data & 15;
2608      combiner.stage[n].mapin_rgbD_component = (data >> 4) & 1;
2609      combiner.stage[n].mapin_rgbD_mapping = (data >> 5) & 7;
2610      combiner.stage[n].mapin_rgbC_input = (data >> 8) & 15;
2611      combiner.stage[n].mapin_rgbC_component = (data >> 12) & 1;
2612      combiner.stage[n].mapin_rgbC_mapping = (data >> 13) & 7;
2613      combiner.stage[n].mapin_rgbB_input = (data >> 16) & 15;
2614      combiner.stage[n].mapin_rgbB_component = (data >> 20) & 1;
2615      combiner.stage[n].mapin_rgbB_mapping = (data >> 21) & 7;
2616      combiner.stage[n].mapin_rgbA_input = (data >> 24) & 15;
2617      combiner.stage[n].mapin_rgbA_component = (data >> 28) & 1;
2618      combiner.stage[n].mapin_rgbA_mapping = (data >> 29) & 7;
2619      countlen--;
2620   }
2621   if ((maddress >= 0x0a60) && (maddress < 0x0a80)) {
2622      int n;
2623
2624      n = (maddress - 0x0a60) >> 2;
2625      combiner_argb8_float(data, combiner.stage[n].register_constantcolor0);
2626      countlen--;
2627   }
2628   if ((maddress >= 0x0a80) && (maddress < 0x0aa0)) {
2629      int n;
2630
2631      n = (maddress - 0x0a80) >> 2;
2632      combiner_argb8_float(data, combiner.stage[n].register_constantcolor1);
2633      countlen--;
2634   }
2635   if ((maddress >= 0x0aa0) && (maddress < 0x0ac0)) {
2636      int n;
2637
2638      n = (maddress - 0x0aa0) >> 2;
2639      combiner.stage[n].mapout_aCD_output = data & 15;
2640      combiner.stage[n].mapout_aAB_output = (data >> 4) & 15;
2641      combiner.stage[n].mapout_aSUM_output = (data >> 8) & 15;
2642      combiner.stage[n].mapout_aCD_dotproduct = (data >> 12) & 1;
2643      combiner.stage[n].mapout_aAB_dotproduct = (data >> 13) & 1;
2644      combiner.stage[n].mapout_a_muxsum = (data >> 14) & 1;
2645      combiner.stage[n].mapout_a_bias = (data >> 15) & 1;
2646      combiner.stage[n].mapout_a_scale = (data >> 16) & 3;
2647      //combiner.=(data >> 27) & 7;
2648      countlen--;
2649   }
2650   if ((maddress >= 0x1e40) && (maddress < 0x1e60)) {
2651      int n;
2652
2653      n = (maddress - 0x1e40) >> 2;
2654      combiner.stage[n].mapout_rgbCD_output = data & 15;
2655      combiner.stage[n].mapout_rgbAB_output = (data >> 4) & 15;
2656      combiner.stage[n].mapout_rgbSUM_output = (data >> 8) & 15;
2657      combiner.stage[n].mapout_rgbCD_dotproduct = (data >> 12) & 1;
2658      combiner.stage[n].mapout_rgbAB_dotproduct = (data >> 13) & 1;
2659      combiner.stage[n].mapout_rgb_muxsum = (data >> 14) & 1;
2660      combiner.stage[n].mapout_rgb_bias = (data >> 15) & 1;
2661      combiner.stage[n].mapout_rgb_scale = (data >> 16) & 3;
2662      //combiner.=(data >> 27) & 7;
2663      countlen--;
2664   }
2665}
2666
2667int nv2a_renderer::toggle_register_combiners_usage()
2668{
2669   combiner.used = 1 - combiner.used;
2670   return combiner.used;
2671}
2672
2673void nv2a_renderer::debug_grab_texture(int type, const char *filename)
2674{
2675   debug_grab_texttype = type;
2676   if (debug_grab_textfile == NULL)
2677      debug_grab_textfile = (char *)malloc(128);
2678   strncpy(debug_grab_textfile, filename, 127);
2679}
2680
2681void nv2a_renderer::debug_grab_vertex_program_slot(int slot, UINT32 *instruction)
2682{
2683   if (slot >= 1024 / 4)
2684      return;
2685   instruction[0] = vertexprogram.exec.op[slot].i[0];
2686   instruction[1] = vertexprogram.exec.op[slot].i[1];
2687   instruction[2] = vertexprogram.exec.op[slot].i[2];
2688   instruction[3] = vertexprogram.exec.op[slot].i[3];
2689}
2690
2691void nv2a_renderer::savestate_items()
2692{
2693}
2694
2695void nv2a_renderer::combiner_argb8_float(UINT32 color, float reg[4])
2696{
2697   reg[0] = (float)(color & 0xff) / 255.0;
2698   reg[1] = (float)((color >> 8) & 0xff) / 255.0;
2699   reg[2] = (float)((color >> 16) & 0xff) / 255.0;
2700   reg[3] = (float)((color >> 24) & 0xff) / 255.0;
2701}
2702
2703UINT32 nv2a_renderer::combiner_float_argb8(float reg[4])
2704{
2705   UINT32 r, g, b, a;
2706
2707   a = reg[3] * 255.0;
2708   b = reg[2] * 255.0;
2709   g = reg[1] * 255.0;
2710   r = reg[0] * 255.0;
2711   return (a << 24) | (r << 16) | (g << 8) | b;
2712}
2713
2714float nv2a_renderer::combiner_map_input_select(int code, int index)
2715{
2716   switch (code) {
2717   case 0:
2718   default:
2719      return combiner.register_zero[index];
2720   case 1:
2721      return combiner.register_color0[index];
2722   case 2:
2723      return combiner.register_color1[index];
2724   case 3:
2725      return combiner.register_fogcolor[index];
2726   case 4:
2727      return combiner.register_primarycolor[index];
2728   case 5:
2729      return combiner.register_secondarycolor[index];
2730   case 8:
2731      return combiner.register_texture0color[index];
2732   case 9:
2733      return combiner.register_texture1color[index];
2734   case 10:
2735      return combiner.register_texture2color[index];
2736   case 11:
2737      return combiner.register_texture3color[index];
2738   case 12:
2739      return combiner.register_spare0[index];
2740   case 13:
2741      return combiner.register_spare1[index];
2742   case 14:
2743      return combiner.variable_sumclamp[index];
2744   case 15:
2745      return combiner.variable_EF[index];
2746   }
2747
2748   // never executed
2749   //return 0;
2750}
2751
2752float *nv2a_renderer::combiner_map_input_select3(int code)
2753{
2754   switch (code) {
2755   case 0:
2756   default:
2757      return combiner.register_zero;
2758   case 1:
2759      return combiner.register_color0;
2760   case 2:
2761      return combiner.register_color1;
2762   case 3:
2763      return combiner.register_fogcolor;
2764   case 4:
2765      return combiner.register_primarycolor;
2766   case 5:
2767      return combiner.register_secondarycolor;
2768   case 8:
2769      return combiner.register_texture0color;
2770   case 9:
2771      return combiner.register_texture1color;
2772   case 10:
2773      return combiner.register_texture2color;
2774   case 11:
2775      return combiner.register_texture3color;
2776   case 12:
2777      return combiner.register_spare0;
2778   case 13:
2779      return combiner.register_spare1;
2780   case 14:
2781      return combiner.variable_sumclamp;
2782   case 15:
2783      return combiner.variable_EF;
2784   }
2785
2786   // never executed
2787   //return 0;
2788}
2789
2790float *nv2a_renderer::combiner_map_output_select3(int code)
2791{
2792   switch (code) {
2793   case 0:
2794      return 0;
2795   case 1:
2796      return 0;
2797   case 2:
2798      return 0;
2799   case 3:
2800      return 0;
2801   case 4:
2802      return combiner.register_primarycolor;
2803   case 5:
2804      return combiner.register_secondarycolor;
2805   case 8:
2806      return combiner.register_texture0color;
2807   case 9:
2808      return combiner.register_texture1color;
2809   case 10:
2810      return combiner.register_texture2color;
2811   case 11:
2812      return combiner.register_texture3color;
2813   case 12:
2814      return combiner.register_spare0;
2815   case 13:
2816      return combiner.register_spare1;
2817   case 14:
2818      return 0;
2819   case 15:
2820   default:
2821      return 0;
2822   }
2823}
2824
2825float nv2a_renderer::combiner_map_input_function(int code, float value)
2826{
2827   float t;
2828
2829   switch (code) {
2830   case 0:
2831      return MAX(0.0, value);
2832   case 1:
2833      t = MAX(value, 0.0);
2834      return 1.0 - MIN(t, 1.0);
2835   case 2:
2836      return 2.0 * MAX(0.0, value) - 1.0;
2837   case 3:
2838      return -2.0 * MAX(0.0, value) + 1.0;
2839   case 4:
2840      return MAX(0.0, value) - 0.5;
2841   case 5:
2842      return -MAX(0.0, value) + 0.5;
2843   case 6:
2844      return value;
2845   case 7:
2846   default:
2847      return -value;
2848   }
2849
2850   // never executed
2851   //return 0;
2852}
2853
2854void nv2a_renderer::combiner_map_input_function3(int code, float *data)
2855{
2856   float t;
2857
2858   switch (code) {
2859   case 0:
2860      data[0] = MAX(0.0, data[0]);
2861      data[1] = MAX(0.0, data[1]);
2862      data[2] = MAX(0.0, data[2]);
2863      break;
2864   case 1:
2865      t = MAX(data[0], 0.0);
2866      data[0] = 1.0 - MIN(t, 1.0);
2867      t = MAX(data[1], 0.0);
2868      data[1] = 1.0 - MIN(t, 1.0);
2869      t = MAX(data[2], 0.0);
2870      data[2] = 1.0 - MIN(t, 1.0);
2871      break;
2872   case 2:
2873      data[0] = 2.0 * MAX(0.0, data[0]) - 1.0;
2874      data[1] = 2.0 * MAX(0.0, data[1]) - 1.0;
2875      data[2] = 2.0 * MAX(0.0, data[2]) - 1.0;
2876      break;
2877   case 3:
2878      data[0] = -2.0 * MAX(0.0, data[0]) + 1.0;
2879      data[1] = -2.0 * MAX(0.0, data[1]) + 1.0;
2880      data[2] = -2.0 * MAX(0.0, data[2]) + 1.0;
2881      break;
2882   case 4:
2883      data[0] = MAX(0.0, data[0]) - 0.5;
2884      data[1] = MAX(0.0, data[1]) - 0.5;
2885      data[2] = MAX(0.0, data[2]) - 0.5;
2886      break;
2887   case 5:
2888      data[0] = -MAX(0.0, data[0]) + 0.5;
2889      data[1] = -MAX(0.0, data[1]) + 0.5;
2890      data[2] = -MAX(0.0, data[2]) + 0.5;
2891      break;
2892   case 6:
2893      return;
2894   case 7:
2895   default:
2896      data[0] = -data[0];
2897      data[1] = -data[1];
2898      data[2] = -data[2];
2899      break;
2900   }
2901}
2902
2903void nv2a_renderer::combiner_initialize_registers(UINT32 argb8[6])
2904{
2905   combiner_argb8_float(argb8[0], combiner.register_primarycolor);
2906   combiner_argb8_float(argb8[1], combiner.register_secondarycolor);
2907   combiner_argb8_float(argb8[2], combiner.register_texture0color);
2908   combiner_argb8_float(argb8[3], combiner.register_texture1color);
2909   combiner_argb8_float(argb8[4], combiner.register_texture2color);
2910   combiner_argb8_float(argb8[5], combiner.register_texture3color);
2911   combiner.register_spare0[3] = combiner.register_texture0color[3];
2912   combiner.register_zero[0] = combiner.register_zero[1] = combiner.register_zero[2] = combiner.register_zero[3] = 0;
2913}
2914
2915void nv2a_renderer::combiner_initialize_stage(int stage_number)
2916{
2917   int n = stage_number;
2918
2919   // put register_constantcolor0 in register_color0
2920   combiner.register_color0[0] = combiner.stage[n].register_constantcolor0[0];
2921   combiner.register_color0[1] = combiner.stage[n].register_constantcolor0[1];
2922   combiner.register_color0[2] = combiner.stage[n].register_constantcolor0[2];
2923   combiner.register_color0[3] = combiner.stage[n].register_constantcolor0[3];
2924   // put register_constantcolor1 in register_color1
2925   combiner.register_color1[0] = combiner.stage[n].register_constantcolor1[0];
2926   combiner.register_color1[1] = combiner.stage[n].register_constantcolor1[1];
2927   combiner.register_color1[2] = combiner.stage[n].register_constantcolor1[2];
2928   combiner.register_color1[3] = combiner.stage[n].register_constantcolor1[3];
2929}
2930
2931void nv2a_renderer::combiner_initialize_final()
2932{
2933   // put register_constantcolor0 in register_color0
2934   combiner.register_color0[0] = combiner.final.register_constantcolor0[0];
2935   combiner.register_color0[1] = combiner.final.register_constantcolor0[1];
2936   combiner.register_color0[2] = combiner.final.register_constantcolor0[2];
2937   combiner.register_color0[3] = combiner.final.register_constantcolor0[3];
2938   // put register_constantcolor1 in register_color1
2939   combiner.register_color1[0] = combiner.final.register_constantcolor1[0];
2940   combiner.register_color1[1] = combiner.final.register_constantcolor1[1];
2941   combiner.register_color1[2] = combiner.final.register_constantcolor1[2];
2942   combiner.register_color1[3] = combiner.final.register_constantcolor1[3];
2943}
2944
2945void nv2a_renderer::combiner_map_input(int stage_number)
2946{
2947   int n = stage_number;
2948   int c, d, i;
2949   float v, *pv;
2950
2951   // A
2952   v = combiner_map_input_select(combiner.stage[n].mapin_aA_input, 2 + combiner.stage[n].mapin_aA_component);
2953   combiner.variable_A[3] = combiner_map_input_function(combiner.stage[n].mapin_aA_mapping, v);
2954   // B
2955   v = combiner_map_input_select(combiner.stage[n].mapin_aB_input, 2 + combiner.stage[n].mapin_aB_component);
2956   combiner.variable_B[3] = combiner_map_input_function(combiner.stage[n].mapin_aB_mapping, v);
2957   // C
2958   v = combiner_map_input_select(combiner.stage[n].mapin_aC_input, 2 + combiner.stage[n].mapin_aC_component);
2959   combiner.variable_C[3] = combiner_map_input_function(combiner.stage[n].mapin_aC_mapping, v);
2960   // D
2961   v = combiner_map_input_select(combiner.stage[n].mapin_aD_input, 2 + combiner.stage[n].mapin_aD_component);
2962   combiner.variable_D[3] = combiner_map_input_function(combiner.stage[n].mapin_aD_mapping, v);
2963
2964   // A
2965   pv = combiner_map_input_select3(combiner.stage[n].mapin_rgbA_input);
2966   c = combiner.stage[n].mapin_rgbA_component * 3;
2967   i = ~combiner.stage[n].mapin_rgbA_component & 1;
2968   for (d = 0; d < 3; d++) {
2969      combiner.variable_A[d] = pv[c];
2970      c = c + i;
2971   }
2972   combiner_map_input_function3(combiner.stage[n].mapin_rgbA_mapping, combiner.variable_A);
2973   // B
2974   pv = combiner_map_input_select3(combiner.stage[n].mapin_rgbB_input);
2975   c = combiner.stage[n].mapin_rgbB_component * 3;
2976   i = ~combiner.stage[n].mapin_rgbB_component & 1;
2977   for (d = 0; d < 3; d++) {
2978      combiner.variable_B[d] = pv[c];
2979      c = c + i;
2980   }
2981   combiner_map_input_function3(combiner.stage[n].mapin_rgbB_mapping, combiner.variable_B);
2982   // C
2983   pv = combiner_map_input_select3(combiner.stage[n].mapin_rgbC_input);
2984   c = combiner.stage[n].mapin_rgbC_component * 3;
2985   i = ~combiner.stage[n].mapin_rgbC_component & 1;
2986   for (d = 0; d < 3; d++) {
2987      combiner.variable_C[d] = pv[c];
2988      c = c + i;
2989   }
2990   combiner_map_input_function3(combiner.stage[n].mapin_rgbC_mapping, combiner.variable_C);
2991   // D
2992   pv = combiner_map_input_select3(combiner.stage[n].mapin_rgbD_input);
2993   c = combiner.stage[n].mapin_rgbD_component * 3;
2994   i = ~combiner.stage[n].mapin_rgbD_component & 1;
2995   for (d = 0; d < 3; d++) {
2996      combiner.variable_D[d] = pv[c];
2997      c = c + i;
2998   }
2999   combiner_map_input_function3(combiner.stage[n].mapin_rgbD_mapping, combiner.variable_D);
3000}
3001
3002void nv2a_renderer::combiner_map_output(int stage_number)
3003{
3004   int n = stage_number;
3005   float *f;
3006
3007   // rgb
3008   f = combiner_map_output_select3(combiner.stage[n].mapout_rgbAB_output);
3009   if (f) {
3010      f[0] = combiner.function_RGBop1[0];
3011      f[1] = combiner.function_RGBop1[1];
3012      f[2] = combiner.function_RGBop1[2];
3013   }
3014   f = combiner_map_output_select3(combiner.stage[n].mapout_rgbCD_output);
3015   if (f) {
3016      f[0] = combiner.function_RGBop2[0];
3017      f[1] = combiner.function_RGBop2[1];
3018      f[2] = combiner.function_RGBop2[2];
3019   }
3020   if ((combiner.stage[n].mapout_rgbAB_dotproduct | combiner.stage[n].mapout_rgbCD_dotproduct) == 0) {
3021      f = combiner_map_output_select3(combiner.stage[n].mapout_rgbSUM_output);
3022      if (f) {
3023         f[0] = combiner.function_RGBop3[0];
3024         f[1] = combiner.function_RGBop3[1];
3025         f[2] = combiner.function_RGBop3[2];
3026      }
3027   }
3028   // a
3029   f = combiner_map_output_select3(combiner.stage[n].mapout_aAB_output);
3030   if (f)
3031      f[3] = combiner.function_Aop1;
3032   f = combiner_map_output_select3(combiner.stage[n].mapout_aCD_output);
3033   if (f)
3034      f[3] = combiner.function_Aop2;
3035   f = combiner_map_output_select3(combiner.stage[n].mapout_aSUM_output);
3036   if (f)
3037      f[3] = combiner.function_Aop3;
3038}
3039
3040void nv2a_renderer::combiner_map_final_input()
3041{
3042   int i, c, d;
3043   float *pv;
3044
3045   // E
3046   pv = combiner_map_input_select3(combiner.final.mapin_rgbE_input);
3047   c = combiner.final.mapin_rgbE_component * 3;
3048   i = ~combiner.final.mapin_rgbE_component & 1;
3049   for (d = 0; d < 3; d++) {
3050      combiner.variable_E[d] = pv[c];
3051      c = c + i;
3052   }
3053   combiner_map_input_function3(combiner.final.mapin_rgbE_mapping, combiner.variable_E);
3054   // F
3055   pv = combiner_map_input_select3(combiner.final.mapin_rgbF_input);
3056   c = combiner.final.mapin_rgbF_component * 3;
3057   i = ~combiner.final.mapin_rgbF_component & 1;
3058   for (d = 0; d < 3; d++) {
3059      combiner.variable_F[d] = pv[c];
3060      c = c + i;
3061   }
3062   combiner_map_input_function3(combiner.final.mapin_rgbF_mapping, combiner.variable_F);
3063   // EF
3064   combiner.variable_EF[0] = combiner.variable_E[0] * combiner.variable_F[0];
3065   combiner.variable_EF[1] = combiner.variable_E[1] * combiner.variable_F[1];
3066   combiner.variable_EF[2] = combiner.variable_E[2] * combiner.variable_F[2];
3067   // sumclamp
3068   combiner.variable_sumclamp[0] = MAX(0, combiner.register_spare0[0]) + MAX(0, combiner.register_secondarycolor[0]);
3069   combiner.variable_sumclamp[1] = MAX(0, combiner.register_spare0[1]) + MAX(0, combiner.register_secondarycolor[1]);
3070   combiner.variable_sumclamp[2] = MAX(0, combiner.register_spare0[2]) + MAX(0, combiner.register_secondarycolor[2]);
3071   if (combiner.final.color_sum_clamp != 0) {
3072      combiner.variable_sumclamp[0] = MIN(combiner.variable_sumclamp[0], 1.0);
3073      combiner.variable_sumclamp[1] = MIN(combiner.variable_sumclamp[1], 1.0);
3074      combiner.variable_sumclamp[2] = MIN(combiner.variable_sumclamp[2], 1.0);
3075   }
3076   // A
3077   pv = combiner_map_input_select3(combiner.final.mapin_rgbA_input);
3078   c = combiner.final.mapin_rgbA_component * 3;
3079   i = ~combiner.final.mapin_rgbA_component & 1;
3080   for (d = 0; d < 3; d++) {
3081      combiner.variable_A[d] = pv[c];
3082      c = c + i;
3083   }
3084   combiner_map_input_function3(combiner.final.mapin_rgbA_mapping, combiner.variable_A);
3085   // B
3086   pv = combiner_map_input_select3(combiner.final.mapin_rgbB_input);
3087   c = combiner.final.mapin_rgbB_component * 3;
3088   i = ~combiner.final.mapin_rgbB_component & 1;
3089   for (d = 0; d < 3; d++) {
3090      combiner.variable_B[d] = pv[c];
3091      c = c + i;
3092   }
3093   combiner_map_input_function3(combiner.final.mapin_rgbB_mapping, combiner.variable_B);
3094   // C
3095   pv = combiner_map_input_select3(combiner.final.mapin_rgbC_input);
3096   c = combiner.final.mapin_rgbC_component * 3;
3097   i = ~combiner.final.mapin_rgbC_component & 1;
3098   for (d = 0; d < 3; d++) {
3099      combiner.variable_C[d] = pv[c];
3100      c = c + i;
3101   }
3102   combiner_map_input_function3(combiner.final.mapin_rgbC_mapping, combiner.variable_C);
3103   // D
3104   pv = combiner_map_input_select3(combiner.final.mapin_rgbD_input);
3105   c = combiner.final.mapin_rgbD_component * 3;
3106   i = ~combiner.final.mapin_rgbD_component & 1;
3107   for (d = 0; d < 3; d++) {
3108      combiner.variable_D[d] = pv[c];
3109      c = c + i;
3110   }
3111   combiner_map_input_function3(combiner.final.mapin_rgbD_mapping, combiner.variable_D);
3112   // G
3113   combiner.variable_G = combiner_map_input_select(combiner.final.mapin_aG_input, 2 + combiner.final.mapin_aG_component);
3114}
3115
3116void nv2a_renderer::combiner_final_output()
3117{
3118   // rgb
3119   combiner.output[0] = combiner.variable_A[0] * combiner.variable_B[0] + (1.0 - combiner.variable_A[0])*combiner.variable_C[0] + combiner.variable_D[0];
3120   combiner.output[1] = combiner.variable_A[1] * combiner.variable_B[1] + (1.0 - combiner.variable_A[1])*combiner.variable_C[1] + combiner.variable_D[1];
3121   combiner.output[2] = combiner.variable_A[2] * combiner.variable_B[2] + (1.0 - combiner.variable_A[2])*combiner.variable_C[2] + combiner.variable_D[2];
3122   combiner.output[0] = MIN(combiner.output[0], 1.0);
3123   combiner.output[1] = MIN(combiner.output[1], 1.0);
3124   combiner.output[2] = MIN(combiner.output[2], 1.0);
3125   // a
3126   combiner.output[3] = combiner_map_input_function(combiner.final.mapin_aG_mapping, combiner.variable_G);
3127}
3128
3129void nv2a_renderer::combiner_function_AB(float result[4])
3130{
3131   result[0] = combiner.variable_A[0] * combiner.variable_B[0];
3132   result[1] = combiner.variable_A[1] * combiner.variable_B[1];
3133   result[2] = combiner.variable_A[2] * combiner.variable_B[2];
3134}
3135
3136void nv2a_renderer::combiner_function_AdotB(float result[4])
3137{
3138   result[0] = combiner.variable_A[0] * combiner.variable_B[0] + combiner.variable_A[1] * combiner.variable_B[1] + combiner.variable_A[2] * combiner.variable_B[2];
3139   result[1] = result[0];
3140   result[2] = result[0];
3141}
3142
3143void nv2a_renderer::combiner_function_CD(float result[4])
3144{
3145   result[0] = combiner.variable_C[0] * combiner.variable_D[0];
3146   result[1] = combiner.variable_C[1] * combiner.variable_D[1];
3147   result[2] = combiner.variable_C[2] * combiner.variable_D[2];
3148}
3149
3150void nv2a_renderer::combiner_function_CdotD(float result[4])
3151{
3152   result[0] = combiner.variable_C[0] * combiner.variable_D[0] + combiner.variable_C[1] * combiner.variable_D[1] + combiner.variable_C[2] * combiner.variable_D[2];
3153   result[1] = result[0];
3154   result[2] = result[0];
3155}
3156
3157void nv2a_renderer::combiner_function_ABmuxCD(float result[4])
3158{
3159   if (combiner.register_spare0[3] >= 0.5)
3160      combiner_function_AB(result);
3161   else
3162      combiner_function_CD(result);
3163}
3164
3165void nv2a_renderer::combiner_function_ABsumCD(float result[4])
3166{
3167   result[0] = combiner.variable_A[0] * combiner.variable_B[0] + combiner.variable_C[0] * combiner.variable_D[0];
3168   result[1] = combiner.variable_A[1] * combiner.variable_B[1] + combiner.variable_C[1] * combiner.variable_D[1];
3169   result[2] = combiner.variable_A[2] * combiner.variable_B[2] + combiner.variable_C[2] * combiner.variable_D[2];
3170}
3171
3172void nv2a_renderer::combiner_compute_rgb_outputs(int stage_number)
3173{
3174   int n = stage_number;
3175   int m;
3176   float biasrgb, scalergb;
3177
3178   if (combiner.stage[n].mapout_rgb_bias)
3179      biasrgb = -0.5;
3180   else
3181      biasrgb = 0;
3182   switch (combiner.stage[n].mapout_rgb_scale) {
3183   case 0:
3184   default:
3185      scalergb = 1.0;
3186      break;
3187   case 1:
3188      scalergb = 2.0;
3189      break;
3190   case 2:
3191      scalergb = 4.0;
3192      break;
3193   case 3:
3194      scalergb = 0.5;
3195      break;
3196   }
3197   if (combiner.stage[n].mapout_rgbAB_dotproduct) {
3198      m = 1;
3199      combiner_function_AdotB(combiner.function_RGBop1);
3200   }
3201   else {
3202      m = 0;
3203      combiner_function_AB(combiner.function_RGBop1);
3204   }
3205   combiner.function_RGBop1[0] = MAX(MIN((combiner.function_RGBop1[0] + biasrgb) * scalergb, 1.0), -1.0);
3206   combiner.function_RGBop1[1] = MAX(MIN((combiner.function_RGBop1[1] + biasrgb) * scalergb, 1.0), -1.0);
3207   combiner.function_RGBop1[2] = MAX(MIN((combiner.function_RGBop1[2] + biasrgb) * scalergb, 1.0), -1.0);
3208   if (combiner.stage[n].mapout_rgbCD_dotproduct) {
3209      m = m | 1;
3210      combiner_function_CdotD(combiner.function_RGBop2);
3211   }
3212   else
3213      combiner_function_CD(combiner.function_RGBop2);
3214   combiner.function_RGBop2[0] = MAX(MIN((combiner.function_RGBop2[0] + biasrgb) * scalergb, 1.0), -1.0);
3215   combiner.function_RGBop2[1] = MAX(MIN((combiner.function_RGBop2[1] + biasrgb) * scalergb, 1.0), -1.0);
3216   combiner.function_RGBop2[2] = MAX(MIN((combiner.function_RGBop2[2] + biasrgb) * scalergb, 1.0), -1.0);
3217   if (m == 0) {
3218      if (combiner.stage[n].mapout_rgb_muxsum)
3219         combiner_function_ABmuxCD(combiner.function_RGBop3);
3220      else
3221         combiner_function_ABsumCD(combiner.function_RGBop3);
3222      combiner.function_RGBop3[0] = MAX(MIN((combiner.function_RGBop3[0] + biasrgb) * scalergb, 1.0), -1.0);
3223      combiner.function_RGBop3[1] = MAX(MIN((combiner.function_RGBop3[1] + biasrgb) * scalergb, 1.0), -1.0);
3224      combiner.function_RGBop3[2] = MAX(MIN((combiner.function_RGBop3[2] + biasrgb) * scalergb, 1.0), -1.0);
3225   }
3226}
3227
3228void nv2a_renderer::combiner_compute_a_outputs(int stage_number)
3229{
3230   int n = stage_number;
3231   float biasa, scalea;
3232
3233   if (combiner.stage[n].mapout_a_bias)
3234      biasa = -0.5;
3235   else
3236      biasa = 0;
3237   switch (combiner.stage[n].mapout_a_scale) {
3238   case 0:
3239   default:
3240      scalea = 1.0;
3241      break;
3242   case 1:
3243      scalea = 2.0;
3244      break;
3245   case 2:
3246      scalea = 4.0;
3247      break;
3248   case 3:
3249      scalea = 0.5;
3250      break;
3251   }
3252   combiner.function_Aop1 = combiner.variable_A[3] * combiner.variable_B[3];
3253   combiner.function_Aop1 = MAX(MIN((combiner.function_Aop1 + biasa) * scalea, 1.0), -1.0);
3254   combiner.function_Aop2 = combiner.variable_C[3] * combiner.variable_D[3];
3255   combiner.function_Aop2 = MAX(MIN((combiner.function_Aop2 + biasa) * scalea, 1.0), -1.0);
3256   if (combiner.stage[n].mapout_a_muxsum) {
3257      if (combiner.register_spare0[3] >= 0.5)
3258         combiner.function_Aop3 = combiner.variable_A[3] * combiner.variable_B[3];
3259      else
3260         combiner.function_Aop3 = combiner.variable_C[3] * combiner.variable_D[3];
3261   }
3262   else
3263      combiner.function_Aop3 = combiner.variable_A[3] * combiner.variable_B[3] + combiner.variable_C[3] * combiner.variable_D[3];
3264   combiner.function_Aop3 = MAX(MIN((combiner.function_Aop3 + biasa) * scalea, 1.0), -1.0);
3265}
3266
3267bool nv2a_renderer::vblank_callback(screen_device &screen, bool state)
3268{
3269   //printf("vblank_callback\n\r");
3270   if (state == true)
3271      pcrtc[0x100 / 4] |= 1;
3272   else
3273      pcrtc[0x100 / 4] &= ~1;
3274   if (pcrtc[0x100 / 4] & pcrtc[0x140 / 4])
3275      pmc[0x100 / 4] |= 0x1000000;
3276   else
3277      pmc[0x100 / 4] &= ~0x1000000;
3278   if ((pmc[0x100 / 4] != 0) && (pmc[0x140 / 4] != 0)) {
3279      // send interrupt
3280      return true;
3281   }
3282   else
3283      return false;
3284}
3285
3286UINT32 nv2a_renderer::screen_update_callback(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
3287{
3288   UINT32 *dst = (UINT32 *)bitmap.raw_pixptr(0, 0);
3289   UINT32 *src = (UINT32 *)fb.raw_pixptr(0, 0);
3290
3291   //printf("updatescreen\n\r");
3292   memcpy(dst, src, bitmap.rowbytes()*bitmap.height());
3293   return 0;
3294}
3295
3296READ32_MEMBER(nv2a_renderer::geforce_r)
3297{
3298   static int x, ret;
3299
3300   ret = 0;
3301   if (offset == 0x1804f6) {
3302      x = x ^ 0x08080808;
3303      ret = x;
3304   }
3305   if ((offset >= 0x00101000 / 4) && (offset < 0x00102000 / 4)) {
3306      //logerror("NV_2A: read STRAPS[%06X] mask %08X value %08X\n",offset*4-0x00101000,mem_mask,ret);
3307   }
3308   else if ((offset >= 0x00002000 / 4) && (offset < 0x00004000 / 4)) {
3309      ret = pfifo[offset - 0x00002000 / 4];
3310      // PFIFO.CACHE1.STATUS or PFIFO.RUNOUT_STATUS
3311      if ((offset == 0x3214 / 4) || (offset == 0x2400 / 4))
3312         ret = 0x10;
3313      //logerror("NV_2A: read PFIFO[%06X] value %08X\n",offset*4-0x00002000,ret);
3314   }
3315   else if ((offset >= 0x00700000 / 4) && (offset < 0x00800000 / 4)) {
3316      ret = ramin[offset - 0x00700000 / 4];
3317      //logerror("NV_2A: read PRAMIN[%06X] value %08X\n",offset*4-0x00700000,ret);
3318   }
3319   else if ((offset >= 0x00400000 / 4) && (offset < 0x00402000 / 4)) {
3320      //logerror("NV_2A: read PGRAPH[%06X] value %08X\n",offset*4-0x00400000,ret);
3321   }
3322   else if ((offset >= 0x00600000 / 4) && (offset < 0x00601000 / 4)) {
3323      ret = pcrtc[offset - 0x00600000 / 4];
3324      //logerror("NV_2A: read PCRTC[%06X] value %08X\n",offset*4-0x00600000,ret);
3325   }
3326   else if ((offset >= 0x00000000 / 4) && (offset < 0x00001000 / 4)) {
3327      ret = pmc[offset - 0x00000000 / 4];
3328      //logerror("NV_2A: read PMC[%06X] value %08X\n",offset*4-0x00000000,ret);
3329   }
3330   else if ((offset >= 0x00800000 / 4) && (offset < 0x00900000 / 4)) {
3331      // 32 channels size 0x10000 each, 8 subchannels per channel size 0x2000 each
3332      int chanel, subchannel, suboffset;
3333
3334      suboffset = offset - 0x00800000 / 4;
3335      chanel = (suboffset >> (16 - 2)) & 31;
3336      subchannel = (suboffset >> (13 - 2)) & 7;
3337      suboffset = suboffset & 0x7ff;
3338      if (suboffset < 0x80 / 4)
3339         ret = channel[chanel][subchannel].regs[suboffset];
3340      //logerror("NV_2A: read channel[%02X,%d,%04X]=%08X\n",chanel,subchannel,suboffset*4,ret);
3341      return ret;
3342   }
3343   else;
3344   //logerror("NV_2A: read at %08X mask %08X value %08X\n",0xfd000000+offset*4,mem_mask,ret);
3345   return ret;
3346}
3347
3348WRITE32_MEMBER(nv2a_renderer::geforce_w)
3349{
3350   if ((offset >= 0x00101000 / 4) && (offset < 0x00102000 / 4)) {
3351      //logerror("NV_2A: write STRAPS[%06X] mask %08X value %08X\n",offset*4-0x00101000,mem_mask,data);
3352   }
3353   else if ((offset >= 0x00002000 / 4) && (offset < 0x00004000 / 4)) {
3354      int e = offset - 0x00002000 / 4;
3355      if (e >= (sizeof(pfifo) / sizeof(UINT32)))
3356         return;
3357      COMBINE_DATA(pfifo + e);
3358      //logerror("NV_2A: read PFIFO[%06X]=%08X\n",offset*4-0x00002000,data & mem_mask); // 2210 pfifo ramht & 1f0 << 12
3359   }
3360   else if ((offset >= 0x00700000 / 4) && (offset < 0x00800000 / 4)) {
3361      int e = offset - 0x00700000 / 4;
3362      if (e >= (sizeof(ramin) / sizeof(UINT32)))
3363         return;
3364      COMBINE_DATA(ramin + e);
3365      //logerror("NV_2A: write PRAMIN[%06X]=%08X\n",offset*4-0x00700000,data & mem_mask);
3366   }
3367   else if ((offset >= 0x00400000 / 4) && (offset < 0x00402000 / 4)) {
3368      //logerror("NV_2A: write PGRAPH[%06X]=%08X\n",offset*4-0x00400000,data & mem_mask);
3369   }
3370   else if ((offset >= 0x00600000 / 4) && (offset < 0x00601000 / 4)) {
3371      int e = offset - 0x00600000 / 4;
3372      if (e >= (sizeof(pcrtc) / sizeof(UINT32)))
3373         return;
3374      COMBINE_DATA(pcrtc + e);
3375      //logerror("NV_2A: write PCRTC[%06X]=%08X\n",offset*4-0x00600000,data & mem_mask);
3376   }
3377   else if ((offset >= 0x00000000 / 4) && (offset < 0x00001000 / 4)) {
3378      int e = offset - 0x00000000 / 4;
3379      if (e >= (sizeof(pmc) / sizeof(UINT32)))
3380         return;
3381      COMBINE_DATA(pmc + e);
3382      //logerror("NV_2A: write PMC[%06X]=%08X\n",offset*4-0x00000000,data & mem_mask);
3383   }
3384   else if ((offset >= 0x00800000 / 4) && (offset < 0x00900000 / 4)) {
3385      // 32 channels size 0x10000 each, 8 subchannels per channel size 0x2000 each
3386      int chanel, subchannel, suboffset;
3387      int method, count, handle, objclass;
3388#ifdef LOG_NV2A
3389      int subch;
3390#endif
3391
3392      suboffset = offset - 0x00800000 / 4;
3393      chanel = (suboffset >> (16 - 2)) & 31;
3394      subchannel = (suboffset >> (13 - 2)) & 7;
3395      suboffset = suboffset & 0x7ff;
3396      //logerror("NV_2A: write channel[%02X,%d,%04X]=%08X\n",chanel,subchannel,suboffset*4,data & mem_mask);
3397      if (suboffset >= 0x80 / 4)
3398         return;
3399      COMBINE_DATA(&channel[chanel][subchannel].regs[suboffset]);
3400      if ((suboffset == 0x40 / 4) || (suboffset == 0x44 / 4)) { // DMA_PUT or DMA_GET
3401         UINT32 *dmaput, *dmaget;
3402         UINT32 cmd, cmdtype;
3403         int countlen;
3404
3405         dmaput = &channel[chanel][subchannel].regs[0x40 / 4];
3406         dmaget = &channel[chanel][subchannel].regs[0x44 / 4];
3407         //printf("dmaget %08X dmaput %08X\n\r",*dmaget,*dmaput);
3408         if ((*dmaput == 0x048cf000) && (*dmaget == 0x07f4d000))
3409            *dmaget = *dmaput;
3410         while (*dmaget != *dmaput) {
3411            cmd = space.read_dword(*dmaget);
3412            *dmaget += 4;
3413            cmdtype = geforce_commandkind(cmd);
3414            switch (cmdtype)
3415            {
3416            case 6: // jump
3417#ifdef LOG_NV2A
3418               printf("jump dmaget %08X", *dmaget);
3419#endif
3420               *dmaget = cmd & 0xfffffffc;
3421#ifdef LOG_NV2A
3422               printf(" -> %08X\n\r", *dmaget);
3423#endif
3424               break;
3425            case 0: // increasing method
3426               method = (cmd >> 2) & 2047; // method*4 is address // if method >= 0x40 send it to assigned object
3427#ifdef LOG_NV2A
3428               subch = (cmd >> 13) & 7;
3429#endif
3430               count = (cmd >> 18) & 2047;
3431               if ((method == 0) && (count == 1)) {
3432                  handle = space.read_dword(*dmaget);
3433                  handle = geforce_object_offset(handle);
3434#ifdef LOG_NV2A
3435                  logerror("  assign to subchannel %d object at %d\n", subch, handle);
3436#endif
3437                  channel[chanel][subchannel].object.objhandle = handle;
3438                  handle = ramin[handle / 4];
3439                  objclass = handle & 0xff;
3440                  channel[chanel][subchannel].object.objclass = objclass;
3441                  *dmaget += 4;
3442               }
3443               else {
3444#ifdef LOG_NV2A
3445                  logerror("  subch. %d method %04x offset %04x count %d\n", subch, method, method * 4, count);
3446#endif
3447                  while (count > 0) {
3448                     countlen = 1;
3449                     geforce_exec_method(space, chanel, subchannel, method, *dmaget, countlen);
3450                     count--;
3451                     method++;
3452                     *dmaget += 4;
3453                  }
3454               }
3455               break;
3456            case 5: // non-increasing method
3457               method = (cmd >> 2) & 2047;
3458#ifdef LOG_NV2A
3459               subch = (cmd >> 13) & 7;
3460#endif
3461               count = (cmd >> 18) & 2047;
3462               if ((method == 0) && (count == 1)) {
3463#ifdef LOG_NV2A
3464                  logerror("  assign channel %d\n", subch);
3465#endif
3466                  handle = space.read_dword(*dmaget);
3467                  handle = geforce_object_offset(handle);
3468#ifdef LOG_NV2A
3469                  logerror("  assign to subchannel %d object at %d\n", subch, handle);
3470#endif
3471                  channel[chanel][subchannel].object.objhandle = handle;
3472                  handle = ramin[handle / 4];
3473                  objclass = handle & 0xff;
3474                  channel[chanel][subchannel].object.objclass = objclass;
3475                  *dmaget += 4;
3476               }
3477               else {
3478#ifdef LOG_NV2A
3479                  logerror("  subch. %d method %04x offset %04x count %d\n", subch, method, method * 4, count);
3480#endif
3481                  while (count > 0) {
3482                     countlen = count;
3483                     geforce_exec_method(space, chanel, subchannel, method, *dmaget, countlen);
3484                     *dmaget += 4 * (count - countlen);
3485                     count = countlen;
3486                  }
3487               }
3488               break;
3489            case 3: // long non-increasing method
3490               method = (cmd >> 2) & 2047;
3491#ifdef LOG_NV2A
3492               subch = (cmd >> 13) & 7;
3493#endif
3494               count = space.read_dword(*dmaget);
3495               *dmaget += 4;
3496               if ((method == 0) && (count == 1)) {
3497                  handle = space.read_dword(*dmaget);
3498                  handle = geforce_object_offset(handle);
3499#ifdef LOG_NV2A
3500                  logerror("  assign to subchannel %d object at %d\n", subch, handle);
3501#endif
3502                  channel[chanel][subchannel].object.objhandle = handle;
3503                  handle = ramin[handle / 4];
3504                  objclass = handle & 0xff;
3505                  channel[chanel][subchannel].object.objclass = objclass;
3506                  *dmaget += 4;
3507               }
3508               else {
3509#ifdef LOG_NV2A
3510                  logerror("  subch. %d method %04x offset %04x count %d\n", subch, method, method * 4, count);
3511#endif
3512                  while (count > 0) {
3513                     countlen = count;
3514                     geforce_exec_method(space, chanel, subchannel, method, *dmaget, countlen);
3515                     *dmaget += 4 * (count - countlen);
3516                     count = countlen;
3517                  }
3518               }
3519               break;
3520            default:
3521               logerror("  unimplemented command %08X\n", cmd);
3522            }
3523         }
3524      }
3525   }
3526   else;
3527   //      logerror("NV_2A: write at %08X mask %08X value %08X\n",0xfd000000+offset*4,mem_mask,data);
3528}
trunk/src/mess/drivers/cnsector.c
r242208r242209
5858
5959***************************************************************************/
6060
61// The device strobes the outputs very fast, it is unnoticeable to the user.
61// Devices with TMS09x0 strobe the outputs very fast, it is unnoticeable to the user.
6262// To prevent flickering here, we need to simulate a decay.
6363
6464// decay time, in steps of 10ms
r242208r242209
118118
119119   // read selected button rows
120120   for (int i = 0; i < 5; i++)
121      if (m_o >> i & 1)
121      if (m_o & (1 << i))
122122         k |= m_button_matrix[i]->read();
123123   
124124   return k;
trunk/src/mess/drivers/comp4.c
r242208r242209
102102
103103   // read selected button rows
104104   for (int i = 0; i < 3; i++)
105      if (m_o >> (i+1) & 1)
105      if (m_o & (1 << (i + 1)))
106106         k |= m_button_matrix[i]->read();
107107   
108108   return k;
trunk/src/mess/drivers/gamate.c
r242208r242209
11/******************************************************************************
22 PeT mess@utanet.at 2007, 2014
3 Peter Wilhelmsen peter.wilhelmsen@gmail.com
4 Morten Shearman Kirkegaard morten+gamate@afdelingp.dk
53******************************************************************************/
64
75#include "emu.h"
r242208r242209
1715      : driver_device(mconfig, type, tag)
1816      , m_maincpu(*this, "maincpu")
1917      , m_cart(*this, "cartslot")
20//      , m_gfxdecode(*this, "gfxdecode")
18//      , m_gfxdecode(*this, "gfxdecode")
2119      , m_io_joy(*this, "JOY")
22      ,   m_palette(*this, "palette")
23      , m_cart_rom(*this, "cart_rom")
24      , m_bios(*this, "bios")
20      ,   m_palette(*this, "palette")
2521   { }
2622
2723   DECLARE_PALETTE_INIT(gamate);
28   DECLARE_READ8_MEMBER(protection_r);
29   DECLARE_READ8_MEMBER(gamate_cart_protection_r);
30   DECLARE_WRITE8_MEMBER(gamate_cart_protection_w);
31   DECLARE_READ8_MEMBER(gamate_video_r);
32   DECLARE_READ8_MEMBER(gamate_pad_r);
33   DECLARE_WRITE8_MEMBER(gamate_video_w);
34   DECLARE_READ8_MEMBER(gamate_audio_r);
35   DECLARE_WRITE8_MEMBER(gamate_audio_w);
36   DECLARE_WRITE8_MEMBER(gamate_bios_w);
24   DECLARE_READ8_MEMBER(video_r);
25   DECLARE_READ8_MEMBER(pad_r);
26   DECLARE_WRITE8_MEMBER(video_w);
27   DECLARE_WRITE8_MEMBER(audio_w);
28   DECLARE_WRITE8_MEMBER(bios_w);
3729   DECLARE_DRIVER_INIT(gamate);
3830   UINT32 screen_update_gamate(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
3931   INTERRUPT_GEN_MEMBER(gamate_interrupt);
40   TIMER_CALLBACK_MEMBER(gamate_timer);
41   TIMER_CALLBACK_MEMBER(gamate_timer2);
4232
4333private:
4434   virtual void machine_start();
4535
4636   struct
4737   {
48     UINT8 reg[8];
49     struct {
50       bool write;
51       bool page2; // else page1
52         UINT8 ypos, xpos/*tennis*/;
53       UINT8 data[2][0x100][0x20];
54     } bitmap;
55     UINT8 x, y;
56      bool y_increment;
38   UINT8 reg[8];
39   struct {
40      bool write; // else tilemap
41      bool page2; // else page1
42      UINT8 data[2][0x100][0x20];
43      } bitmap;
44   struct {
45      UINT8 data[32][32];
46   } tilemap;
47   UINT8 x, y;
5748   } video;
5849
59   struct {
60      int bit_shifter;
61      UINT8 cartridge_byte;
62      UINT16 address; // in reality something more like short local cartridge address offset
63      bool unprotected;
64      bool failed;
65   } card_protection;
66
50//  UINT8 m_ports[5];
51//  UINT8 m_ram[0x4000];
6752   required_device<cpu_device> m_maincpu;
6853   required_device<generic_slot_device> m_cart;
69//   required_device<gfxdecode_device> m_gfxdecode;
54//  required_device<gfxdecode_device> m_gfxdecode;
7055   required_ioport m_io_joy;
7156   required_device<palette_device> m_palette;
72   required_shared_ptr<UINT8> m_cart_rom;
73   required_shared_ptr<UINT8> m_bios;
74   emu_timer *timer1;
75   emu_timer *timer2;
7657};
7758
78WRITE8_MEMBER( gamate_state::gamate_cart_protection_w )
59WRITE8_MEMBER( gamate_state::video_w )
7960{
61   if (m_maincpu->pc()<0xf000)
62   logerror("%.6f %04x video write %04x %02x\n", machine().time().as_double(), m_maincpu->pc(), offset,data);
63   video.reg[offset]=data;
8064   switch (offset) {
81   case 0:
82      card_protection.failed= card_protection.failed || ((card_protection.cartridge_byte&0x80)!=0) != ((data&4)!=0);
83      card_protection.bit_shifter++;
84      if (card_protection.bit_shifter>=8) {
85         card_protection.cartridge_byte=m_cart_rom[card_protection.address++];
86         card_protection.bit_shifter=0;
87      }
88      break;
65   case 1: video.bitmap.write=data&0x40;break; // probably y increment
66   case 4: video.bitmap.page2=data&0x80;video.x=data&0x7f;break;
67   case 5: video.y=data;break;
68   case 7:
69   if (video.bitmap.write) {
70      if (video.x<ARRAY_LENGTH(video.bitmap.data[0][0]) /*&& video.y<ARRAY_LENGTH(video.bitmap.data[0])*/)
71      video.bitmap.data[video.bitmap.page2][video.y][video.x]=data;
72      else
73      logerror("%.6f %04x video bitmap x %x invalid\n",machine().time().as_double(), m_maincpu->pc(), video.x);
74      video.y++;
75   } else {
76      if (video.x<ARRAY_LENGTH(video.tilemap.data[0]) && (video.y&0x1f)<ARRAY_LENGTH(video.tilemap.data))
77      video.tilemap.data[video.y&0x1f][video.x]=data;
78      else
79      logerror("%.6f %04x video tilemap %x %x invalid\n",machine().time().as_double(), m_maincpu->pc(), video.x, video.y);
80      video.x++;
8981   }
90}
91READ8_MEMBER( gamate_state::gamate_cart_protection_r )
92{
93   UINT8 ret=1;
94   switch (offset) {
95   case 0:
96      ret=(card_protection.cartridge_byte&0x80)?2:0;
97      card_protection.cartridge_byte<<=1;
98      card_protection.bit_shifter++;
99      if (card_protection.bit_shifter>=8) {
100         card_protection.bit_shifter=0;
101         card_protection.cartridge_byte=m_cart_rom[card_protection.address++];
102         card_protection.unprotected=true;
103         if (!card_protection.failed) {
104         } // now protection chip on cartridge activates cartridge chip select on cpu accesses
105      }
106      break;
10782   }
108   return ret;
10983}
11084
111READ8_MEMBER( gamate_state::protection_r ) { return 1; }
112
113WRITE8_MEMBER( gamate_state::gamate_video_w )
85READ8_MEMBER( gamate_state::video_r )
11486{
115  video.reg[offset]=data;
116  switch (offset) {
117  case 1: video.bitmap.write=data&0xc0; // more addressing mode
118      video.y_increment=data&0x40;
119      break;
120   case 2: video.bitmap.xpos=data;break; // at least 7 bits
121   case 3: video.bitmap.ypos=data;break; // at least 7 bits
122  case 4: video.bitmap.page2=data&0x80;video.x=data&0x7f;break;
123  case 5: video.y=data;break;
124  case 7:
125    if (video.bitmap.write) {
126      if (video.x<ARRAY_LENGTH(video.bitmap.data[0][0]) && video.y<ARRAY_LENGTH(video.bitmap.data[0]))
127        video.bitmap.data[video.bitmap.page2][video.y][video.x]=data;
128      else
129        logerror("%.6f %04x video bitmap x %x invalid\n",machine().time().as_double(), m_maincpu->pc(), video.x);
130    } else {
131        video.bitmap.data[0][video.y][video.x&(ARRAY_LENGTH(video.bitmap.data[0][0])-1)]=data;
132    }   
133    if (video.y_increment) video.y++;
134      else video.x++;
135  }
87   if (offset!=6) return 0;
88   UINT8 data=0;
89   if (video.bitmap.write) {
90      if (video.x<ARRAY_LENGTH(video.bitmap.data[0][0]) /*&& video.y<ARRAY_LENGTH(video.bitmap.data[0])*/)
91      data=video.bitmap.data[video.bitmap.page2][video.y][video.x];
92      else
93      logerror("%.6f video bitmap x %x invalid\n",machine().time().as_double(),video.x);
94   } else {
95      if (video.x<ARRAY_LENGTH(video.tilemap.data[0]) && video.y<ARRAY_LENGTH(video.tilemap.data))
96      data=video.tilemap.data[video.y][video.x];
97      else
98      logerror("%.6f video tilemap %x %x invalid\n",machine().time().as_double(),video.x, video.y);
99   }
100   if (m_maincpu->pc()<0xf000)
101   logerror("%.6f video read %04x %02x\n",machine().time().as_double(),offset, data);
102   return data;
136103}
137104
138READ8_MEMBER( gamate_state::gamate_video_r )
105WRITE8_MEMBER( gamate_state::audio_w )
139106{
140   if (offset!=6) return 0;
141  UINT8 data=0;
142  if (video.bitmap.write) {
143      if (video.x<ARRAY_LENGTH(video.bitmap.data[0][0]) && video.y<ARRAY_LENGTH(video.bitmap.data[0]))
144        data=video.bitmap.data[video.bitmap.page2][video.y][video.x];   
145      else
146        logerror("%.6f video bitmap x %x invalid\n",machine().time().as_double(),video.x);
147  } else {
148    data=video.bitmap.data[0][video.y][video.x&(ARRAY_LENGTH(video.bitmap.data[0][0])-1)];
149  }
150  if (m_maincpu->pc()<0xf000)
151    logerror("%.6f video read %04x %02x\n",machine().time().as_double(),offset, data);
152  return data;
107   //  logerror("%.6f audio write %04x %02x\n",timer_get_time(),offset,data);
153108}
154109
155WRITE8_MEMBER( gamate_state::gamate_audio_w )
110WRITE8_MEMBER( gamate_state::bios_w )
156111{
157  logerror("%.6f %04x audio write %04x %02x\n",machine().time().as_double(),m_maincpu->pc(),offset,data);
158}
112   UINT8 *memory = memregion("maincpu")->base(); //memory_region (REGION_CPU1);
159113
160READ8_MEMBER( gamate_state::gamate_audio_r )
161{
162  logerror("%.6f %04x audio read %04x \n",machine().time().as_double(),m_maincpu->pc(),offset);
163   return 0;
114   unsigned short stack=m_maincpu->sp();//cpu_get_reg(M6502_S)|0x100;
115   unsigned short address= memory[stack+1]|(memory[stack+2]<<8);
116   switch (offset) {
117   case 0x12:
118   logerror("%.6f bios api %04x %04x string:%04x x:%02x y:%02x\n",
119            machine().time().as_double(), offset|0xf000, address,
120            memory[0]|(memory[1]<<8), 0, 0);//cpu_get_reg(M6502_X), cpu_get_reg(M6502_Y) );
121   break;
122   case 0x15:
123   logerror("%.6f bios api %04x %04x string:%04x x:%02x y:%02x\n",
124            machine().time().as_double(), offset|0xf000, address,
125            memory[0]|(memory[1]<<8), 0, 0); //cpu_get_reg(M6502_X), cpu_get_reg(M6502_Y) );
126   break;
127   case 0x18:
128   logerror("%.6f bios api %04x %04x string:%04x\n",machine().time().as_double(), offset|0xf000, address,
129            memory[0]|(memory[1]<<8) );
130   break;
131   case 0x1b:
132   logerror("%.6f bios api %04x %04x string:%04x\n",machine().time().as_double(), offset|0xf000, address,
133            memory[0]|(memory[1]<<8) );
134   break;
135   case 0x1e:
136   logerror("%.6f bios api %04x %04x string:%04x\n",machine().time().as_double(), offset|0xf000, address,
137            memory[0]|(memory[1]<<8) );
138   break;
139   case 0x2a: // cube up menu lighting
140   logerror("%.6f bios api %04x %04x 1c1d:%04x a:%02x x:%02x y:%02x\n",
141            machine().time().as_double(), offset|0xf000, address,
142            memory[0x1c]|(memory[0x1d]<<8),
143            0,0,0);//cpu_get_reg(M6502_A), cpu_get_reg(M6502_X), cpu_get_reg(M6502_Y) );
144   break;
145   default:
146   logerror("%.6f bios api %04x %04x\n",machine().time().as_double(), offset|0xf000, address);
147   }
164148}
165149
166
167READ8_MEMBER( gamate_state::gamate_pad_r )
150READ8_MEMBER( gamate_state::pad_r )
168151{
169  UINT8 data=m_io_joy->read();
170  return data;
152   UINT8 data=m_io_joy->read();//readinputport(0);
153   //  logerror("%.6f pad read %04x %02x\n",timer_get_time(),offset,data);
154   return data;
171155}
172156
173157static ADDRESS_MAP_START( gamate_mem, AS_PROGRAM, 8, gamate_state )
174    AM_RANGE(0x0000, 0x03ff) AM_RAM
175  AM_RANGE(0x4000, 0x400d) AM_READWRITE(gamate_audio_r, gamate_audio_w)
176  AM_RANGE(0x4400, 0x4400) AM_READ(gamate_pad_r)
177  AM_RANGE(0x5000, 0x5007) AM_READWRITE(gamate_video_r, gamate_video_w)
178  AM_RANGE(0x5a00, 0x5a00) AM_READ(protection_r)
158//  AM_RANGE(0x4000, 0x7fff) AM_READWRITE(gmaster_io_r, gmaster_io_w)
179159
180  AM_RANGE(0x6000, 0xdfff) AM_ROM AM_SHARE("cart_rom")
181   AM_RANGE(0x6000, 0x6002) AM_READWRITE(gamate_cart_protection_r, gamate_cart_protection_w)
182//   AM_RANGE(0x6000, 0xdfff) AM_READWRITE(gamate_cart_r, gamate_cart_w)
183  AM_RANGE(0xf000, 0xffff) AM_ROM AM_SHARE("bios")
160   AM_RANGE(0x0000, 0x03ff) AM_RAM
161   AM_RANGE(0x4000, 0x400d) AM_WRITE(audio_w)
162   AM_RANGE(0x4400, 0x4400) AM_READ(pad_r)
163//  AM_RANGE(0x5006, 0x5006) AM_READ(video_r)
164//  AM_RANGE(0x5000, 0x5007) AM_WRITE(video_w)
165   AM_RANGE(0x5000, 0x5007) AM_READWRITE(video_r, video_w)
166
167   AM_RANGE(0x6000, 0xdfff) AM_ROM
168   AM_RANGE(0xf000, 0xffff) AM_ROM
184169ADDRESS_MAP_END
185170
186171
r242208r242209
188173   PORT_START("JOY")
189174   PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_JOYSTICK_UP)
190175   PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN )
191   PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT )
192   PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT )
176   PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) // left?
177   PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) // rechts?
193178   PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_BUTTON1) PORT_NAME("A")
194179   PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_BUTTON2) PORT_NAME("B")
195180   PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_START) PORT_NAME("start/pause")
196181   PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_SELECT) PORT_NAME("select")
197182INPUT_PORTS_END
198183
184#if 0
199185static const struct gfx_layout gamate_charlayout =
200186{
201        4,      /* width of object */
202        1,      /* height of object */
203        256,/* 256 characters */
204        2,      /* bits per pixel */
205        { 0,1 }, /* no bitplanes */
206        /* x offsets */
207        { 0,2,4,6 },
208        /* y offsets */
209        { 0 },
210        8*1 /* size of 1 object in bits */
187      4,      /* width of object */
188      1,      /* height of object */
189      256,/* 256 characters */
190      2,      /* bits per pixel */
191      { 0,1 }, /* no bitplanes */
192      /* x offsets */
193      { 0,2,4,6 },
194      /* y offsets */
195      { 0 },
196      8*1 /* size of 1 object in bits */
211197};
212198
213199static const unsigned short gamate_palette[4] =
214200{
215201   0,1,2,3
216202};
203#endif
217204
218205/* palette in red, green, blue tribles */
219206static const unsigned char gamate_colors[4][3] =
220207{
221  { 255,255,255 },
222  { 0xa0, 0xa0, 0xa0 },
223  { 0x60, 0x60, 0x60 },
224  { 0, 0, 0 }
208   { 255,255,255 },
209   { 0xa0, 0xa0, 0xa0 },
210   { 0x60, 0x60, 0x60 },
211   { 0, 0, 0 }
225212};
226213
214#if 0
227215static GFXDECODE_START( gamate_charlayout )
228        GFXDECODE_ENTRY( "gfx1", 0x0000, gamate_charlayout, 0, 0x100 )
216      GFXDECODE_ENTRY( "gfx1", 0x0000, gamate_charlayout, 0, 0x100 )
229217GFXDECODE_END
218#endif
230219
231220PALETTE_INIT_MEMBER(gamate_state, gamate)
232221{
r242208r242209
256245
257246UINT32 gamate_state::screen_update_gamate(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
258247{
259  int x, y, j;
260  for (y=0;y<160;y++) {
261    for (x=0, j=0;x<160;x+=8, j++) {
262//      UINT8 d1=video.bitmap.data[0][(y+video.bitmap.ypos)&0xff][j+video.bitmap.xpos/8];
263//      UINT8 d2=video.bitmap.data[1][(y+video.bitmap.ypos)&0xff][j+video.bitmap.xpos/8];
264      UINT8 d1=video.bitmap.data[0][(y+video.bitmap.ypos)%200][j]; // kill shot, tornade
265      UINT8 d2=video.bitmap.data[1][(y+video.bitmap.ypos)%200][j];
248   int x, y, j;
249   for (y=0;y<160;y++) {
250   for (x=0, j=0;x<160;x+=8, j++) {
251//  for (y=0;y<256;y++) {
252//    for (x=0, j=0;x<256;x+=8, j++) {
253      UINT8 d1=video.bitmap.data[0][y][j];
254      UINT8 d2=video.bitmap.data[1][y][j];
255#if 0
256      UINT16 data=PLANES2_2_PACKED(d1, d2);
257      m_gfxdecode->gfx(0)->opaque(bitmap, bitmap.cliprect(), (data>>8)&0xff,0,0,0, x, y);
258      m_gfxdecode->gfx(0)->opaque(bitmap, bitmap.cliprect(), data&0xff,0,0,0, x+4, y);
259#else
266260         BlitPlane(&bitmap.pix16(y, x+4), d1, d2);
267261         BlitPlane(&bitmap.pix16(y, x), d1>>4, d2>>4);
268    }
269  }
262#endif
263   }
264   }
265   for (y=0; y<32; y++) {
266   for (x=0; x<32; x++) {
267#if 0
268      UINT8 d=video.tilemap.data[y][x];
269      if (d) {
270      m_gfxdecode->gfx(0)->opaque(bitmap, bitmap.cliprect(), 0xff,0,0,0, 256+x*8, y*8);
271      m_gfxdecode->gfx(0)->opaque(bitmap, bitmap.cliprect(), 0xff,0,0,0, 256+x*8, y*8+1);
272      m_gfxdecode->gfx(0)->opaque(bitmap, bitmap.cliprect(), 0xff,0,0,0, 256+x*8, y*8+2);
273      m_gfxdecode->gfx(0)->opaque(bitmap, bitmap.cliprect(), 0xff,0,0,0, 256+x*8, y*8+3);
274      m_gfxdecode->gfx(0)->opaque(bitmap, bitmap.cliprect(), 0xff,0,0,0, 256+x*8, y*8+4);
275      m_gfxdecode->gfx(0)->opaque(bitmap, bitmap.cliprect(), 0xff,0,0,0, 256+x*8, y*8+5);
276      m_gfxdecode->gfx(0)->opaque(bitmap, bitmap.cliprect(), 0xff,0,0,0, 256+x*8, y*8+6);
277      m_gfxdecode->gfx(0)->opaque(bitmap, bitmap.cliprect(), 0xff,0,0,0, 256+x*8, y*8+7);
278      m_gfxdecode->gfx(0)->opaque(bitmap, bitmap.cliprect(), 0xff,0,0,0, 260+x*8, y*8);
279      m_gfxdecode->gfx(0)->opaque(bitmap, bitmap.cliprect(), 0xff,0,0,0, 260+x*8, y*8+1);
280      m_gfxdecode->gfx(0)->opaque(bitmap, bitmap.cliprect(), 0xff,0,0,0, 260+x*8, y*8+2);
281      m_gfxdecode->gfx(0)->opaque(bitmap, bitmap.cliprect(), 0xff,0,0,0, 260+x*8, y*8+3);
282      m_gfxdecode->gfx(0)->opaque(bitmap, bitmap.cliprect(), 0xff,0,0,0, 260+x*8, y*8+4);
283      m_gfxdecode->gfx(0)->opaque(bitmap, bitmap.cliprect(), 0xff,0,0,0, 260+x*8, y*8+5);
284      m_gfxdecode->gfx(0)->opaque(bitmap, bitmap.cliprect(), 0xff,0,0,0, 260+x*8, y*8+6);
285      m_gfxdecode->gfx(0)->opaque(bitmap, bitmap.cliprect(), 0xff,0,0,0, 260+x*8, y*8+7);
286      } else {
287      m_gfxdecode->gfx(0)->opaque(bitmap, bitmap.cliprect(), 0,0,0,0, 256+x*8, y*8);
288      m_gfxdecode->gfx(0)->opaque(bitmap, bitmap.cliprect(), 0,0,0,0, 256+x*8, y*8+1);
289      m_gfxdecode->gfx(0)->opaque(bitmap, bitmap.cliprect(), 0,0,0,0, 256+x*8, y*8+2);
290      m_gfxdecode->gfx(0)->opaque(bitmap, bitmap.cliprect(), 0,0,0,0, 256+x*8, y*8+3);
291      m_gfxdecode->gfx(0)->opaque(bitmap, bitmap.cliprect(), 0,0,0,0, 256+x*8, y*8+4);
292      m_gfxdecode->gfx(0)->opaque(bitmap, bitmap.cliprect(), 0,0,0,0, 256+x*8, y*8+5);
293      m_gfxdecode->gfx(0)->opaque(bitmap, bitmap.cliprect(), 0,0,0,0, 256+x*8, y*8+6);
294      m_gfxdecode->gfx(0)->opaque(bitmap, bitmap.cliprect(), 0,0,0,0, 256+x*8, y*8+7);
295      m_gfxdecode->gfx(0)->opaque(bitmap, bitmap.cliprect(), 0,0,0,0, 260+x*8, y*8);
296      m_gfxdecode->gfx(0)->opaque(bitmap, bitmap.cliprect(), 0,0,0,0, 260+x*8, y*8+1);
297      m_gfxdecode->gfx(0)->opaque(bitmap, bitmap.cliprect(), 0,0,0,0, 260+x*8, y*8+2);
298      m_gfxdecode->gfx(0)->opaque(bitmap, bitmap.cliprect(), 0,0,0,0, 260+x*8, y*8+3);
299      m_gfxdecode->gfx(0)->opaque(bitmap, bitmap.cliprect(), 0,0,0,0, 260+x*8, y*8+4);
300      m_gfxdecode->gfx(0)->opaque(bitmap, bitmap.cliprect(), 0,0,0,0, 260+x*8, y*8+5);
301      m_gfxdecode->gfx(0)->opaque(bitmap, bitmap.cliprect(), 0,0,0,0, 260+x*8, y*8+6);
302      m_gfxdecode->gfx(0)->opaque(bitmap, bitmap.cliprect(), 0,0,0,0, 260+x*8, y*8+7);
303      }
304#endif
305   }
306   }
270307   return 0;
271308}
272309
273310DRIVER_INIT_MEMBER(gamate_state,gamate)
274311{
275312   memset(&video, 0, sizeof(video));/* memset(m_ram, 0, sizeof(m_ram));*/
276   UINT8 *gfx=memregion("gfx1")->base();   for (int i=0; i<256; i++) gfx[i]=i;
277   timer1 = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(gamate_state::gamate_timer),this));
278   timer2 = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(gamate_state::gamate_timer2),this));
313   UINT8 *gfx=memregion("gfx1")->base();   for (int i=0; i<256; i++) gfx[i]=i;
279314}
280315
281316
282317void gamate_state::machine_start()
283318{
284   if (m_cart->exists()) {
319   if (m_cart->exists())
285320      m_maincpu->space(AS_PROGRAM).install_read_handler(0x6000, 0xdfff, read8_delegate(FUNC(generic_slot_device::read_rom),(generic_slot_device*)m_cart));
286//      m_maincpu->space(AS_PROGRAM).install_read_handler(0x6000, 0x6000, READ8_DELEGATE(gamate_state, gamate_cart_protection_r));
287   }
288   m_bios[0xdf1]=0xea; m_bios[0xdf2]=0xea; // $47 protection readback
289   card_protection.address=0x6005-0x6001;
290   card_protection.bit_shifter=0;
291   card_protection.cartridge_byte=m_cart_rom[card_protection.address++];
292   card_protection.failed=false;
293   card_protection.unprotected=false;
294   timer2->enable(TRUE);
295   timer2->reset(m_maincpu->cycles_to_attotime(1000));
296321#if 0
297322   save_item(NAME(m_video.data));
298323   save_item(NAME(m_video.index));
r242208r242209
306331#endif
307332}
308333
309TIMER_CALLBACK_MEMBER(gamate_state::gamate_timer)
310{
311   m_maincpu->set_input_line(M6502_IRQ_LINE, CLEAR_LINE);
312   timer1->enable(FALSE);
313}
314334
315TIMER_CALLBACK_MEMBER(gamate_state::gamate_timer2)
316{
317   m_maincpu->set_input_line(M6502_IRQ_LINE, ASSERT_LINE);
318   timer1->enable(TRUE);
319   timer1->reset(m_maincpu->cycles_to_attotime(10/* cycles short enought to clear irq line early enough*/));
320   timer2->enable(TRUE);
321   timer2->reset(m_maincpu->cycles_to_attotime(40000));
322}
323
324
325335INTERRUPT_GEN_MEMBER(gamate_state::gamate_interrupt)
326336{
337//  m_maincpu->set_input_line(UPD7810_INTFE1, ASSERT_LINE);
338   static bool state=false;
339//  m_maincpu->set_input_line(M6502_IRQ_LINE, state?ASSERT_LINE: CLEAR_LINE);
340   state=!state;
341//  cpu_set_irq_line(0, M6502_INT_IRQ, PULSE_LINE);
327342}
328343
329344static MACHINE_CONFIG_START( gamate, gamate_state )
r242208r242209
333348
334349   MCFG_SCREEN_ADD("screen", LCD)
335350   MCFG_SCREEN_REFRESH_RATE(60)
336#ifdef SHOW_TILEMAP
337   MCFG_SCREEN_SIZE(256, 152+256)
338   MCFG_SCREEN_VISIBLE_AREA(0, 256-1, 0, 152+256-1)
351#if 0
352   MCFG_SCREEN_SIZE(512, 256)
353   MCFG_SCREEN_VISIBLE_AREA(0, 512-1, 0, 256-1)
339354#else
340   MCFG_SCREEN_SIZE(160, 152)
341   MCFG_SCREEN_VISIBLE_AREA(0, 160-1, 0, 152-1)
355   MCFG_SCREEN_SIZE(160, 160)
356   MCFG_SCREEN_VISIBLE_AREA(0, 160-1, 0, 160-1)
342357#endif
343358   MCFG_SCREEN_UPDATE_DRIVER(gamate_state, screen_update_gamate)
344359   MCFG_SCREEN_PALETTE("palette")
345360
346//   MCFG_GFXDECODE_ADD("gfxdecode", "palette", gamate )
361//  MCFG_GFXDECODE_ADD("gfxdecode", "palette", gamate )
347362   MCFG_PALETTE_ADD("palette", ARRAY_LENGTH(gamate_colors))
348//   MCFG_PALETTE_INDIRECT_ENTRIES(4)
363//  MCFG_PALETTE_INDIRECT_ENTRIES(4)
349364   MCFG_PALETTE_INIT_OWNER(gamate_state, gamate)
350365   MCFG_DEFAULT_LAYOUT(layout_lcd)
351366
352367   MCFG_GENERIC_CARTSLOT_ADD("cartslot", generic_linear_slot, "gamate_cart")
353368   MCFG_GENERIC_MANDATORY
354369
355   MCFG_SOFTWARE_LIST_ADD("cart_list","gamate")
370   MCFG_SOFTWARE_LIST_ADD("cart_list", "gamate")
356371MACHINE_CONFIG_END
357372
358373
359374ROM_START(gamate)
360375   ROM_REGION(0x10000,"maincpu", 0)
361   ROM_LOAD("gamate_bios_umc.bin", 0xf000, 0x1000, CRC(07090415) SHA1(ea449dc607601f9a68d855ad6ab53800d2e99297) )
362 ROM_REGION(0x100,"gfx1", ROMREGION_ERASEFF)
376   ROM_LOAD("gamate.bin", 0xf000, 0x1000, BAD_DUMP CRC(b8bf539b) SHA1(d00cb43b8a4cb0cc7fea06bee5f08490a71f5690) )
377//  ROM_LOAD("gamate.bin", 0xf000, 0x1000, CRC(b8bf539b) SHA1(d00cb43b8a4cb0cc7fea06bee5f08490a71f5690) )
378   ROM_REGION(0x100,"gfx1", ROMREGION_ERASEFF)
363379ROM_END
364380
365381
366382/*    YEAR  NAME      PARENT  COMPAT    MACHINE   INPUT    CLASS          INIT      COMPANY    FULLNAME */
367CONS( 19??, gamate,  0,      0,        gamate,  gamate, gamate_state, gamate, "Bit Corp", "Gamate", GAME_NO_SOUND)
368
369
383CONS( 19??, gamate,  0,      0,        gamate,  gamate, gamate_state, gamate, "Bit Corp", "Gamate", GAME_NOT_WORKING | GAME_NO_SOUND)
trunk/src/mess/drivers/leapster.c
r242208r242209
248248{
249249   UINT32 size = m_cart->common_get_size("rom");
250250
251   m_cart->rom_alloc(size, GENERIC_ROM32_WIDTH, ENDIANNESS_LITTLE);
251   m_cart->rom_alloc(size, GENERIC_ROM8_WIDTH, ENDIANNESS_LITTLE);
252252   m_cart->common_load_rom(m_cart->get_rom_base(), size, "rom");
253253
254254   return IMAGE_INIT_PASS;
r242208r242209
258258{
259259   astring region_tag;
260260   m_cart_rom = memregion(region_tag.cpy(m_cart->tag()).cat(GENERIC_ROM_REGION_TAG));
261   membank("cartrom")->set_base(m_cart_rom->base());
262261}
263262
264263void leapster_state::machine_reset()
r242208r242209
266265}
267266
268267static ADDRESS_MAP_START( leapster_map, AS_PROGRAM, 32, leapster_state )
269   AM_RANGE(0x00000000, 0x001fffff) AM_ROM AM_MIRROR(0x40000000) // pointers in the bios region seem to be to the 40xxxxxx region, either we mirror there or something (real bios?) is acutally missing
270   AM_RANGE(0x80000000, 0x807fffff) AM_ROMBANK("cartrom") // game ROM pointers are all to the 80xxxxxx region, so I assume it maps here
271
268   AM_RANGE(0x000000, 0x1fffff) AM_ROM
272269ADDRESS_MAP_END
273270
274271static MACHINE_CONFIG_START( leapster, leapster_state )
r242208r242209
296293
297294ROM_START(leapster)
298295   ROM_REGION(0x200000, "maincpu", ROMREGION_ERASE00)
299   ROM_LOAD( "155-10072-a.bin", 0x00000, 0x200000, CRC(af05e5a0) SHA1(d4468d060543ba7e44785041093bc98bcd9afa07) )
296   ROM_LOAD16_WORD_SWAP( "155-10072-a.bin", 0x00000, 0x200000, CRC(af05e5a0) SHA1(d4468d060543ba7e44785041093bc98bcd9afa07) )
300297ROM_END
301298
302299ROM_START(leapstertv)
303300   ROM_REGION(0x200000, "maincpu", ROMREGION_ERASE00)
304   ROM_LOAD( "am29pl160cb-90sf.bin", 0x00000, 0x200000, BAD_DUMP CRC(dc281f1f) SHA1(17588de54ab3bb82801bd5062f3e6aa687412178) )
301   ROM_LOAD16_WORD_SWAP( "am29pl160cb-90sf.bin", 0x00000, 0x200000, BAD_DUMP CRC(dc281f1f) SHA1(17588de54ab3bb82801bd5062f3e6aa687412178) )
305302ROM_END
306303
307304
trunk/src/mess/drivers/megadriv.c
r242208r242209
773773   ROM_SYSTEM_BIOS(0, "v100s", "v1.00S")
774774   ROMX_LOAD( "mpr-14088h.bin", 0x000000,  0x020000, CRC(3773d5aa) SHA1(bbf729a1aaa1667b783749299e1ad932aaf5f253), ROM_BIOS(1) | ROM_GROUPWORD | ROM_REVERSE)
775775   /* Confirmed by ElBarto */
776   ROM_SYSTEM_BIOS(1, "v100g", "v1.00G")
776   ROM_SYSTEM_BIOS(1, "v100g", "v1.00g")
777777   ROMX_LOAD( "epr-14088b.bin", 0x000000,  0x020000, CRC(69ed6ccd) SHA1(27d11c3836506f01ee81cd142c0cd8b51abebbd2), ROM_BIOS(2) | ROM_GROUPWORD | ROM_REVERSE)
778778   /* Confirmed by ElBarto */
779779   ROM_SYSTEM_BIOS(2, "v100l", "v1.00L")
780780   ROMX_LOAD( "mpr-14088c.bin", 0x000000,  0x020000, CRC(03134289) SHA1(d60cb5a53f26d6b13e354bc149217587f2301718), ROM_BIOS(3) | ROM_GROUPWORD | ROM_REVERSE)
781781   /* Confirmed by ElBarto */
782   ROM_SYSTEM_BIOS(3, "v100o", "v1.00O")
782   ROM_SYSTEM_BIOS(3, "v100o", "v1.00o")
783783   ROMX_LOAD( "epr-14088d.bin", 0x000000,  0x020000, CRC(dfa95ee9) SHA1(e13666c76fa0a2e94e2f651b26b0fd625bf55f07), ROM_BIOS(4) | ROM_GROUPWORD | ROM_REVERSE)
784   ROM_SYSTEM_BIOS(4, "v100p", "v1.00P")   // CRC: e2e70bc8 when byteswapped
785   ROMX_LOAD( "epr-14088e.bin", 0x000000,  0x020000, CRC(9d2da8f2) SHA1(4846f448160059a7da0215a5df12ca160f26dd69), ROM_BIOS(5) )
784   ROM_SYSTEM_BIOS(4, "v100p", "v1.00P")
785   ROMX_LOAD( "megacd_model1_bios_1_00p_j.bin", 0x000000,  0x020000, CRC(9d2da8f2) SHA1(4846f448160059a7da0215a5df12ca160f26dd69), ROM_BIOS(5) )
786786ROM_END
787787
788788/* Asia bios, when run in USA region will show :
trunk/src/mess/drivers/merlin.c
r242208r242209
7878   
7979   // read selected button rows
8080   for (int i = 0; i < 4; i++)
81      if (m_o >> i & 1)
81      if (m_o & (1 << i))
8282         k |= m_button_matrix[i]->read();
8383
8484   return k;
trunk/src/mess/drivers/simon.c
r242208r242209
6666   for (int i = 0; i < 4; i++)
6767   {
6868      const int r[4] = { 0, 1, 2, 9 };
69      if (m_r >> r[i] & 1)
69      if (m_r & (1 << r[i]))
7070         k |= m_button_matrix[i]->read();
7171   }
7272
trunk/src/mess/drivers/starwbc.c
r242208r242209
22// copyright-holders:hap
33/***************************************************************************
44
5  Kenner Star Wars - Electronic Battle Command
6  * TMS1100 MCU, labeled MP3438A
7 
8  This is a small tabletop space-dogfighting game. To start the game,
9  press BASIC/INTER/ADV and enter P#(number of players), then
10  START TURN. Refer to the official manual for more information.
5  Kenner Star Wars: Electronic Battle Command Game
6  * TMS1100 MCU, marked MP3438A
117
128
139***************************************************************************/
1410
1511#include "emu.h"
1612#include "cpu/tms0980/tms0980.h"
17#include "sound/speaker.h"
1813
1914#include "starwbc.lh"
2015
2116
22// master clock is unknown, the value below is an approximation
23// (patent says R=51K, C=47pf, but then it sounds too low pitched)
24#define MASTER_CLOCK (350000)
25
26
2717class starwbc_state : public driver_device
2818{
2919public:
3020   starwbc_state(const machine_config &mconfig, device_type type, const char *tag)
3121      : driver_device(mconfig, type, tag),
32      m_maincpu(*this, "maincpu"),
33      m_button_matrix(*this, "IN"),
34      m_speaker(*this, "speaker")
22      m_maincpu(*this, "maincpu")
3523   { }
3624
3725   required_device<cpu_device> m_maincpu;
38   required_ioport_array<5> m_button_matrix;
39   required_device<speaker_sound_device> m_speaker;
4026
4127   UINT16 m_r;
4228   UINT16 m_o;
4329
44   UINT16 m_leds_state[0x10];
45   UINT16 m_leds_cache[0x10];
46   UINT8 m_leds_decay[0x100];
47
4830   DECLARE_READ8_MEMBER(read_k);
4931   DECLARE_WRITE16_MEMBER(write_o);
5032   DECLARE_WRITE16_MEMBER(write_r);
51   
52   TIMER_DEVICE_CALLBACK_MEMBER(leds_decay_tick);
53   void leds_update();
54   void prepare_and_update();
5533
5634   virtual void machine_start();
5735};
r242208r242209
6038
6139/***************************************************************************
6240
63  LEDs
64
65***************************************************************************/
66
67// The device strobes the outputs very fast, it is unnoticeable to the user.
68// To prevent flickering here, we need to simulate a decay.
69
70// decay time, in steps of 10ms
71#define LEDS_DECAY_TIME 4
72
73void starwbc_state::leds_update()
74{
75   UINT16 active_state[0x10];
76   
77   for (int i = 0; i < 0x10; i++)
78   {
79      active_state[i] = 0;
80     
81      for (int j = 0; j < 0x10; j++)
82      {
83         int di = j << 4 | i;
84         
85         // turn on powered leds
86         if (m_leds_state[i] >> j & 1)
87            m_leds_decay[di] = LEDS_DECAY_TIME;
88         
89         // determine active state
90         int ds = (m_leds_decay[di] != 0) ? 1 : 0;
91         active_state[i] |= (ds << j);
92      }
93   }
94   
95   // on difference, send to output
96   for (int i = 0; i < 0x10; i++)
97      if (m_leds_cache[i] != active_state[i])
98      {
99         output_set_digit_value(i, active_state[i]);
100         
101         for (int j = 0; j < 8; j++)
102            output_set_lamp_value(i*10 + j, active_state[i] >> j & 1);
103      }
104   
105   memcpy(m_leds_cache, active_state, sizeof(m_leds_cache));
106}
107
108TIMER_DEVICE_CALLBACK_MEMBER(starwbc_state::leds_decay_tick)
109{
110   // slowly turn off unpowered leds
111   for (int i = 0; i < 0x100; i++)
112      if (!(m_leds_state[i & 0xf] >> (i>>4) & 1) && m_leds_decay[i])
113         m_leds_decay[i]--;
114   
115   leds_update();
116}
117
118void starwbc_state::prepare_and_update()
119{
120   UINT8 o = (m_o << 4 & 0xf0) | (m_o >> 4 & 0x0f);
121   const UINT8 mask[5] = { 0x30, 0xff, 0xff, 0x7f, 0x7f };
122   
123   // R0,R2,R4,R6,R8
124   for (int i = 0; i < 5; i++)
125      m_leds_state[i*2] = (m_r >> (i*2) & 1) ? (o & mask[i]) : 0;
126
127   leds_update();
128}
129
130
131
132/***************************************************************************
133
13441  I/O
13542
13643***************************************************************************/
13744
13845READ8_MEMBER(starwbc_state::read_k)
13946{
140   UINT8 k = 0;
141
142   // read selected button rows
143   for (int i = 0; i < 5; i++)
144   {
145      const int r[5] = { 0, 1, 3, 5, 7 };
146      if (m_r >> r[i] & 1)
147         k |= m_button_matrix[i]->read();
148   }
149
150   return k;
47   return 0;
15148}
15249
15350WRITE16_MEMBER(starwbc_state::write_r)
15451{
155   // R0,R2,R4: select lamp row
156   // R6,R8: select digit
157   // R0,R1,R3,R5,R7: input mux
158   // R9: piezo speaker
159   m_speaker->level_w(data >> 9 & 1);
160   
16152   m_r = data;
162   prepare_and_update();
16353}
16454
16555WRITE16_MEMBER(starwbc_state::write_o)
16656{
167   // O0-O7: leds state
16857   m_o = data;
169   prepare_and_update();
17058}
17159
17260
r242208r242209
17765
17866***************************************************************************/
17967
180/* physical button layout and labels is like this:
181
182    (reconnnaissance=yellow)        (tactical reaction=green)
183    [MAGNA] [ENEMY]                 [EM]       [BS]   [SCR]
184
185    [BASIC] [INTER]    [START TURN] [END TURN] [MOVE] [FIRE]
186    [ADV]   [P#]       [<]          [^]        [>]    [v]
187    (game=blue)        (maneuvers=red)                       */
188
18968static INPUT_PORTS_START( starwbc )
190   PORT_START("IN.0") // R0
191   PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_1) PORT_NAME("Basic Game")
192   PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_2) PORT_NAME("Intermediate Game")
193   PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_3) PORT_NAME("Advanced Game")
194   PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_4) PORT_CODE(KEYCODE_P) PORT_NAME("Player Number")
195
196   PORT_START("IN.1") // R1
197   PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_ENTER) PORT_NAME("Start Turn")
198   PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_UNUSED)
199   PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_UNUSED)
200   PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_BACKSPACE) PORT_CODE(KEYCODE_DEL) PORT_NAME("End Turn")
201
202   PORT_START("IN.2") // R3
203   PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_Q) PORT_NAME("Magna Scan") // only used in adv. game
204   PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_W) PORT_NAME("Enemy Scan") // only used in adv. game
205   PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_UNUSED)
206   PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_S) PORT_NAME("Screen Up")
207
208   PORT_START("IN.3") // R5
209   PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_E) PORT_NAME("Evasive Maneuvers")
210   PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_M) PORT_NAME("Move")
211   PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_F) PORT_NAME("Fire")
212   PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_B) PORT_NAME("Battle Stations")
213
214   PORT_START("IN.4") // R7
215   PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_LEFT) PORT_NAME("Left")
216   PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_UP) PORT_NAME("Up")
217   PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_DOWN) PORT_NAME("Down")
218   PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_RIGHT) PORT_NAME("Right")
21969INPUT_PORTS_END
22070
22171
r242208r242209
22878
22979void starwbc_state::machine_start()
23080{
231   memset(m_leds_state, 0, sizeof(m_leds_state));
232   memset(m_leds_cache, 0, sizeof(m_leds_cache));
233   memset(m_leds_decay, 0, sizeof(m_leds_decay));
23481   m_r = 0;
23582   m_o = 0;
23683   
237   save_item(NAME(m_leds_state));
238   save_item(NAME(m_leds_cache));
239   save_item(NAME(m_leds_decay));
24084   save_item(NAME(m_r));
24185   save_item(NAME(m_o));
24286}
r242208r242209
24589static MACHINE_CONFIG_START( starwbc, starwbc_state )
24690
24791   /* basic machine hardware */
248   MCFG_CPU_ADD("maincpu", TMS1100, MASTER_CLOCK)
92   MCFG_CPU_ADD("maincpu", TMS1100, 400000)
24993   MCFG_TMS1XXX_READ_K_CB(READ8(starwbc_state, read_k))
25094   MCFG_TMS1XXX_WRITE_O_CB(WRITE16(starwbc_state, write_o))
25195   MCFG_TMS1XXX_WRITE_R_CB(WRITE16(starwbc_state, write_r))
252
253   MCFG_TIMER_DRIVER_ADD_PERIODIC("leds_decay", starwbc_state, leds_decay_tick, attotime::from_msec(10))
25496   
25597   MCFG_DEFAULT_LAYOUT(layout_starwbc)
25698
25799   /* no video! */
258100
259101   /* sound hardware */
260   MCFG_SPEAKER_STANDARD_MONO("mono")
261   MCFG_SOUND_ADD("speaker", SPEAKER_SOUND, 0)
262   MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.25)
102//   MCFG_SPEAKER_STANDARD_MONO("mono")
263103MACHINE_CONFIG_END
264104
265105
r242208r242209
280120   ROM_LOAD( "tms1100_starwbc_opla.pla", 0, 365, CRC(d358a76d) SHA1(06b60b207540e9b726439141acadea9aba718013) )
281121ROM_END
282122
283ROM_START( starwbcp )
284   ROM_REGION( 0x0800, "maincpu", 0 )
285   ROM_LOAD( "us4270755", 0x0000, 0x0800, BAD_DUMP CRC(fb3332f2) SHA1(a79ac81e239983cd699b7cfcc55f89b203b2c9ec) ) // from patent US4270755, may have errors
286123
287   ROM_REGION( 867, "maincpu:mpla", 0 )
288   ROM_LOAD( "tms1100_starwbc_mpla.pla", 0, 867, CRC(03574895) SHA1(04407cabfb3adee2ee5e4218612cb06c12c540f4) )
289   ROM_REGION( 365, "maincpu:opla", 0 )
290   ROM_LOAD( "tms1100_starwbc_opla.pla", 0, 365, CRC(d358a76d) SHA1(06b60b207540e9b726439141acadea9aba718013) )
291ROM_END
292
293
294CONS( 1979, starwbc,  0,       0, starwbc, starwbc, driver_device, 0, "Kenner", "Star Wars - Electronic Battle Command", GAME_SUPPORTS_SAVE )
295CONS( 1979, starwbcp, starwbc, 0, starwbc, starwbc, driver_device, 0, "Kenner", "Star Wars - Electronic Battle Command (prototype)", GAME_SUPPORTS_SAVE )
124CONS( 1979, starwbc, 0, 0, starwbc, starwbc, driver_device, 0, "Kenner", "Star Wars: Electronic Battle Command Game", GAME_NOT_WORKING | GAME_SUPPORTS_SAVE | GAME_NO_SOUND )
trunk/src/mess/drivers/ticalc1x.c
r242208r242209
150150
151151   // read selected button rows
152152   for (int i = 0; i < 11; i++)
153      if (m_r >> i & 1)
153      if (m_r & (1 << i))
154154         k |= m_button_matrix[i]->read();
155155
156156   return k;
r242208r242209
182182
183183   // read selected button rows
184184   for (int i = 0; i < 7; i++)
185      if (m_o >> (i+1) & 1)
185      if (m_o & (1 << (i + 1)))
186186         k |= m_button_matrix[i]->read();
187187
188188   return k;
r242208r242209
213213
214214   // read selected button rows
215215   for (int i = 0; i < 4; i++)
216      if (m_o >> (i+1) & 1)
216      if (m_o & (1 << (i + 1)))
217217         k |= m_button_matrix[i]->read();
218218
219219   return k;
r242208r242209
255255
256256   // read selected button rows
257257   for (int i = 0; i < 8; i++)
258      if (m_o >> i & 1)
258      if (m_o & (1 << i))
259259         k |= m_button_matrix[i]->read();
260260
261261   return k;
trunk/src/mess/layout/starwbc.lay
r242208r242209
11<?xml version="1.0"?>
22<mamelayout version="2">
33
4<!-- define elements -->
5
6   <element name="static_black"><rect><color red="0.0" green="0.0" blue="0.0" /></rect></element>
7   <element name="static_yellow"><rect><color red="0.67" green="0.65" blue="0.1" /></rect></element>
8   <element name="static_red"><rect><color red="0.6" green="0.05" blue="0.0" /></rect></element>
9   <element name="static_gray"><rect><color red="0.66" green="0.66" blue="0.66" /></rect></element>
10
11   <element name="digit" defstate="0">
12      <led7seg><color red="1.0" green="0.25" blue="0.23" /></led7seg>
13   </element>
14
15   <element name="lamp" defstate="0">
16      <rect><color red="0.0" green="0.0" blue="0.0" /></rect>
17      <disk state="1">
18         <color red="1.0" green="0.25" blue="0.23" />
19         <bounds x="0.4" y="0.4" width="0.2" height="0.2" />
20      </disk>
21      <disk state="0">
22         <color red="0.2" green="0.05" blue="0.04" />
23         <bounds x="0.4" y="0.4" width="0.2" height="0.2" />
24      </disk>
25   </element>
26
27   <element name="nlamp" defstate="0">
28      <disk state="1"><color red="1.0" green="0.25" blue="0.23" /></disk>
29      <disk state="0"><color red="0.2" green="0.05" blue="0.04" /></disk>
30   </element>
31
32   <element name="text_a"><text string="A"><color red="0.69" green="0.69" blue="0.69" /></text></element>
33   <element name="text_b"><text string="B"><color red="0.69" green="0.69" blue="0.69" /></text></element>
34   <element name="text_c"><text string="C"><color red="0.69" green="0.69" blue="0.69" /></text></element>
35   <element name="text_d"><text string="D"><color red="0.69" green="0.69" blue="0.69" /></text></element>
36
37   <element name="text_1"><text string="1"><color red="0.69" green="0.69" blue="0.69" /></text></element>
38   <element name="text_2"><text string="2"><color red="0.69" green="0.69" blue="0.69" /></text></element>
39   <element name="text_3"><text string="3"><color red="0.69" green="0.69" blue="0.69" /></text></element>
40   <element name="text_4"><text string="4"><color red="0.69" green="0.69" blue="0.69" /></text></element>
41
42   <element name="text_alert"><text string="ALERT"><color red="0.69" green="0.69" blue="0.69" /></text></element>
43   <element name="text_combat"><text string="COMBAT"><color red="0.69" green="0.69" blue="0.69" /></text></element>
44   <element name="text_force"><text string="FORCE UNITS"><color red="0.69" green="0.69" blue="0.69" /></text></element>
45   <element name="text_players"><text string="PLAYERS"><color red="0.69" green="0.69" blue="0.69" /></text></element>
46
47
48
49<!-- build screen -->
50
514   <view name="Internal Layout">
52      <bounds left="0" right="165" top="0" bottom="105" />
53     
54      <bezel element="static_yellow"><bounds x="3" y="17" width="10" height="83" /></bezel>
55      <bezel element="static_black"><bounds x="4" y="18" width="8" height="81" /></bezel>
5      <bounds left="0" right="200" top="0" bottom="200" />
566
57      <bezel element="static_red"><bounds x="17" y="3" width="83" height="10" /></bezel>
58      <bezel element="static_black"><bounds x="18" y="4" width="81" height="8" /></bezel>
59
60      <bezel element="static_yellow"><bounds x="3.5" y="38" width="9" height="1" /></bezel>
61      <bezel element="static_yellow"><bounds x="3.5" y="58" width="9" height="1" /></bezel>
62      <bezel element="static_yellow"><bounds x="3.5" y="78" width="9" height="1" /></bezel>
63
64      <bezel element="static_red"><bounds x="38" y="3.5" width="1" height="9" /></bezel>
65      <bezel element="static_red"><bounds x="58" y="3.5" width="1" height="9" /></bezel>
66      <bezel element="static_red"><bounds x="78" y="3.5" width="1" height="9" /></bezel>
67
68      <bezel element="text_a"><bounds x="4" y="24.5" width="8" height="8" /></bezel>
69      <bezel element="text_b"><bounds x="4" y="44.5" width="8" height="8" /></bezel>
70      <bezel element="text_c"><bounds x="4" y="64.5" width="8" height="8" /></bezel>
71      <bezel element="text_d"><bounds x="4" y="84.5" width="8" height="8" /></bezel>
72
73      <bezel element="text_1"><bounds x="24.5" y="4" width="8" height="8" /></bezel>
74      <bezel element="text_2"><bounds x="44.5" y="4" width="8" height="8" /></bezel>
75      <bezel element="text_3"><bounds x="64.5" y="4" width="8" height="8" /></bezel>
76      <bezel element="text_4"><bounds x="84.5" y="4" width="8" height="8" /></bezel>
77
78     
79   <!-- lamp matrix -->
80     
81      <bezel element="static_gray"><bounds x="17" y="17" width="83" height="83" /></bezel>
82
83      <bezel name="lamp20" element="lamp"><bounds x="20" y="20" width="17" height="17" /></bezel>
84      <bezel name="lamp21" element="lamp"><bounds x="40" y="20" width="17" height="17" /></bezel>
85      <bezel name="lamp22" element="lamp"><bounds x="60" y="20" width="17" height="17" /></bezel>
86      <bezel name="lamp23" element="lamp"><bounds x="80" y="20" width="17" height="17" /></bezel>
87
88      <bezel name="lamp24" element="lamp"><bounds x="20" y="40" width="17" height="17" /></bezel>
89      <bezel name="lamp25" element="lamp"><bounds x="40" y="40" width="17" height="17" /></bezel>
90      <bezel name="lamp26" element="lamp"><bounds x="60" y="40" width="17" height="17" /></bezel>
91      <bezel name="lamp27" element="lamp"><bounds x="80" y="40" width="17" height="17" /></bezel>
92
93      <bezel name="lamp40" element="lamp"><bounds x="20" y="60" width="17" height="17" /></bezel>
94      <bezel name="lamp41" element="lamp"><bounds x="40" y="60" width="17" height="17" /></bezel>
95      <bezel name="lamp42" element="lamp"><bounds x="60" y="60" width="17" height="17" /></bezel>
96      <bezel name="lamp43" element="lamp"><bounds x="80" y="60" width="17" height="17" /></bezel>
97
98      <bezel name="lamp44" element="lamp"><bounds x="20" y="80" width="17" height="17" /></bezel>
99      <bezel name="lamp45" element="lamp"><bounds x="40" y="80" width="17" height="17" /></bezel>
100      <bezel name="lamp46" element="lamp"><bounds x="60" y="80" width="17" height="17" /></bezel>
101      <bezel name="lamp47" element="lamp"><bounds x="80" y="80" width="17" height="17" /></bezel>
102
103
104   <!-- right side -->
105
106      <bezel element="static_gray"><bounds x="105" y="17" width="55" height="23" /></bezel>
107      <bezel element="static_black"><bounds x="106" y="18" width="53" height="21" /></bezel>
108      <bezel element="text_alert"><bounds x="106" y="18.5" width="53" height="8" /></bezel>
109
110      <bezel name="lamp5" element="nlamp"><bounds x="130.8" y="30.5" width="3.4" height="3.4" /></bezel>
111
112      <bezel element="static_gray"><bounds x="105" y="43" width="55" height="23" /></bezel>
113      <bezel element="static_black"><bounds x="106" y="44" width="53" height="21" /></bezel>
114      <bezel element="text_combat"><bounds x="106" y="44.5" width="53" height="8" /></bezel>
115
116      <bezel name="lamp4" element="nlamp"><bounds x="130.8" y="56.5" width="3.4" height="3.4" /></bezel>
117
118      <bezel element="static_gray"><bounds x="105" y="69" width="55" height="31" /></bezel>
119      <bezel element="static_black"><bounds x="106" y="70" width="53" height="29" /></bezel>
120      <bezel element="text_force"><bounds x="106" y="70.5" width="53" height="8" /></bezel>
121      <bezel element="text_players"><bounds x="106" y="90" width="53" height="8" /></bezel>
122
123      <bezel name="digit6" element="digit"><bounds x="126" y="79.7" width="6" height="9" /></bezel>
124      <bezel name="digit8" element="digit"><bounds x="132" y="79.7" width="6" height="9" /></bezel>
125
1267   </view>
1278</mamelayout>
trunk/src/mess/mess.lst
r242208r242209
22382238mpf1p
22392239cnsector
22402240starwbc
2241starwbcp
22422241stopthie
22432242amico2k
22442243jtc


Previous 199869 Revisions Next


© 1997-2024 The MAME Team