Previous 199869 Revisions Next

r23535 Saturday 8th June, 2013 at 12:31:01 UTC by O. Galibert
naomi video: Pretend-modernize the powervr2 [O. Galibert]
[src/emu]delegate.h devcb2.c
[src/mame]mame.mak
[src/mame/drivers]naomi.c
[src/mame/includes]dc.h naomi.h
[src/mame/machine]dc.c
[src/mame/video]dc.c powervr2.c* powervr2.h
[src/mess]mess.mak
[src/mess/drivers]dccons.c
[src/mess/includes]dccons.h

trunk/src/mame/video/dc.c
r23534r23535
1/*
2    dc.c - Dreamcast video emulation
3
4*/
5
6#include "emu.h"
7#include "includes/dc.h"
8#include "cpu/sh4/sh4.h"
9#include "render.h"
10#include "rendutil.h"
11#include "video/rgbutil.h"
12
13#define DEBUG_FIFO_POLY (0)
14#define DEBUG_PVRTA (0)
15#define DEBUG_PVRTA_REGS (0)
16#define DEBUG_PVRDLIST  (0)
17#define DEBUG_PALRAM (1)
18
19#define NUM_BUFFERS 4
20
21/* PVR TA macro defines */
22/*
23SPG_HBLANK_INT
24---- --xx xxxx xxxx ---- ---- ---- ---- hblank_in_interrupt
25---- ---- ---- ---- --xx ---- ---- ---- hblank_int_mode
26---- ---- ---- ---- ---- --xx xxxx xxxx line_comp_val
27*/
28#define spg_hblank_in_irq   ((state->pvrta_regs[SPG_HBLANK_INT] & 0x03ff0000) >> 16)
29#define spg_hblank_in_irq_new   ((pvrta_regs[SPG_HBLANK_INT] & 0x03ff0000) >> 16)
30#define spg_hblank_int_mode ((state->pvrta_regs[SPG_HBLANK_INT] & 0x00003000) >> 12)
31#define spg_line_comp_val   ((state->pvrta_regs[SPG_HBLANK_INT] & 0x000003ff) >> 0)
32
33/*
34SPG_VBLANK_INT
35---- --xx xxxx xxxx ---- ---- ---- ---- vblank_out_interrupt_line_number
36---- ---- ---- ---- ---- --xx xxxx xxxx vblank_in_interrupt_line_number
37*/
38#define spg_vblank_out_irq_line_num ((state->pvrta_regs[SPG_VBLANK_INT] & 0x03ff0000) >> 16)
39#define spg_vblank_in_irq_line_num  ((state->pvrta_regs[SPG_VBLANK_INT] & 0x000003ff) >> 0)
40#define spg_vblank_out_irq_line_num_new ((pvrta_regs[SPG_VBLANK_INT] & 0x03ff0000) >> 16)
41#define spg_vblank_in_irq_line_num_new  ((pvrta_regs[SPG_VBLANK_INT] & 0x000003ff) >> 0)
42
43
44/*
45VO_BORDER_COL
46---- ---x ---- ---- ---- ---- ---- ---- Chroma ;suchie3 sets 0xff there, maybe it's 8 bits too?
47---- ---- xxxx xxxx ---- ---- ---- ---- Red
48---- ---- ---- ---- xxxx xxxx ---- ---- Green
49---- ---- ---- ---- ---- ---- xxxx xxxx Blue
50*/
51#define vo_border_K ((pvrta_regs[VO_BORDER_COL] & 0x01000000) >> 24)
52#define vo_border_R ((pvrta_regs[VO_BORDER_COL] & 0x00ff0000) >> 16)
53#define vo_border_G ((pvrta_regs[VO_BORDER_COL] & 0x0000ff00) >> 8)
54#define vo_border_B ((pvrta_regs[VO_BORDER_COL] & 0x000000ff) >> 0)
55
56/*
57SPG_HBLANK
58---- ---- --xx xxxx xxxx ---- ---- ---- hbend
59---- ---- ---- ---- ---- --xx xxxx xxxx hbstart
60*/
61#define spg_hbend    ((state->pvrta_regs[SPG_HBLANK] & 0x03ff0000) >> 16)
62#define spg_hbstart  ((state->pvrta_regs[SPG_HBLANK] & 0x000003ff) >> 0)
63
64
65/*
66SPG_LOAD
67---- ---- --xx xxxx xxxx ---- ---- ---- vcount
68---- ---- ---- ---- ---- --xx xxxx xxxx hcount
69*/
70#define spg_vcount   ((state->pvrta_regs[SPG_LOAD] & 0x03ff0000) >> 16)
71#define spg_hcount   ((state->pvrta_regs[SPG_LOAD] & 0x000003ff) >> 0)
72
73/*
74SPG_VBLANK
75---- ---- --xx xxxx xxxx ---- ---- ---- vbend
76---- ---- ---- ---- ---- --xx xxxx xxxx vbstart
77*/
78#define spg_vbend    ((state->pvrta_regs[SPG_VBLANK] & 0x03ff0000) >> 16)
79#define spg_vbstart  ((state->pvrta_regs[SPG_VBLANK] & 0x000003ff) >> 0)
80
81
82/*
83VO_CONTROL
84---- ---- --xx xxxx ---- ---- ---- ---- pclk_delay
85---- ---- ---- ---- ---- ---x ---- ---- pixel_double ;used in test mode
86---- ---- ---- ---- ---- ---- xxxx ---- field_mode
87---- ---- ---- ---- ---- ---- ---- x--- blank_video
88---- ---- ---- ---- ---- ---- ---- -x-- blank_pol
89---- ---- ---- ---- ---- ---- ---- --x- vsync_pol
90---- ---- ---- ---- ---- ---- ---- ---x hsync_pol
91*/
92#define spg_pclk_delay   ((state->pvrta_regs[VO_CONTROL] & 0x003f0000) >> 16)
93#define spg_pixel_double ((state->pvrta_regs[VO_CONTROL] & 0x00000100) >> 8)
94#define spg_field_mode   ((state->pvrta_regs[VO_CONTROL] & 0x000000f0) >> 4)
95#define spg_blank_video  ((pvrta_regs[VO_CONTROL] & 0x00000008) >> 3)
96#define spg_blank_pol    ((state->pvrta_regs[VO_CONTROL] & 0x00000004) >> 2)
97#define spg_vsync_pol    ((state->pvrta_regs[VO_CONTROL] & 0x00000002) >> 1)
98#define spg_hsync_pol    ((state->pvrta_regs[VO_CONTROL] & 0x00000001) >> 0)
99
100/*
101VO_STARTX
102---- ---- ---- ---- ---- ---x xxxx xxxx horzontal start position
103*/
104#define vo_horz_start_pos ((state->pvrta_regs[VO_STARTX] & 0x000003ff) >> 0)
105
106/*
107VO_STARTY
108---- ---x xxxx xxxx ---- ---- ---- ---- vertical start position on field 2
109---- ---- ---- ---- ---- ---x xxxx xxxx vertical start position on field 1
110*/
111
112#define vo_vert_start_pos_f2 ((state->pvrta_regs[VO_STARTY] & 0x03ff0000) >> 16)
113#define vo_vert_start_pos_f1 ((state->pvrta_regs[VO_STARTY] & 0x000003ff) >> 0)
114
115/*
116SPG_STATUS
117---- ---- ---- ---- --x- ---- ---- ---- vsync
118---- ---- ---- ---- ---x ---- ---- ---- hsync
119---- ---- ---- ---- ---- x--- ---- ---- blank
120---- ---- ---- ---- ---- -x-- ---- ---- field number
121---- ---- ---- ---- ---- --xx xxxx xxxx state->scanline
122*/
123
124static const int pvr_parconfseq[] = {1,2,3,2,3,4,5,6,5,6,7,8,9,10,11,12,13,14,13,14,15,16,17,16,17,0,0,0,0,0,18,19,20,19,20,21,22,23,22,23};
125static const int pvr_wordsvertex[24]  = {8,8,8,8,8,16,16,8,8,8, 8, 8,8,8,8,8,16,16, 8,16,16,8,16,16};
126static const int pvr_wordspolygon[24] = {8,8,8,8,8, 8, 8,8,8,8,16,16,8,8,8,8, 8, 8,16,16,16,8, 8, 8};
127static int pvr_parameterconfig[128];
128static UINT32 dilated0[15][1024];
129static UINT32 dilated1[15][1024];
130static int dilatechose[64];
131static float wbuffer[480][640];
132static void pvr_accumulationbuffer_to_framebuffer(address_space &space, int x,int y);
133
134// the real accumulation buffer is a 32x32x8bpp buffer into which tiles get rendered before they get copied to the framebuffer
135//  our implementation is not currently tile based, and thus the accumulation buffer is screen sized
136static bitmap_rgb32 *fake_accumulationbuffer_bitmap;
137static void render_to_accumulation_buffer(running_machine &machine,bitmap_rgb32 &bitmap,const rectangle &cliprect);
138
139struct texinfo  {
140   UINT32 address, vqbase;
141   int textured, sizex, sizey, stride, sizes, pf, palette, mode, mipmapped, blend_mode, filter_mode, flip_u, flip_v;
142
143   UINT32 (*r)(running_machine &machine, struct texinfo *t, float x, float y);
144   UINT32 (*blend)(UINT32 s, UINT32 d);
145   int palbase, cd;
146};
147
148typedef struct
149{
150   float x, y, w, u, v;
151} vert;
152
153struct strip
154{
155   int svert, evert;
156   texinfo ti;
157};
158
159struct receiveddata {
160   vert verts[65536];
161   strip strips[65536];
162
163   int verts_size, strips_size;
164   UINT32 ispbase;
165   UINT32 fbwsof1;
166   UINT32 fbwsof2;
167   int busy;
168   int valid;
169};
170
171struct pvrta_state {
172   int tafifo_pos, tafifo_mask, tafifo_vertexwords, tafifo_listtype;
173   int start_render_received;
174   int renderselect;
175   int listtype_used;
176   int alloc_ctrl_OPB_Mode, alloc_ctrl_PT_OPB, alloc_ctrl_TM_OPB, alloc_ctrl_T_OPB, alloc_ctrl_OM_OPB, alloc_ctrl_O_OPB;
177   receiveddata grab[NUM_BUFFERS];
178   int grabsel;
179   int grabsellast;
180   UINT32 paracontrol,paratype,endofstrip,listtype,global_paratype,parameterconfig;
181   UINT32 groupcontrol,groupen,striplen,userclip;
182   UINT32 objcontrol,shadow,volume,coltype,texture,offfset,gouraud,uv16bit;
183   UINT32 texturesizes,textureaddress,scanorder,pixelformat;
184   UINT32 blend_mode, srcselect,dstselect,fogcontrol,colorclamp, use_alpha;
185   UINT32 ignoretexalpha,flipuv,clampuv,filtermode,sstexture,mmdadjust,tsinstruction;
186   UINT32 depthcomparemode,cullingmode,zwritedisable,cachebypass,dcalcctrl,volumeinstruction,mipmapped,vqcompressed,strideselect,paletteselector;
187};
188
189enum
190{
191   TEX_FILTER_NEAREST = 0,
192   TEX_FILTER_BILINEAR,
193   TEX_FILTER_TRILINEAR_A,
194   TEX_FILTER_TRILINEAR_B
195};
196
197static pvrta_state state_ta;
198
199// Perform a standard bilinear filter across four pixels
200INLINE INT32 clamp(INT32 in, INT32 min, INT32 max)
201{
202   if(in < min) return min;
203   if(in > max) return max;
204   return in;
205}
206
207INLINE UINT32 bilinear_filter(UINT32 c0, UINT32 c1, UINT32 c2, UINT32 c3, float u, float v)
208{
209   UINT32 ui = (u * 256.0);
210   UINT32 vi = (v * 256.0);
211   return rgba_bilinear_filter(c0, c1, c3, c2, ui, vi);
212}
213
214// Multiply with alpha value in bits 31-24
215INLINE UINT32 bla(UINT32 c, UINT32 a)
216{
217   a = a >> 24;
218   return ((((c & 0xff00ff)*a) & 0xff00ff00) >> 8) | ((((c >> 8) & 0xff00ff)*a) & 0xff00ff00);
219}
220
221// Multiply with 1-alpha value in bits 31-24
222INLINE UINT32 blia(UINT32 c, UINT32 a)
223{
224   a = 0x100 - (a >> 24);
225   return ((((c & 0xff00ff)*a) & 0xff00ff00) >> 8) | ((((c >> 8) & 0xff00ff)*a) & 0xff00ff00);
226}
227
228// Per-component multiply with color value
229INLINE UINT32 blc(UINT32 c1, UINT32 c2)
230{
231   UINT32 cr =
232      (((c1 & 0x000000ff)*(c2 & 0x000000ff) & 0x0000ff00) >> 8)  |
233      (((c1 & 0x0000ff00)*(c2 & 0x0000ff00) & 0x00ff0000) >> 8);
234   c1 >>= 16;
235   c2 >>= 16;
236   cr |=
237      (((c1 & 0x000000ff)*(c2 & 0x000000ff) & 0x0000ff00) << 8)  |
238      (((c1 & 0x0000ff00)*(c2 & 0x0000ff00) & 0x00ff0000) << 8);
239   return cr;
240}
241
242// Per-component multiply with 1-color value
243INLINE UINT32 blic(UINT32 c1, UINT32 c2)
244{
245   UINT32 cr =
246      (((c1 & 0x000000ff)*(0x00100-(c2 & 0x000000ff)) & 0x0000ff00) >> 8)  |
247      (((c1 & 0x0000ff00)*(0x10000-(c2 & 0x0000ff00)) & 0x00ff0000) >> 8);
248   c1 >>= 16;
249   c2 >>= 16;
250   cr |=
251      (((c1 & 0x000000ff)*(0x00100-(c2 & 0x000000ff)) & 0x0000ff00) << 8)  |
252      (((c1 & 0x0000ff00)*(0x10000-(c2 & 0x0000ff00)) & 0x00ff0000) << 8);
253   return cr;
254}
255
256// Add two colors with saturation
257INLINE UINT32 bls(UINT32 c1, UINT32 c2)
258{
259   UINT32 cr1, cr2;
260   cr1 = (c1 & 0x00ff00ff) + (c2 & 0x00ff00ff);
261   if(cr1 & 0x0000ff00)
262      cr1 = (cr1 & 0xffff00ff) | 0x000000ff;
263   if(cr1 & 0xff000000)
264      cr1 = (cr1 & 0x00ffffff) | 0x00ff0000;
265
266   cr2 = ((c1 >> 8) & 0x00ff00ff) + ((c2 >> 8) & 0x00ff00ff);
267   if(cr2 & 0x0000ff00)
268      cr2 = (cr2 & 0xffff00ff) | 0x000000ff;
269   if(cr2 & 0xff000000)
270      cr2 = (cr2 & 0x00ffffff) | 0x00ff0000;
271   return cr1|(cr2 << 8);
272}
273
274// All 64 blending modes, 3 top bits are source mode, 3 bottom bits are destination mode
275INLINE UINT32 bl00(UINT32 s, UINT32 d) { return 0; }
276INLINE UINT32 bl01(UINT32 s, UINT32 d) { return d; }
277INLINE UINT32 bl02(UINT32 s, UINT32 d) { return blc(d, s); }
278INLINE UINT32 bl03(UINT32 s, UINT32 d) { return blic(d, s); }
279INLINE UINT32 bl04(UINT32 s, UINT32 d) { return bla(d, s); }
280INLINE UINT32 bl05(UINT32 s, UINT32 d) { return blia(d, s); }
281INLINE UINT32 bl06(UINT32 s, UINT32 d) { return bla(d, d); }
282INLINE UINT32 bl07(UINT32 s, UINT32 d) { return blia(d, d); }
283INLINE UINT32 bl10(UINT32 s, UINT32 d) { return s; }
284INLINE UINT32 bl11(UINT32 s, UINT32 d) { return bls(s, d); }
285INLINE UINT32 bl12(UINT32 s, UINT32 d) { return bls(s, blc(s, d)); }
286INLINE UINT32 bl13(UINT32 s, UINT32 d) { return bls(s, blic(s, d)); }
287INLINE UINT32 bl14(UINT32 s, UINT32 d) { return bls(s, bla(d, s)); }
288INLINE UINT32 bl15(UINT32 s, UINT32 d) { return bls(s, blia(d, s)); }
289INLINE UINT32 bl16(UINT32 s, UINT32 d) { return bls(s, bla(d, d)); }
290INLINE UINT32 bl17(UINT32 s, UINT32 d) { return bls(s, blia(d, d)); }
291INLINE UINT32 bl20(UINT32 s, UINT32 d) { return blc(d, s); }
292INLINE UINT32 bl21(UINT32 s, UINT32 d) { return bls(blc(d, s), d); }
293INLINE UINT32 bl22(UINT32 s, UINT32 d) { return bls(blc(d, s), blc(s, d)); }
294INLINE UINT32 bl23(UINT32 s, UINT32 d) { return bls(blc(d, s), blic(s, d)); }
295INLINE UINT32 bl24(UINT32 s, UINT32 d) { return bls(blc(d, s), bla(d, s)); }
296INLINE UINT32 bl25(UINT32 s, UINT32 d) { return bls(blc(d, s), blia(d, s)); }
297INLINE UINT32 bl26(UINT32 s, UINT32 d) { return bls(blc(d, s), bla(d, d)); }
298INLINE UINT32 bl27(UINT32 s, UINT32 d) { return bls(blc(d, s), blia(d, d)); }
299INLINE UINT32 bl30(UINT32 s, UINT32 d) { return blic(d, s); }
300INLINE UINT32 bl31(UINT32 s, UINT32 d) { return bls(blic(d, s), d); }
301INLINE UINT32 bl32(UINT32 s, UINT32 d) { return bls(blic(d, s), blc(s, d)); }
302INLINE UINT32 bl33(UINT32 s, UINT32 d) { return bls(blic(d, s), blic(s, d)); }
303INLINE UINT32 bl34(UINT32 s, UINT32 d) { return bls(blic(d, s), bla(d, s)); }
304INLINE UINT32 bl35(UINT32 s, UINT32 d) { return bls(blic(d, s), blia(d, s)); }
305INLINE UINT32 bl36(UINT32 s, UINT32 d) { return bls(blic(d, s), bla(d, d)); }
306INLINE UINT32 bl37(UINT32 s, UINT32 d) { return bls(blic(d, s), blia(d, d)); }
307INLINE UINT32 bl40(UINT32 s, UINT32 d) { return bla(s, s); }
308INLINE UINT32 bl41(UINT32 s, UINT32 d) { return bls(bla(s, s), d); }
309INLINE UINT32 bl42(UINT32 s, UINT32 d) { return bls(bla(s, s), blc(s, d)); }
310INLINE UINT32 bl43(UINT32 s, UINT32 d) { return bls(bla(s, s), blic(s, d)); }
311INLINE UINT32 bl44(UINT32 s, UINT32 d) { return bls(bla(s, s), bla(d, s)); }
312INLINE UINT32 bl45(UINT32 s, UINT32 d) { return bls(bla(s, s), blia(d, s)); }
313INLINE UINT32 bl46(UINT32 s, UINT32 d) { return bls(bla(s, s), bla(d, d)); }
314INLINE UINT32 bl47(UINT32 s, UINT32 d) { return bls(bla(s, s), blia(d, d)); }
315INLINE UINT32 bl50(UINT32 s, UINT32 d) { return blia(s, s); }
316INLINE UINT32 bl51(UINT32 s, UINT32 d) { return bls(blia(s, s), d); }
317INLINE UINT32 bl52(UINT32 s, UINT32 d) { return bls(blia(s, s), blc(s, d)); }
318INLINE UINT32 bl53(UINT32 s, UINT32 d) { return bls(blia(s, s), blic(s, d)); }
319INLINE UINT32 bl54(UINT32 s, UINT32 d) { return bls(blia(s, s), bla(d, s)); }
320INLINE UINT32 bl55(UINT32 s, UINT32 d) { return bls(blia(s, s), blia(d, s)); }
321INLINE UINT32 bl56(UINT32 s, UINT32 d) { return bls(blia(s, s), bla(d, d)); }
322INLINE UINT32 bl57(UINT32 s, UINT32 d) { return bls(blia(s, s), blia(d, d)); }
323INLINE UINT32 bl60(UINT32 s, UINT32 d) { return bla(s, d); }
324INLINE UINT32 bl61(UINT32 s, UINT32 d) { return bls(bla(s, d), d); }
325INLINE UINT32 bl62(UINT32 s, UINT32 d) { return bls(bla(s, d), blc(s, d)); }
326INLINE UINT32 bl63(UINT32 s, UINT32 d) { return bls(bla(s, d), blic(s, d)); }
327INLINE UINT32 bl64(UINT32 s, UINT32 d) { return bls(bla(s, d), bla(d, s)); }
328INLINE UINT32 bl65(UINT32 s, UINT32 d) { return bls(bla(s, d), blia(d, s)); }
329INLINE UINT32 bl66(UINT32 s, UINT32 d) { return bls(bla(s, d), bla(d, d)); }
330INLINE UINT32 bl67(UINT32 s, UINT32 d) { return bls(bla(s, d), blia(d, d)); }
331INLINE UINT32 bl70(UINT32 s, UINT32 d) { return blia(s, d); }
332INLINE UINT32 bl71(UINT32 s, UINT32 d) { return bls(blia(s, d), d); }
333INLINE UINT32 bl72(UINT32 s, UINT32 d) { return bls(blia(s, d), blc(s, d)); }
334INLINE UINT32 bl73(UINT32 s, UINT32 d) { return bls(blia(s, d), blic(s, d)); }
335INLINE UINT32 bl74(UINT32 s, UINT32 d) { return bls(blia(s, d), bla(d, s)); }
336INLINE UINT32 bl75(UINT32 s, UINT32 d) { return bls(blia(s, d), blia(d, s)); }
337INLINE UINT32 bl76(UINT32 s, UINT32 d) { return bls(blia(s, d), bla(d, d)); }
338INLINE UINT32 bl77(UINT32 s, UINT32 d) { return bls(blia(s, d), blia(d, d)); }
339
340static UINT32 (*const blend_functions[64])(UINT32 s, UINT32 d) = {
341   bl00, bl01, bl02, bl03, bl04, bl05, bl06, bl07,
342   bl10, bl11, bl12, bl13, bl14, bl15, bl16, bl17,
343   bl20, bl21, bl22, bl23, bl24, bl25, bl26, bl27,
344   bl30, bl31, bl32, bl33, bl34, bl35, bl36, bl37,
345   bl40, bl41, bl42, bl43, bl44, bl45, bl46, bl47,
346   bl50, bl51, bl52, bl53, bl54, bl55, bl56, bl57,
347   bl60, bl61, bl62, bl63, bl64, bl65, bl66, bl67,
348   bl70, bl71, bl72, bl73, bl74, bl75, bl76, bl77,
349};
350
351INLINE UINT32 cv_1555(UINT16 c)
352{
353   return
354      (c & 0x8000 ? 0xff000000 : 0) |
355      ((c << 9) & 0x00f80000) | ((c << 4) & 0x00070000) |
356      ((c << 6) & 0x0000f800) | ((c << 1) & 0x00000700) |
357      ((c << 3) & 0x000000f8) | ((c >> 2) & 0x00000007);
358}
359
360INLINE UINT32 cv_1555z(UINT16 c)
361{
362   return
363      (c & 0x8000 ? 0xff000000 : 0) |
364      ((c << 9) & 0x00f80000) |
365      ((c << 6) & 0x0000f800) |
366      ((c << 3) & 0x000000f8);
367}
368
369INLINE UINT32 cv_565(UINT16 c)
370{
371   return
372      0xff000000 |
373      ((c << 8) & 0x00f80000) | ((c << 3) & 0x00070000) |
374      ((c << 5) & 0x0000fc00) | ((c >> 1) & 0x00000300) |
375      ((c << 3) & 0x000000f8) | ((c >> 2) & 0x00000007);
376}
377
378INLINE UINT32 cv_565z(UINT16 c)
379{
380   return
381      0xff000000 |
382      ((c << 8) & 0x00f80000) |
383      ((c << 5) & 0x0000fc00) |
384      ((c << 3) & 0x000000f8);
385}
386
387INLINE UINT32 cv_4444(UINT16 c)
388{
389   return
390      ((c << 16) & 0xf0000000) | ((c << 12) & 0x0f000000) |
391      ((c << 12) & 0x00f00000) | ((c <<  8) & 0x000f0000) |
392      ((c <<  8) & 0x0000f000) | ((c <<  4) & 0x00000f00) |
393      ((c <<  4) & 0x000000f0) | ((c      ) & 0x0000000f);
394}
395
396INLINE UINT32 cv_4444z(UINT16 c)
397{
398   return
399      ((c << 16) & 0xf0000000) |
400      ((c << 12) & 0x00f00000) |
401      ((c <<  8) & 0x0000f000) |
402      ((c <<  4) & 0x000000f0);
403}
404
405INLINE UINT32 cv_yuv(UINT16 c1, UINT16 c2, int x)
406{
407   int u = 11*((c1 & 0xff) - 128);
408   int v = 11*((c2 & 0xff) - 128);
409   int y = (x & 1 ? c2 : c1) >> 8;
410   int r = y + v/8;
411   int g = y - u/32 - v/16;
412   int b = y + (3*u)/16;
413   r = r < 0 ? 0 : r > 255 ? 255 : r;
414   g = g < 0 ? 0 : g > 255 ? 255 : g;
415   b = b < 0 ? 0 : b > 255 ? 255 : b;
416   return 0xff000000 | (r << 16) | (g << 8) | b;
417}
418
419
420INLINE UINT32 tex_r_yuv_n(running_machine &machine, texinfo *t, float x, float y)
421{
422   dc_state *state = machine.driver_data<dc_state>();
423   int xt = ((int)x) & (t->sizex-1);
424   int yt = ((int)y) & (t->sizey-1);
425   int addrp = t->address + (t->stride*yt + (xt & ~1))*2;
426   UINT16 c1 = *(UINT16 *)((reinterpret_cast<UINT8 *>(state->dc_texture_ram.target())) + WORD_XOR_LE(addrp));
427   UINT16 c2 = *(UINT16 *)((reinterpret_cast<UINT8 *>(state->dc_texture_ram.target())) + WORD_XOR_LE(addrp+2));
428   return cv_yuv(c1, c2, xt);
429}
430
431INLINE UINT32 tex_r_1555_n(running_machine &machine, texinfo *t, float x, float y)
432{
433   dc_state *state = machine.driver_data<dc_state>();
434   int xt = ((int)x) & (t->sizex-1);
435   int yt = ((int)y) & (t->sizey-1);
436   int addrp = t->address + (t->stride*yt + xt)*2;
437   return cv_1555z(*(UINT16 *)((reinterpret_cast<UINT8 *>(state->dc_texture_ram.target())) + WORD_XOR_LE(addrp)));
438}
439
440INLINE UINT32 tex_r_1555_tw(running_machine &machine, texinfo *t, float x, float y)
441{
442   dc_state *state = machine.driver_data<dc_state>();
443   int xt = ((int)x) & (t->sizex-1);
444   int yt = ((int)y) & (t->sizey-1);
445   int addrp = t->address + (dilated1[t->cd][xt] + dilated0[t->cd][yt])*2;
446   return cv_1555(*(UINT16 *)((reinterpret_cast<UINT8 *>(state->dc_texture_ram.target())) + WORD_XOR_LE(addrp)));
447}
448
449INLINE UINT32 tex_r_1555_vq(running_machine &machine, texinfo *t, float x, float y)
450{
451   dc_state *state = machine.driver_data<dc_state>();
452   int xt = ((int)x) & (t->sizex-1);
453   int yt = ((int)y) & (t->sizey-1);
454   int idx = (reinterpret_cast<UINT8 *>(state->dc_texture_ram.target()))[BYTE_XOR_LE(t->address + dilated1[t->cd][xt >> 1] + dilated0[t->cd][yt >> 1])];
455   int addrp = t->vqbase + 8*idx + (dilated1[t->cd][xt & 1] + dilated0[t->cd][yt & 1])*2;
456   return cv_1555(*(UINT16 *)((reinterpret_cast<UINT8 *>(state->dc_texture_ram.target())) + WORD_XOR_LE(addrp)));
457}
458
459INLINE UINT32 tex_r_565_n(running_machine &machine, texinfo *t, float x, float y)
460{
461   dc_state *state = machine.driver_data<dc_state>();
462   int xt = ((int)x) & (t->sizex-1);
463   int yt = ((int)y) & (t->sizey-1);
464   int addrp = t->address + (t->stride*yt + xt)*2;
465   return cv_565z(*(UINT16 *)((reinterpret_cast<UINT8 *>(state->dc_texture_ram.target())) + WORD_XOR_LE(addrp)));
466}
467
468INLINE UINT32 tex_r_565_tw(running_machine &machine, texinfo *t, float x, float y)
469{
470   dc_state *state = machine.driver_data<dc_state>();
471   int xt = ((int)x) & (t->sizex-1);
472   int yt = ((int)y) & (t->sizey-1);
473   int addrp = t->address + (dilated1[t->cd][xt] + dilated0[t->cd][yt])*2;
474   return cv_565(*(UINT16 *)((reinterpret_cast<UINT8 *>(state->dc_texture_ram.target())) + WORD_XOR_LE(addrp)));
475}
476
477INLINE UINT32 tex_r_565_vq(running_machine &machine, texinfo *t, float x, float y)
478{
479   dc_state *state = machine.driver_data<dc_state>();
480   int xt = ((int)x) & (t->sizex-1);
481   int yt = ((int)y) & (t->sizey-1);
482   int idx = (reinterpret_cast<UINT8 *>(state->dc_texture_ram.target()))[BYTE_XOR_LE(t->address + dilated1[t->cd][xt >> 1] + dilated0[t->cd][yt >> 1])];
483   int addrp = t->vqbase + 8*idx + (dilated1[t->cd][xt & 1] + dilated0[t->cd][yt & 1])*2;
484   return cv_565(*(UINT16 *)((reinterpret_cast<UINT8 *>(state->dc_texture_ram.target())) + WORD_XOR_LE(addrp)));
485}
486
487INLINE UINT32 tex_r_4444_n(running_machine &machine, texinfo *t, float x, float y)
488{
489   dc_state *state = machine.driver_data<dc_state>();
490   int xt = ((int)x) & (t->sizex-1);
491   int yt = ((int)y) & (t->sizey-1);
492   int addrp = t->address + (t->stride*yt + xt)*2;
493   return cv_4444z(*(UINT16 *)((reinterpret_cast<UINT8 *>(state->dc_texture_ram.target())) + WORD_XOR_LE(addrp)));
494}
495
496INLINE UINT32 tex_r_4444_tw(running_machine &machine, texinfo *t, float x, float y)
497{
498   dc_state *state = machine.driver_data<dc_state>();
499   int xt = ((int)x) & (t->sizex-1);
500   int yt = ((int)y) & (t->sizey-1);
501   int addrp = t->address + (dilated1[t->cd][xt] + dilated0[t->cd][yt])*2;
502   return cv_4444(*(UINT16 *)((reinterpret_cast<UINT8 *>(state->dc_texture_ram.target())) + WORD_XOR_LE(addrp)));
503}
504
505INLINE UINT32 tex_r_4444_vq(running_machine &machine, texinfo *t, float x, float y)
506{
507   dc_state *state = machine.driver_data<dc_state>();
508   int xt = ((int)x) & (t->sizex-1);
509   int yt = ((int)y) & (t->sizey-1);
510   int idx = (reinterpret_cast<UINT8 *>(state->dc_texture_ram.target()))[BYTE_XOR_LE(t->address + dilated1[t->cd][xt >> 1] + dilated0[t->cd][yt >> 1])];
511   int addrp = t->vqbase + 8*idx + (dilated1[t->cd][xt & 1] + dilated0[t->cd][yt & 1])*2;
512   return cv_4444(*(UINT16 *)((reinterpret_cast<UINT8 *>(state->dc_texture_ram.target())) + WORD_XOR_LE(addrp)));
513}
514
515INLINE UINT32 tex_r_p4_1555_tw(running_machine &machine, texinfo *t, float x, float y)
516{
517   dc_state *state = machine.driver_data<dc_state>();
518   int xt = ((int)x) & (t->sizex-1);
519   int yt = ((int)y) & (t->sizey-1);
520   int off = dilated1[t->cd][xt] + dilated0[t->cd][yt];
521   int addrp = t->address + (off >> 1);
522   int c = ((reinterpret_cast<UINT8 *>(state->dc_texture_ram.target()))[BYTE_XOR_LE(addrp)] >> ((off & 1) << 2)) & 0xf;
523   return cv_1555(state->pvrta_regs[t->palbase + c]);
524}
525
526INLINE UINT32 tex_r_p4_1555_vq(running_machine &machine, texinfo *t, float x, float y)
527{
528   dc_state *state = machine.driver_data<dc_state>();
529   int xt = ((int)x) & (t->sizex-1);
530   int yt = ((int)y) & (t->sizey-1);
531   int idx = (reinterpret_cast<UINT8 *>(state->dc_texture_ram.target()))[BYTE_XOR_LE(t->address + dilated1[t->cd][xt >> 1] + dilated0[t->cd][yt >> 1])];
532   int addrp = t->vqbase + 8*idx + dilated1[t->cd][xt & 1] + dilated0[t->cd][yt & 3];
533   int c = (reinterpret_cast<UINT8 *>(state->dc_texture_ram.target()))[BYTE_XOR_LE(addrp)] & 0xf;
534   return cv_1555(state->pvrta_regs[t->palbase + c]);
535}
536
537INLINE UINT32 tex_r_p4_565_tw(running_machine &machine, texinfo *t, float x, float y)
538{
539   dc_state *state = machine.driver_data<dc_state>();
540   int xt = ((int)x) & (t->sizex-1);
541   int yt = ((int)y) & (t->sizey-1);
542   int off = dilated1[t->cd][xt] + dilated0[t->cd][yt];
543   int addrp = t->address + (off >> 1);
544   int c = ((reinterpret_cast<UINT8 *>(state->dc_texture_ram.target()))[BYTE_XOR_LE(addrp)] >> ((off & 1) << 2)) & 0xf;
545   return cv_565(state->pvrta_regs[t->palbase + c]);
546}
547
548INLINE UINT32 tex_r_p4_565_vq(running_machine &machine, texinfo *t, float x, float y)
549{
550   dc_state *state = machine.driver_data<dc_state>();
551   int xt = ((int)x) & (t->sizex-1);
552   int yt = ((int)y) & (t->sizey-1);
553   int idx = (reinterpret_cast<UINT8 *>(state->dc_texture_ram.target()))[BYTE_XOR_LE(t->address + dilated1[t->cd][xt >> 1] + dilated0[t->cd][yt >> 1])];
554   int addrp = t->vqbase + 8*idx + dilated1[t->cd][xt & 1] + dilated0[t->cd][yt & 3];
555   int c = (reinterpret_cast<UINT8 *>(state->dc_texture_ram.target()))[BYTE_XOR_LE(addrp)] & 0xf;
556   return cv_565(state->pvrta_regs[t->palbase + c]);
557}
558
559INLINE UINT32 tex_r_p4_4444_tw(running_machine &machine, texinfo *t, float x, float y)
560{
561   dc_state *state = machine.driver_data<dc_state>();
562   int xt = ((int)x) & (t->sizex-1);
563   int yt = ((int)y) & (t->sizey-1);
564   int off = dilated1[t->cd][xt] + dilated0[t->cd][yt];
565   int addrp = t->address + (off >> 1);
566   int c = ((reinterpret_cast<UINT8 *>(state->dc_texture_ram.target()))[BYTE_XOR_LE(addrp)] >> ((off & 1) << 2)) & 0xf;
567   return cv_4444(state->pvrta_regs[t->palbase + c]);
568}
569
570INLINE UINT32 tex_r_p4_4444_vq(running_machine &machine, texinfo *t, float x, float y)
571{
572   dc_state *state = machine.driver_data<dc_state>();
573   int xt = ((int)x) & (t->sizex-1);
574   int yt = ((int)y) & (t->sizey-1);
575   int idx = (reinterpret_cast<UINT8 *>(state->dc_texture_ram.target()))[BYTE_XOR_LE(t->address + dilated1[t->cd][xt >> 1] + dilated0[t->cd][yt >> 1])];
576   int addrp = t->vqbase + 8*idx + dilated1[t->cd][xt & 1] + dilated0[t->cd][yt & 3];
577   int c = (reinterpret_cast<UINT8 *>(state->dc_texture_ram.target()))[BYTE_XOR_LE(addrp)] & 0xf;
578   return cv_4444(state->pvrta_regs[t->palbase + c]);
579}
580
581INLINE UINT32 tex_r_p4_8888_tw(running_machine &machine, texinfo *t, float x, float y)
582{
583   dc_state *state = machine.driver_data<dc_state>();
584   int xt = ((int)x) & (t->sizex-1);
585   int yt = ((int)y) & (t->sizey-1);
586   int off = dilated1[t->cd][xt] + dilated0[t->cd][yt];
587   int addrp = t->address + (off >> 1);
588   int c = ((reinterpret_cast<UINT8 *>(state->dc_texture_ram.target()))[BYTE_XOR_LE(addrp)] >> ((off & 1) << 2)) & 0xf;
589   return state->pvrta_regs[t->palbase + c];
590}
591
592INLINE UINT32 tex_r_p4_8888_vq(running_machine &machine, texinfo *t, float x, float y)
593{
594   dc_state *state = machine.driver_data<dc_state>();
595   int xt = ((int)x) & (t->sizex-1);
596   int yt = ((int)y) & (t->sizey-1);
597   int idx = (reinterpret_cast<UINT8 *>(state->dc_texture_ram.target()))[BYTE_XOR_LE(t->address + dilated1[t->cd][xt >> 1] + dilated0[t->cd][yt >> 1])];
598   int addrp = t->vqbase + 8*idx + dilated1[t->cd][xt & 1] + dilated0[t->cd][yt & 3];
599   int c = (reinterpret_cast<UINT8 *>(state->dc_texture_ram.target()))[BYTE_XOR_LE(addrp)] & 0xf;
600   return state->pvrta_regs[t->palbase + c];
601}
602
603INLINE UINT32 tex_r_p8_1555_tw(running_machine &machine, texinfo *t, float x, float y)
604{
605   dc_state *state = machine.driver_data<dc_state>();
606   int xt = ((int)x) & (t->sizex-1);
607   int yt = ((int)y) & (t->sizey-1);
608   int addrp = t->address + dilated1[t->cd][xt] + dilated0[t->cd][yt];
609   int c = (reinterpret_cast<UINT8 *>(state->dc_texture_ram.target()))[BYTE_XOR_LE(addrp)];
610   return cv_1555(state->pvrta_regs[t->palbase + c]);
611}
612
613INLINE UINT32 tex_r_p8_1555_vq(running_machine &machine, texinfo *t, float x, float y)
614{
615   dc_state *state = machine.driver_data<dc_state>();
616   int xt = ((int)x) & (t->sizex-1);
617   int yt = ((int)y) & (t->sizey-1);
618   int idx = (reinterpret_cast<UINT8 *>(state->dc_texture_ram.target()))[BYTE_XOR_LE(t->address + dilated1[t->cd][xt >> 1] + dilated0[t->cd][yt >> 1])];
619   int addrp = t->vqbase + 8*idx + dilated1[t->cd][xt & 1] + dilated0[t->cd][yt & 3];
620   int c = (reinterpret_cast<UINT8 *>(state->dc_texture_ram.target()))[BYTE_XOR_LE(addrp)];
621   return cv_1555(state->pvrta_regs[t->palbase + c]);
622}
623
624INLINE UINT32 tex_r_p8_565_tw(running_machine &machine, texinfo *t, float x, float y)
625{
626   dc_state *state = machine.driver_data<dc_state>();
627   int xt = ((int)x) & (t->sizex-1);
628   int yt = ((int)y) & (t->sizey-1);
629   int addrp = t->address + dilated1[t->cd][xt] + dilated0[t->cd][yt];
630   int c = (reinterpret_cast<UINT8 *>(state->dc_texture_ram.target()))[BYTE_XOR_LE(addrp)];
631   return cv_565(state->pvrta_regs[t->palbase + c]);
632}
633
634INLINE UINT32 tex_r_p8_565_vq(running_machine &machine, texinfo *t, float x, float y)
635{
636   dc_state *state = machine.driver_data<dc_state>();
637   int xt = ((int)x) & (t->sizex-1);
638   int yt = ((int)y) & (t->sizey-1);
639   int idx = (reinterpret_cast<UINT8 *>(state->dc_texture_ram.target()))[BYTE_XOR_LE(t->address + dilated1[t->cd][xt >> 1] + dilated0[t->cd][yt >> 1])];
640   int addrp = t->vqbase + 8*idx + dilated1[t->cd][xt & 1] + dilated0[t->cd][yt & 3];
641   int c = (reinterpret_cast<UINT8 *>(state->dc_texture_ram.target()))[BYTE_XOR_LE(addrp)];
642   return cv_565(state->pvrta_regs[t->palbase + c]);
643}
644
645INLINE UINT32 tex_r_p8_4444_tw(running_machine &machine, texinfo *t, float x, float y)
646{
647   dc_state *state = machine.driver_data<dc_state>();
648   int xt = ((int)x) & (t->sizex-1);
649   int yt = ((int)y) & (t->sizey-1);
650   int addrp = t->address + dilated1[t->cd][xt] + dilated0[t->cd][yt];
651   int c = (reinterpret_cast<UINT8 *>(state->dc_texture_ram.target()))[BYTE_XOR_LE(addrp)];
652   return cv_4444(state->pvrta_regs[t->palbase + c]);
653}
654
655INLINE UINT32 tex_r_p8_4444_vq(running_machine &machine, texinfo *t, float x, float y)
656{
657   dc_state *state = machine.driver_data<dc_state>();
658   int xt = ((int)x) & (t->sizex-1);
659   int yt = ((int)y) & (t->sizey-1);
660   int idx = (reinterpret_cast<UINT8 *>(state->dc_texture_ram.target()))[BYTE_XOR_LE(t->address + dilated1[t->cd][xt >> 1] + dilated0[t->cd][yt >> 1])];
661   int addrp = t->vqbase + 8*idx + dilated1[t->cd][xt & 1] + dilated0[t->cd][yt & 3];
662   int c = (reinterpret_cast<UINT8 *>(state->dc_texture_ram.target()))[BYTE_XOR_LE(addrp)];
663   return cv_4444(state->pvrta_regs[t->palbase + c]);
664}
665
666INLINE UINT32 tex_r_p8_8888_tw(running_machine &machine, texinfo *t, float x, float y)
667{
668   dc_state *state = machine.driver_data<dc_state>();
669   int xt = ((int)x) & (t->sizex-1);
670   int yt = ((int)y) & (t->sizey-1);
671   int addrp = t->address + dilated1[t->cd][xt] + dilated0[t->cd][yt];
672   int c = (reinterpret_cast<UINT8 *>(state->dc_texture_ram.target()))[BYTE_XOR_LE(addrp)];
673   return state->pvrta_regs[t->palbase + c];
674}
675
676INLINE UINT32 tex_r_p8_8888_vq(running_machine &machine, texinfo *t, float x, float y)
677{
678   dc_state *state = machine.driver_data<dc_state>();
679   int xt = ((int)x) & (t->sizex-1);
680   int yt = ((int)y) & (t->sizey-1);
681   int idx = (reinterpret_cast<UINT8 *>(state->dc_texture_ram.target()))[BYTE_XOR_LE(t->address + dilated1[t->cd][xt >> 1] + dilated0[t->cd][yt >> 1])];
682   int addrp = t->vqbase + 8*idx + dilated1[t->cd][xt & 1] + dilated0[t->cd][yt & 3];
683   int c = (reinterpret_cast<UINT8 *>(state->dc_texture_ram.target()))[BYTE_XOR_LE(addrp)];
684   return state->pvrta_regs[t->palbase + c];
685}
686
687
688INLINE UINT32 tex_r_default(running_machine &machine, texinfo *t, float x, float y)
689{
690   return ((int)x ^ (int)y) & 4 ? 0xffffff00 : 0xff0000ff;
691}
692
693static void tex_get_info(running_machine &machine,texinfo *t, pvrta_state *sa)
694{
695   dc_state *state = machine.driver_data<dc_state>();
696   int miptype = 0;
697
698   t->textured    = sa->texture;
699
700   // not textured, abort.
701   if (!t->textured) return;
702
703   t->address     = sa->textureaddress;
704   t->pf          = sa->pixelformat;
705   t->palette     = 0;
706
707   t->mode = (sa->vqcompressed<<1);
708
709   // scanorder is ignored for palettized textures (palettized textures are ALWAYS twiddled)
710   // (the same bits are used for palette select instead)
711   if ((t->pf == 5) || (t->pf == 6))
712   {
713      t->palette = sa->paletteselector;
714   }
715   else
716   {
717      t->mode |= sa->scanorder;
718   }
719
720   /* When scan order is 1 (non-twiddled) mipmap is ignored */
721   t->mipmapped  = t->mode & 1 ? 0 : sa->mipmapped;
722
723   // Mipmapped textures are always square, ignore v size
724   if (t->mipmapped)
725   {
726      t->sizes = (sa->texturesizes & 0x38) | ((sa->texturesizes & 0x38) >> 3);
727   }
728   else
729   {
730      t->sizes = sa->texturesizes;
731   }
732
733   t->sizex = 1 << (3+((t->sizes >> 3) & 7));
734   t->sizey = 1 << (3+(t->sizes & 7));
735
736
737   /* Stride select is used only in the non-twiddled case */
738   t->stride = (t->mode & 1) && sa->strideselect ? (state->pvrta_regs[TEXT_CONTROL] & 0x1f) << 5 : t->sizex;
739
740   t->blend_mode  = sa->blend_mode;
741   t->filter_mode = sa->filtermode;
742   t->flip_u      = (sa->flipuv >> 1) & 1;
743   t->flip_v      = sa->flipuv & 1;
744
745   t->r = tex_r_default;
746   t->cd = dilatechose[t->sizes];
747   t->palbase = 0;
748   t->vqbase = t->address;
749   t->blend = sa->use_alpha ? blend_functions[t->blend_mode] : bl10;
750
751   //  fprintf(stderr, "tex %d %d %d %d\n", t->pf, t->mode, state->pvrta_regs[PAL_RAM_CTRL], t->mipmapped);
752
753   switch(t->pf) {
754   case 0: // 1555
755      switch(t->mode) {
756      case 0:  t->r = tex_r_1555_tw; miptype = 2; break;
757      case 1:  t->r = tex_r_1555_n;  miptype = 2; break;
758      case 2:
759      case 3:  t->r = tex_r_1555_vq; miptype = 3; t->address += 0x800; break;
760
761      default:
762         //
763         break;
764      }
765      break;
766
767   case 1: // 565
768      switch(t->mode) {
769      case 0:  t->r = tex_r_565_tw; miptype = 2; break;
770      case 1:  t->r = tex_r_565_n;  miptype = 2; break;
771      case 2:
772      case 3:  t->r = tex_r_565_vq; miptype = 3; t->address += 0x800; break;
773
774      default:
775         //
776         break;
777      }
778      break;
779
780   case 2: // 4444
781      switch(t->mode) {
782      case 0:  t->r = tex_r_4444_tw; miptype = 2; break;
783      case 1:  t->r = tex_r_4444_n;  miptype = 2; break;
784      case 2:
785      case 3:  t->r = tex_r_4444_vq; miptype = 3; t->address += 0x800; break;
786
787      default:
788         //
789         break;
790      }
791      break;
792
793   case 3: // yuv422
794      switch(t->mode) {
795      case 0:  /*t->r = tex_r_yuv_tw*/; miptype = -1; break;
796      case 1:  t->r = tex_r_yuv_n; miptype = -1; break;
797      default: /*t->r = tex_r_yuv_vq*/; miptype = -1; break;
798      }
799      break;
800
801   case 4: // bumpmap
802      break;
803
804   case 5: // 4bpp palette
805      t->palbase = 0x400 | ((t->palette & 0x3f) << 4);
806      switch(t->mode) {
807      case 0: case 1:
808         miptype = 0;
809
810         switch(state->pvrta_regs[PAL_RAM_CTRL]) {
811         case 0: t->r = tex_r_p4_1555_tw; break;
812         case 1: t->r = tex_r_p4_565_tw;  break;
813         case 2: t->r = tex_r_p4_4444_tw; break;
814         case 3: t->r = tex_r_p4_8888_tw; break;
815         }
816         break;
817      case 2: case 3:
818         miptype = 3; // ?
819         switch(state->pvrta_regs[PAL_RAM_CTRL]) {
820         case 0: t->r = tex_r_p4_1555_vq; t->address += 0x800; break;
821         case 1: t->r = tex_r_p4_565_vq;  t->address += 0x800; break;
822         case 2: t->r = tex_r_p4_4444_vq; t->address += 0x800; break;
823         case 3: t->r = tex_r_p4_8888_vq; t->address += 0x800; break;
824         }
825         break;
826
827      default:
828         //
829         break;
830      }
831      break;
832
833   case 6: // 8bpp palette
834      t->palbase = 0x400 | ((t->palette & 0x30) << 4);
835      switch(t->mode) {
836      case 0: case 1:
837         miptype = 1;
838
839         switch(state->pvrta_regs[PAL_RAM_CTRL]) {
840         case 0: t->r = tex_r_p8_1555_tw; break;
841         case 1: t->r = tex_r_p8_565_tw; break;
842         case 2: t->r = tex_r_p8_4444_tw; break;
843         case 3: t->r = tex_r_p8_8888_tw; break;
844         }
845         break;
846      case 2: case 3:
847         miptype = 3; // ?
848         switch(state->pvrta_regs[PAL_RAM_CTRL]) {
849         case 0: t->r = tex_r_p8_1555_vq; t->address += 0x800; break;
850         case 1: t->r = tex_r_p8_565_vq;  t->address += 0x800; break;
851         case 2: t->r = tex_r_p8_4444_vq; t->address += 0x800; break;
852         case 3: t->r = tex_r_p8_8888_vq; t->address += 0x800; break;
853         }
854         break;
855
856      default:
857         //
858         break;
859      }
860      break;
861
862   case 9: // reserved
863      break;
864   }
865
866   if (t->mipmapped)
867   {
868      // full offset tables for reference,
869      // we don't do mipmapping, so don't use anything < 8x8
870      // first table is half-bytes
871
872      // 4BPP palette textures
873      // Texture size _4-bit_ offset value for starting address
874      // 1x1          0x00003
875      // 2x2          0x00004
876      // 4x4          0x00008
877      // 8x8          0x00018
878      // 16x16        0x00058
879      // 32x32        0x00158
880      // 64x64        0x00558
881      // 128x128      0x01558
882      // 256x256      0x05558
883      // 512x512      0x15558
884      // 1024x1024    0x55558
885
886      // 8BPP palette textures
887      // Texture size Byte offset value for starting address
888      // 1x1          0x00003
889      // 2x2          0x00004
890      // 4x4          0x00008
891      // 8x8          0x00018
892      // 16x16        0x00058
893      // 32x32        0x00158
894      // 64x64        0x00558
895      // 128x128      0x01558
896      // 256x256      0x05558
897      // 512x512      0x15558
898      // 1024x1024    0x55558
899
900      // Non-palette textures
901      // Texture size Byte offset value for starting address
902      // 1x1          0x00006
903      // 2x2          0x00008
904      // 4x4          0x00010
905      // 8x8          0x00030
906      // 16x16        0x000B0
907      // 32x32        0x002B0
908      // 64x64        0x00AB0
909      // 128x128      0x02AB0
910      // 256x256      0x0AAB0
911      // 512x512      0x2AAB0
912      // 1024x1024    0xAAAB0
913
914      // VQ textures
915      // Texture size Byte offset value for starting address
916      // 1x1          0x00000
917      // 2x2          0x00001
918      // 4x4          0x00002
919      // 8x8          0x00006
920      // 16x16        0x00016
921      // 32x32        0x00056
922      // 64x64        0x00156
923      // 128x128      0x00556
924      // 256x256      0x01556
925      // 512x512      0x05556
926      // 1024x1024    0x15556
927
928      static const int mipmap_4_8_offset[8] = { 0x00018, 0x00058, 0x00158, 0x00558, 0x01558, 0x05558, 0x15558, 0x55558 };  // 4bpp (4bit offset) / 8bpp (8bit offset)
929      static const int mipmap_np_offset[8] =  { 0x00030, 0x000B0, 0x002B0, 0x00AB0, 0x02AB0, 0x0AAB0, 0x2AAB0, 0xAAAB0 };  // nonpalette textures
930      static const int mipmap_vq_offset[8] =  { 0x00006, 0x00016, 0x00056, 0x00156, 0x00556, 0x01556, 0x05556, 0x15556 }; // vq textures
931
932      switch (miptype)
933      {
934         case 0: // 4bpp
935            //printf("4bpp\n");
936            t->address += mipmap_4_8_offset[(t->sizes)&7]>>1;
937            break;
938
939         case 1: // 8bpp
940            //printf("8bpp\n");
941            t->address += mipmap_4_8_offset[(t->sizes)&7];
942            break;
943
944         case 2: // nonpalette
945            //printf("np\n");
946            t->address += mipmap_np_offset[(t->sizes)&7];
947            break;
948
949         case 3: // vq
950            //printf("vq\n");
951            t->address += mipmap_vq_offset[(t->sizes)&7];
952            break;
953      }
954   }
955
956}
957
958// register decode helper
959INLINE int decode_reg_64(UINT32 offset, UINT64 mem_mask, UINT64 *shift)
960{
961   int reg = offset * 2;
962
963   *shift = 0;
964
965   // non 32-bit accesses have not yet been seen here, we need to know when they are
966   if ((mem_mask != U64(0xffffffff00000000)) && (mem_mask != U64(0x00000000ffffffff)))
967   {
968      /*assume to return the lower 32-bits ONLY*/
969      return reg & 0xffffffff;
970   }
971
972   if (mem_mask == U64(0xffffffff00000000))
973   {
974      reg++;
975      *shift = 32;
976   }
977
978   return reg;
979}
980
981READ64_HANDLER( pvr_ta_r )
982{
983   dc_state *state = space.machine().driver_data<dc_state>();
984   int reg;
985   UINT64 shift;
986
987   reg = decode_reg_64(offset, mem_mask, &shift);
988
989   switch (reg)
990   {
991   case SPG_STATUS:
992      {
993         UINT8 fieldnum,vsync,hsync,blank;
994
995         fieldnum = (space.machine().primary_screen->frame_number() & 1) ? 1 : 0;
996
997         vsync = space.machine().primary_screen->vblank() ? 1 : 0;
998         if(spg_vsync_pol) { vsync^=1; }
999
1000         hsync = space.machine().primary_screen->hblank() ? 1 : 0;
1001         if(spg_hsync_pol) { hsync^=1; }
1002
1003         /* FIXME: following is just a wild guess */
1004         blank = (space.machine().primary_screen->vblank() | space.machine().primary_screen->hblank()) ? 0 : 1;
1005         if(spg_blank_pol) { blank^=1; }
1006
1007         state->pvrta_regs[reg] = (vsync << 13) | (hsync << 12) | (blank << 11) | (fieldnum << 10) | (space.machine().primary_screen->vpos() & 0x3ff);
1008         break;
1009      }
1010   case SPG_TRIGGER_POS:
1011      printf("Warning: read at h/v counter ext latches\n");
1012      break;
1013   case TA_LIST_INIT:
1014      return 0; //bit 31 always return 0, a probable left-over in Crazy Taxi reads this and discards the read (?)
1015   }
1016
1017   #if DEBUG_PVRTA_REGS
1018   if (reg != 0x43)
1019      mame_printf_verbose("PVRTA: [%08x] read %x @ %x (reg %x), mask %" I64FMT "x (PC=%x)\n", 0x5f8000+reg*4, state->pvrta_regs[reg], offset, reg, mem_mask, space.device().safe_pc());
1020   #endif
1021   return (UINT64)state->pvrta_regs[reg] << shift;
1022}
1023
1024WRITE64_HANDLER( pvr_ta_w )
1025{
1026   dc_state *state = space.machine().driver_data<dc_state>();
1027   int reg;
1028   UINT64 shift;
1029   UINT32 dat;
1030   UINT32 sizera,offsetra;
1031   int a;
1032   int sanitycount;
1033
1034   reg = decode_reg_64(offset, mem_mask, &shift);
1035   dat = (UINT32)(data >> shift);
1036   //old = state->pvrta_regs[reg];
1037
1038   // Dreamcast BIOS attempts to set PVRID to zero and then dies
1039   // if it succeeds.  Don't allow.
1040   if ((reg != PVRID) && (reg != REVISION))
1041   {
1042      state->pvrta_regs[reg] = dat; // 5f8000+reg*4=dat
1043   }
1044
1045   switch (reg)
1046   {
1047   case SOFTRESET:
1048      if (dat & 1)
1049      {
1050         #if DEBUG_PVRTA
1051         mame_printf_verbose("pvr_ta_w:  TA soft reset\n");
1052         #endif
1053         state_ta.listtype_used=0;
1054      }
1055      if (dat & 2)
1056      {
1057         #if DEBUG_PVRTA
1058         mame_printf_verbose("pvr_ta_w:  Core Pipeline soft reset\n");
1059         #endif
1060         if (state_ta.start_render_received == 1)
1061         {
1062            for (a=0;a < NUM_BUFFERS;a++)
1063               if (state_ta.grab[a].busy == 1)
1064                  state_ta.grab[a].busy = 0;
1065            state_ta.start_render_received = 0;
1066         }
1067      }
1068      if (dat & 4)
1069      {
1070         #if DEBUG_PVRTA
1071         mame_printf_verbose("pvr_ta_w:  sdram I/F soft reset\n");
1072         #endif
1073      }
1074      break;
1075   case STARTRENDER:
1076      g_profiler.start(PROFILER_USER1);
1077      #if DEBUG_PVRTA
1078      mame_printf_verbose("Start Render Received:\n");
1079      mame_printf_verbose("  Region Array at %08x\n",state->pvrta_regs[REGION_BASE]);
1080      mame_printf_verbose("  ISP/TSP Parameters at %08x\n",state->pvrta_regs[PARAM_BASE]);
1081
1082      #endif
1083      // select buffer to draw using PARAM_BASE
1084      for (a=0;a < NUM_BUFFERS;a++)
1085      {
1086         if ((state_ta.grab[a].ispbase == state->pvrta_regs[PARAM_BASE]) && (state_ta.grab[a].valid == 1) && (state_ta.grab[a].busy == 0))
1087         {
1088            state_ta.grab[a].busy = 1;
1089            state_ta.renderselect = a;
1090            state_ta.start_render_received=1;
1091
1092
1093            state_ta.grab[a].fbwsof1=state->pvrta_regs[FB_W_SOF1];
1094            state_ta.grab[a].fbwsof2=state->pvrta_regs[FB_W_SOF2];
1095
1096            rectangle clip(0, 1023, 0, 1023);
1097
1098            // we've got a request to draw, so, draw to the accumulation buffer!
1099            // this should really be done for each tile!
1100            render_to_accumulation_buffer(space.machine(),*fake_accumulationbuffer_bitmap,clip);
1101
1102            state->endofrender_timer_isp->adjust(attotime::from_usec(4000) ); // hack, make sure render takes some amount of time
1103
1104            /* copy the tiles to the framebuffer (really the rendering should be in this loop too) */
1105            if (state->pvrta_regs[FPU_PARAM_CFG] & 0x200000)
1106               sizera=6;
1107            else
1108               sizera=5;
1109            offsetra=state->pvrta_regs[REGION_BASE];
1110
1111            //printf("base is %08x\n", offsetra);
1112
1113            // sanity
1114            sanitycount = 0;
1115            for (;;)
1116            {
1117               UINT32 st[6];
1118
1119               st[0]=space.read_dword((0x05000000+offsetra));
1120               st[1]=space.read_dword((0x05000004+offsetra)); // Opaque List Pointer
1121               st[2]=space.read_dword((0x05000008+offsetra)); // Opaque Modifier Volume List Pointer
1122               st[3]=space.read_dword((0x0500000c+offsetra)); // Translucent List Pointer
1123               st[4]=space.read_dword((0x05000010+offsetra)); // Translucent Modifier Volume List Pointer
1124
1125               if (sizera == 6)
1126               {
1127                  st[5] = space.read_dword((0x05000014+offsetra)); // Punch Through List Pointer
1128                  offsetra+=0x18;
1129               }
1130               else
1131               {
1132                  st[5] = 0;
1133                  offsetra+=0x14;
1134               }
1135
1136               {
1137                  int x = ((st[0]&0x000000fc)>>2)*32;
1138                  int y = ((st[0]&0x00003f00)>>8)*32;
1139                  //printf("tiledata %08x %d %d - %08x %08x %08x %08x %08x\n",st[0],x,y,st[1],st[2],st[3],st[4],st[5]);
1140
1141                  // should render to the accumulation buffer here using pointers we filled in when processing the data
1142                  // sent to the TA.  HOWEVER, we don't process the TA data and create the real format object lists, so
1143                  // instead just use these co-ordinates to copy data from our fake full-screnen accumnulation buffer into
1144                  // the framebuffer
1145
1146                  pvr_accumulationbuffer_to_framebuffer(space, x,y);
1147               }
1148
1149               if (st[0] & 0x80000000)
1150                  break;
1151
1152               // prevent infinite loop if asked to process invalid data
1153               if(sanitycount>2000)
1154                  break;
1155            }
1156
1157
1158
1159
1160            break;
1161         }
1162      }
1163      if (a != NUM_BUFFERS)
1164         break;
1165      assert_always(0, "TA grabber error A!\n");
1166      break;
1167   case TA_LIST_INIT:
1168      if(dat & 0x80000000)
1169      {
1170         state_ta.tafifo_pos=0;
1171         state_ta.tafifo_mask=7;
1172         state_ta.tafifo_vertexwords=8;
1173         state_ta.tafifo_listtype= -1;
1174   #if DEBUG_PVRTA
1175         mame_printf_verbose("TA_OL_BASE       %08x TA_OL_LIMIT  %08x\n", state->pvrta_regs[TA_OL_BASE], state->pvrta_regs[TA_OL_LIMIT]);
1176         mame_printf_verbose("TA_ISP_BASE      %08x TA_ISP_LIMIT %08x\n", state->pvrta_regs[TA_ISP_BASE], state->pvrta_regs[TA_ISP_LIMIT]);
1177         mame_printf_verbose("TA_ALLOC_CTRL    %08x\n", state->pvrta_regs[TA_ALLOC_CTRL]);
1178         mame_printf_verbose("TA_NEXT_OPB_INIT %08x\n", state->pvrta_regs[TA_NEXT_OPB_INIT]);
1179   #endif
1180         state->pvrta_regs[TA_NEXT_OPB] = state->pvrta_regs[TA_NEXT_OPB_INIT];
1181         state->pvrta_regs[TA_ITP_CURRENT] = state->pvrta_regs[TA_ISP_BASE];
1182         state_ta.alloc_ctrl_OPB_Mode = state->pvrta_regs[TA_ALLOC_CTRL] & 0x100000; // 0 up 1 down
1183         state_ta.alloc_ctrl_PT_OPB = (4 << ((state->pvrta_regs[TA_ALLOC_CTRL] >> 16) & 3)) & 0x38; // number of 32 bit words (0,8,16,32)
1184         state_ta.alloc_ctrl_TM_OPB = (4 << ((state->pvrta_regs[TA_ALLOC_CTRL] >> 12) & 3)) & 0x38;
1185         state_ta.alloc_ctrl_T_OPB = (4 << ((state->pvrta_regs[TA_ALLOC_CTRL] >> 8) & 3)) & 0x38;
1186         state_ta.alloc_ctrl_OM_OPB = (4 << ((state->pvrta_regs[TA_ALLOC_CTRL] >> 4) & 3)) & 0x38;
1187         state_ta.alloc_ctrl_O_OPB = (4 << ((state->pvrta_regs[TA_ALLOC_CTRL] >> 0) & 3)) & 0x38;
1188         state_ta.listtype_used |= (1+4);
1189         // use TA_ISP_BASE and select buffer for grab data
1190         state_ta.grabsel = -1;
1191         // try to find already used buffer but not busy
1192         for (a=0;a < NUM_BUFFERS;a++)
1193         {
1194            if ((state_ta.grab[a].ispbase == state->pvrta_regs[TA_ISP_BASE]) && (state_ta.grab[a].busy == 0) && (state_ta.grab[a].valid == 1))
1195            {
1196               state_ta.grabsel=a;
1197               break;
1198            }
1199         }
1200         // try a buffer not used yet
1201         if (state_ta.grabsel < 0)
1202         {
1203            for (a=0;a < NUM_BUFFERS;a++)
1204            {
1205               if (state_ta.grab[a].valid == 0)
1206               {
1207                  state_ta.grabsel=a;
1208                  break;
1209               }
1210            }
1211         }
1212         // find a non busy buffer starting from the last one used
1213         if (state_ta.grabsel < 0)
1214         {
1215            for (a=0;a < 3;a++)
1216            {
1217               if (state_ta.grab[(state_ta.grabsellast+1+a) & 3].busy == 0)
1218               {
1219                  state_ta.grabsel=a;
1220                  break;
1221               }
1222            }
1223         }
1224         if (state_ta.grabsel < 0)
1225            assert_always(0, "TA grabber error B!\n");
1226         state_ta.grabsellast=state_ta.grabsel;
1227         state_ta.grab[state_ta.grabsel].ispbase=state->pvrta_regs[TA_ISP_BASE];
1228         state_ta.grab[state_ta.grabsel].busy=0;
1229         state_ta.grab[state_ta.grabsel].valid=1;
1230         state_ta.grab[state_ta.grabsel].verts_size=0;
1231         state_ta.grab[state_ta.grabsel].strips_size=0;
1232
1233         g_profiler.stop();
1234      }
1235      break;
1236//#define TA_YUV_TEX_BASE       ((0x005f8148-0x005f8000)/4)
1237   case TA_YUV_TEX_BASE:
1238      printf("TA_YUV_TEX_BASE initialized to %08x\n", dat);
1239
1240      // hack, this interrupt is generated after transfering a set amount of data
1241      //state->dc_sysctrl_regs[SB_ISTNRM] |= IST_EOXFER_YUV;
1242      //dc_update_interrupt_status(space.machine());
1243
1244      break;
1245   case TA_YUV_TEX_CTRL:
1246      printf("TA_YUV_TEX_CTRL initialized to %08x\n", dat);
1247      break;
1248
1249   case SPG_VBLANK_INT:
1250      /* clear pending irqs and modify them with the updated ones */
1251      state->vbin_timer->adjust(attotime::never);
1252      state->vbout_timer->adjust(attotime::never);
1253
1254      state->vbin_timer->adjust(space.machine().primary_screen->time_until_pos(spg_vblank_in_irq_line_num));
1255      state->vbout_timer->adjust(space.machine().primary_screen->time_until_pos(spg_vblank_out_irq_line_num));
1256      break;
1257   /* TODO: timer adjust for SPG_HBLANK_INT too */
1258   case TA_LIST_CONT:
1259   #if DEBUG_PVRTA
1260      mame_printf_verbose("List continuation processing\n");
1261   #endif
1262      if(dat & 0x80000000)
1263      {
1264         state_ta.tafifo_listtype= -1; // no list being received
1265         state_ta.listtype_used |= (1+4);
1266      }
1267      break;
1268   case SPG_VBLANK:
1269   case SPG_HBLANK:
1270   case SPG_LOAD:
1271   case VO_STARTX:
1272   case VO_STARTY:
1273      {
1274         rectangle visarea = space.machine().primary_screen->visible_area();
1275         /* FIXME: right visible area calculations aren't known yet*/
1276         visarea.min_x = 0;
1277         visarea.max_x = ((spg_hbstart - spg_hbend - vo_horz_start_pos) <= 0x180 ? 320 : 640) - 1;
1278         visarea.min_y = 0;
1279         visarea.max_y = ((spg_vbstart - spg_vbend - vo_vert_start_pos_f1) <= 0x100 ? 240 : 480) - 1;
1280
1281
1282         space.machine().primary_screen->configure(spg_hbstart, spg_vbstart, visarea, space.machine().primary_screen->frame_period().attoseconds );
1283      }
1284      break;
1285   }
1286
1287   #if DEBUG_PVRTA_REGS
1288   if ((reg != 0x14) && (reg != 0x15))
1289      mame_printf_verbose("PVRTA: [%08x=%x] write %" I64FMT "x to %x (reg %x %x), mask %" I64FMT "x\n", 0x5f8000+reg*4, dat, data>>shift, offset, reg, (reg*4)+0x8000, mem_mask);
1290   #endif
1291}
1292
1293TIMER_CALLBACK_MEMBER(dc_state::transfer_opaque_list_irq)
1294{
1295   dc_sysctrl_regs[SB_ISTNRM] |= IST_EOXFER_OPLST;
1296   dc_update_interrupt_status();
1297}
1298
1299TIMER_CALLBACK_MEMBER(dc_state::transfer_opaque_modifier_volume_list_irq)
1300{
1301   dc_sysctrl_regs[SB_ISTNRM] |= IST_EOXFER_OPMV;
1302   dc_update_interrupt_status();
1303}
1304
1305TIMER_CALLBACK_MEMBER(dc_state::transfer_translucent_list_irq)
1306{
1307   dc_sysctrl_regs[SB_ISTNRM] |= IST_EOXFER_TRLST;
1308   dc_update_interrupt_status();
1309}
1310
1311TIMER_CALLBACK_MEMBER(dc_state::transfer_translucent_modifier_volume_list_irq)
1312{
1313   dc_sysctrl_regs[SB_ISTNRM] |= IST_EOXFER_TRMV;
1314   dc_update_interrupt_status();
1315}
1316
1317TIMER_CALLBACK_MEMBER(dc_state::transfer_punch_through_list_irq)
1318{
1319   dc_sysctrl_regs[SB_ISTNRM] |= (1 << 21);
1320   dc_update_interrupt_status();
1321}
1322
1323static void process_ta_fifo(running_machine& machine)
1324{
1325   dc_state *state = machine.driver_data<dc_state>();
1326
1327   /* first byte in the buffer is the Parameter Control Word
1328
1329    pppp pppp gggg gggg oooo oooo oooo oooo
1330
1331    p = para control
1332    g = group control
1333    o = object control
1334
1335   */
1336
1337   receiveddata *rd = &state_ta.grab[state_ta.grabsel];
1338
1339   // Para Control
1340   state_ta.paracontrol=(state->tafifo_buff[0] >> 24) & 0xff;
1341   // 0 end of list
1342   // 1 user tile clip
1343   // 2 object list set
1344   // 3 reserved
1345   // 4 polygon/modifier volume
1346   // 5 sprite
1347   // 6 reserved
1348   // 7 vertex
1349   state_ta.paratype=(state_ta.paracontrol >> 5) & 7;
1350   state_ta.endofstrip=(state_ta.paracontrol >> 4) & 1;
1351   state_ta.listtype=(state_ta.paracontrol >> 0) & 7;
1352   if ((state_ta.paratype >= 4) && (state_ta.paratype <= 6))
1353   {
1354      state_ta.global_paratype = state_ta.paratype;
1355      // Group Control
1356      state_ta.groupcontrol=(state->tafifo_buff[0] >> 16) & 0xff;
1357      state_ta.groupen=(state_ta.groupcontrol >> 7) & 1;
1358      state_ta.striplen=(state_ta.groupcontrol >> 2) & 3;
1359      state_ta.userclip=(state_ta.groupcontrol >> 0) & 3;
1360      // Obj Control
1361      state_ta.objcontrol=(state->tafifo_buff[0] >> 0) & 0xffff;
1362      state_ta.shadow=(state_ta.objcontrol >> 7) & 1;
1363      state_ta.volume=(state_ta.objcontrol >> 6) & 1;
1364      state_ta.coltype=(state_ta.objcontrol >> 4) & 3;
1365      state_ta.texture=(state_ta.objcontrol >> 3) & 1;
1366      state_ta.offfset=(state_ta.objcontrol >> 2) & 1;
1367      state_ta.gouraud=(state_ta.objcontrol >> 1) & 1;
1368      state_ta.uv16bit=(state_ta.objcontrol >> 0) & 1;
1369   }
1370
1371   // check if we need 8 words more
1372   if (state_ta.tafifo_mask == 7)
1373   {
1374      state_ta.parameterconfig = pvr_parameterconfig[state_ta.objcontrol & 0x3d];
1375      // decide number of words per vertex
1376      if (state_ta.paratype == 7)
1377      {
1378         if ((state_ta.global_paratype == 5) || (state_ta.tafifo_listtype == 1) || (state_ta.tafifo_listtype == 3))
1379            state_ta.tafifo_vertexwords = 16;
1380         if (state_ta.tafifo_vertexwords == 16)
1381         {
1382            state_ta.tafifo_mask = 15;
1383            state_ta.tafifo_pos = 8;
1384            return;
1385         }
1386      }
1387      // decide number of words when not a vertex
1388      state_ta.tafifo_vertexwords=pvr_wordsvertex[state_ta.parameterconfig];
1389      if ((state_ta.paratype == 4) && ((state_ta.listtype != 1) && (state_ta.listtype != 3)))
1390         if (pvr_wordspolygon[state_ta.parameterconfig] == 16)
1391         {
1392            state_ta.tafifo_mask = 15;
1393            state_ta.tafifo_pos = 8;
1394            return;
1395         }
1396   }
1397   state_ta.tafifo_mask = 7;
1398
1399   // now we heve all the needed words
1400   // here we should generate the data for the various tiles
1401   // for now, just interpret their meaning
1402   if (state_ta.paratype == 0)
1403   { // end of list
1404      #if DEBUG_PVRDLIST
1405      mame_printf_verbose("Para Type 0 End of List\n");
1406      #endif
1407      /* Process transfer FIFO done irqs here */
1408      /* FIXME: timing of these */
1409      switch (state_ta.tafifo_listtype)
1410      {
1411      case 0: machine.scheduler().timer_set(attotime::from_usec(100), timer_expired_delegate(FUNC(dc_state::transfer_opaque_list_irq),state)); break;
1412      case 1: machine.scheduler().timer_set(attotime::from_usec(100), timer_expired_delegate(FUNC(dc_state::transfer_opaque_modifier_volume_list_irq),state)); break;
1413      case 2: machine.scheduler().timer_set(attotime::from_usec(100), timer_expired_delegate(FUNC(dc_state::transfer_translucent_list_irq),state)); break;
1414      case 3: machine.scheduler().timer_set(attotime::from_usec(100), timer_expired_delegate(FUNC(dc_state::transfer_translucent_modifier_volume_list_irq),state)); break;
1415      case 4: machine.scheduler().timer_set(attotime::from_usec(100), timer_expired_delegate(FUNC(dc_state::transfer_punch_through_list_irq),state)); break;
1416      }
1417      state_ta.tafifo_listtype= -1; // no list being received
1418      state_ta.listtype_used |= (2+8);
1419   }
1420   else if (state_ta.paratype == 1)
1421   { // user tile clip
1422      #if DEBUG_PVRDLIST
1423      mame_printf_verbose("Para Type 1 User Tile Clip\n");
1424      mame_printf_verbose(" (%d , %d)-(%d , %d)\n", state->tafifo_buff[4], state->tafifo_buff[5], state->tafifo_buff[6], state->tafifo_buff[7]);
1425      #endif
1426   }
1427   else if (state_ta.paratype == 2)
1428   { // object list set
1429      #if DEBUG_PVRDLIST
1430      mame_printf_verbose("Para Type 2 Object List Set at %08x\n", state->tafifo_buff[1]);
1431      mame_printf_verbose(" (%d , %d)-(%d , %d)\n", state->tafifo_buff[4], state->tafifo_buff[5], state->tafifo_buff[6], state->tafifo_buff[7]);
1432      #endif
1433   }
1434   else if (state_ta.paratype == 3)
1435   {
1436      #if DEBUG_PVRDLIST
1437      mame_printf_verbose("Para Type %x Unknown!\n", state->tafifo_buff[0]);
1438      #endif
1439   }
1440   else
1441   { // global parameter or vertex parameter
1442      #if DEBUG_PVRDLIST
1443      mame_printf_verbose("Para Type %d", state_ta.paratype);
1444      if (state_ta.paratype == 7)
1445         mame_printf_verbose(" End of Strip %d", state_ta.endofstrip);
1446      if (state_ta.listtype_used & 3)
1447         mame_printf_verbose(" List Type %d", state_ta.listtype);
1448      mame_printf_verbose("\n");
1449      #endif
1450
1451      // set type of list currently being received
1452      if ((state_ta.paratype == 4) || (state_ta.paratype == 5) || (state_ta.paratype == 6))
1453      {
1454         if (state_ta.tafifo_listtype < 0)
1455         {
1456            state_ta.tafifo_listtype = state_ta.listtype;
1457         }
1458      }
1459      state_ta.listtype_used = state_ta.listtype_used ^ (state_ta.listtype_used & 3);
1460
1461      if ((state_ta.paratype == 4) || (state_ta.paratype == 5))
1462      { // quad or polygon
1463         state_ta.depthcomparemode=(state->tafifo_buff[1] >> 29) & 7;
1464         state_ta.cullingmode=(state->tafifo_buff[1] >> 27) & 3;
1465         state_ta.zwritedisable=(state->tafifo_buff[1] >> 26) & 1;
1466         state_ta.cachebypass=(state->tafifo_buff[1] >> 21) & 1;
1467         state_ta.dcalcctrl=(state->tafifo_buff[1] >> 20) & 1;
1468         state_ta.volumeinstruction=(state->tafifo_buff[1] >> 29) & 7;
1469
1470         //state_ta.textureusize=1 << (3+((state->tafifo_buff[2] >> 3) & 7));
1471         //state_ta.texturevsize=1 << (3+(state->tafifo_buff[2] & 7));
1472         state_ta.texturesizes=state->tafifo_buff[2] & 0x3f;
1473         state_ta.blend_mode = state->tafifo_buff[2] >> 26;
1474         state_ta.srcselect=(state->tafifo_buff[2] >> 25) & 1;
1475         state_ta.dstselect=(state->tafifo_buff[2] >> 24) & 1;
1476         state_ta.fogcontrol=(state->tafifo_buff[2] >> 22) & 3;
1477         state_ta.colorclamp=(state->tafifo_buff[2] >> 21) & 1;
1478         state_ta.use_alpha = (state->tafifo_buff[2] >> 20) & 1;
1479         state_ta.ignoretexalpha=(state->tafifo_buff[2] >> 19) & 1;
1480         state_ta.flipuv=(state->tafifo_buff[2] >> 17) & 3;
1481         state_ta.clampuv=(state->tafifo_buff[2] >> 15) & 3;
1482         state_ta.filtermode=(state->tafifo_buff[2] >> 13) & 3;
1483         state_ta.sstexture=(state->tafifo_buff[2] >> 12) & 1;
1484         state_ta.mmdadjust=(state->tafifo_buff[2] >> 8) & 1;
1485         state_ta.tsinstruction=(state->tafifo_buff[2] >> 6) & 3;
1486         if (state_ta.texture == 1)
1487         {
1488            state_ta.textureaddress=(state->tafifo_buff[3] & 0x1FFFFF) << 3;
1489            state_ta.scanorder=(state->tafifo_buff[3] >> 26) & 1;
1490            state_ta.pixelformat=(state->tafifo_buff[3] >> 27) & 7;
1491            state_ta.mipmapped=(state->tafifo_buff[3] >> 31) & 1;
1492            state_ta.vqcompressed=(state->tafifo_buff[3] >> 30) & 1;
1493            state_ta.strideselect=(state->tafifo_buff[3] >> 25) & 1;
1494            state_ta.paletteselector=(state->tafifo_buff[3] >> 21) & 0x3F;
1495            #if DEBUG_PVRDLIST
1496            mame_printf_verbose(" Texture at %08x format %d\n", (state->tafifo_buff[3] & 0x1FFFFF) << 3, state_ta.pixelformat);
1497            #endif
1498         }
1499         if (state_ta.paratype == 4)
1500         { // polygon or mv
1501            if ((state_ta.tafifo_listtype == 1) || (state_ta.tafifo_listtype == 3))
1502            {
1503            #if DEBUG_PVRDLIST
1504               mame_printf_verbose(" Modifier Volume\n");
1505            #endif
1506            }
1507            else
1508            {
1509            #if DEBUG_PVRDLIST
1510               mame_printf_verbose(" Polygon\n");
1511            #endif
1512            }
1513         }
1514         if (state_ta.paratype == 5)
1515         { // quad
1516            #if DEBUG_PVRDLIST
1517            mame_printf_verbose(" Sprite\n");
1518            #endif
1519         }
1520      }
1521
1522      if (state_ta.paratype == 7)
1523      { // vertex
1524         if ((state_ta.tafifo_listtype == 1) || (state_ta.tafifo_listtype == 3))
1525         {
1526            #if DEBUG_PVRDLIST
1527            mame_printf_verbose(" Vertex modifier volume");
1528            mame_printf_verbose(" A(%f,%f,%f) B(%f,%f,%f) C(%f,%f,%f)", u2f(state->tafifo_buff[1]), u2f(state->tafifo_buff[2]),
1529               u2f(state->tafifo_buff[3]), u2f(state->tafifo_buff[4]), u2f(state->tafifo_buff[5]), u2f(state->tafifo_buff[6]), u2f(state->tafifo_buff[7]),
1530               u2f(state->tafifo_buff[8]), u2f(state->tafifo_buff[9]));
1531            mame_printf_verbose("\n");
1532            #endif
1533         }
1534         else if (state_ta.global_paratype == 5)
1535         {
1536            #if DEBUG_PVRDLIST
1537            mame_printf_verbose(" Vertex sprite");
1538            mame_printf_verbose(" A(%f,%f,%f) B(%f,%f,%f) C(%f,%f,%f) D(%f,%f,)", u2f(state->tafifo_buff[1]), u2f(state->tafifo_buff[2]),
1539               u2f(state->tafifo_buff[3]), u2f(state->tafifo_buff[4]), u2f(state->tafifo_buff[5]), u2f(state->tafifo_buff[6]), u2f(state->tafifo_buff[7]),
1540               u2f(state->tafifo_buff[8]), u2f(state->tafifo_buff[9]), u2f(state->tafifo_buff[10]), u2f(state->tafifo_buff[11]));
1541            mame_printf_verbose("\n");
1542            #endif
1543            if (state_ta.texture == 1)
1544            {
1545               if (rd->verts_size <= 65530)
1546               {
1547                  strip *ts;
1548                  vert *tv = &rd->verts[rd->verts_size];
1549                  tv[0].x = u2f(state->tafifo_buff[0x1]);
1550                  tv[0].y = u2f(state->tafifo_buff[0x2]);
1551                  tv[0].w = u2f(state->tafifo_buff[0x3]);
1552                  tv[1].x = u2f(state->tafifo_buff[0x4]);
1553                  tv[1].y = u2f(state->tafifo_buff[0x5]);
1554                  tv[1].w = u2f(state->tafifo_buff[0x6]);
1555                  tv[3].x = u2f(state->tafifo_buff[0x7]);
1556                  tv[3].y = u2f(state->tafifo_buff[0x8]);
1557                  tv[3].w = u2f(state->tafifo_buff[0x9]);
1558                  tv[2].x = u2f(state->tafifo_buff[0xa]);
1559                  tv[2].y = u2f(state->tafifo_buff[0xb]);
1560                  tv[2].w = tv[0].w+tv[3].w-tv[1].w;
1561                  tv[0].u = u2f(state->tafifo_buff[0xd] & 0xffff0000);
1562                  tv[0].v = u2f(state->tafifo_buff[0xd] << 16);
1563                  tv[1].u = u2f(state->tafifo_buff[0xe] & 0xffff0000);
1564                  tv[1].v = u2f(state->tafifo_buff[0xe] << 16);
1565                  tv[3].u = u2f(state->tafifo_buff[0xf] & 0xffff0000);
1566                  tv[3].v = u2f(state->tafifo_buff[0xf] << 16);
1567                  tv[2].u = tv[0].u+tv[3].u-tv[1].u;
1568                  tv[2].v = tv[0].v+tv[3].v-tv[1].v;
1569
1570                  ts = &rd->strips[rd->strips_size++];
1571                  tex_get_info(machine, &ts->ti, &state_ta);
1572                  ts->svert = rd->verts_size;
1573                  ts->evert = rd->verts_size + 3;
1574
1575                  rd->verts_size += 4;
1576               }
1577            }
1578         }
1579         else if (state_ta.global_paratype == 4)
1580         {
1581            #if DEBUG_PVRDLIST
1582            mame_printf_verbose(" Vertex polygon");
1583            mame_printf_verbose(" V(%f,%f,%f) T(%f,%f)", u2f(state->tafifo_buff[1]), u2f(state->tafifo_buff[2]), u2f(state->tafifo_buff[3]), u2f(state->tafifo_buff[4]), u2f(state->tafifo_buff[5]));
1584            mame_printf_verbose("\n");
1585            #endif
1586            if (rd->verts_size <= 65530)
1587            {
1588               /* add a vertex to our list */
1589               /* this is used for 3d stuff, ie most of the graphics (see guilty gear, confidential mission, maze of the kings etc.) */
1590               /* -- this is also wildly inaccurate! */
1591               vert *tv = &rd->verts[rd->verts_size];
1592
1593               tv->x=u2f(state->tafifo_buff[1]);
1594               tv->y=u2f(state->tafifo_buff[2]);
1595               tv->w=u2f(state->tafifo_buff[3]);
1596               tv->u=u2f(state->tafifo_buff[4]);
1597               tv->v=u2f(state->tafifo_buff[5]);
1598
1599
1600               if((!rd->strips_size) ||
1601                  rd->strips[rd->strips_size-1].evert != -1)
1602               {
1603                  strip *ts = &rd->strips[rd->strips_size++];
1604                  tex_get_info(machine, &ts->ti, &state_ta);
1605                  ts->svert = rd->verts_size;
1606                  ts->evert = -1;
1607               }
1608               if(state_ta.endofstrip)
1609                  rd->strips[rd->strips_size-1].evert = rd->verts_size;
1610               rd->verts_size++;
1611            }
1612         }
1613      }
1614   }
1615}
1616
1617WRITE64_HANDLER( ta_fifo_poly_w )
1618{
1619   dc_state *state = space.machine().driver_data<dc_state>();
1620
1621   if (mem_mask == U64(0xffffffffffffffff))    // 64 bit
1622   {
1623      state->tafifo_buff[state_ta.tafifo_pos]=(UINT32)data;
1624      state->tafifo_buff[state_ta.tafifo_pos+1]=(UINT32)(data >> 32);
1625      #if DEBUG_FIFO_POLY
1626      mame_printf_debug("ta_fifo_poly_w:  Unmapped write64 %08x = %" I64FMT "x -> %08x %08x\n", 0x10000000+offset*8, data, state->tafifo_buff[state_ta.tafifo_pos], state->tafifo_buff[state_ta.tafifo_pos+1]);
1627      #endif
1628      state_ta.tafifo_pos += 2;
1629   }
1630   else
1631   {
1632      fatalerror("ta_fifo_poly_w:  Only 64 bit writes supported!\n");
1633   }
1634
1635   state_ta.tafifo_pos &= state_ta.tafifo_mask;
1636
1637   // if the command is complete, process it
1638   if (state_ta.tafifo_pos == 0)
1639      process_ta_fifo(space.machine());
1640
1641}
1642
1643WRITE64_HANDLER( ta_fifo_yuv_w )
1644{
1645   //dc_state *state = space.machine().driver_data<dc_state>();
1646
1647//  int reg;
1648//  UINT64 shift;
1649//  UINT32 dat;
1650
1651//  reg = decode_reg_64(offset, mem_mask, &shift);
1652//  dat = (UINT32)(data >> shift);
1653
1654//  printf("YUV FIFO: [%08x=%x] write %" I64FMT "x to %x, mask %" I64FMT "x %08x\n", 0x10800000+reg*4, dat, data, offset, mem_mask,test);
1655}
1656
1657/* test video start */
1658static UINT32 dilate0(UINT32 value,int bits) // dilate first "bits" bits in "value"
1659{
1660   UINT32 x,m1,m2,m3;
1661   int a;
1662
1663   x = value;
1664   for (a=0;a < bits;a++)
1665   {
1666      m2 = 1 << (a << 1);
1667      m1 = m2 - 1;
1668      m3 = (~m1) << 1;
1669      x = (x & m1) + (x & m2) + ((x & m3) << 1);
1670   }
1671   return x;
1672}
1673
1674static UINT32 dilate1(UINT32 value,int bits) // dilate first "bits" bits in "value"
1675{
1676   UINT32 x,m1,m2,m3;
1677   int a;
1678
1679   x = value;
1680   for (a=0;a < bits;a++)
1681   {
1682      m2 = 1 << (a << 1);
1683      m1 = m2 - 1;
1684      m3 = (~m1) << 1;
1685      x = (x & m1) + ((x & m2) << 1) + ((x & m3) << 1);
1686   }
1687   return x;
1688}
1689
1690static void computedilated(void)
1691{
1692   int a,b;
1693
1694   for (b=0;b <= 14;b++)
1695      for (a=0;a < 1024;a++) {
1696         dilated0[b][a]=dilate0(a,b);
1697         dilated1[b][a]=dilate1(a,b);
1698      }
1699   for (b=0;b <= 7;b++)
1700      for (a=0;a <= 7;a++)
1701         dilatechose[(b << 3) + a]=3+(a < b ? a : b);
1702}
1703
1704static void render_hline(running_machine &machine,bitmap_rgb32 &bitmap, texinfo *ti, int y, float xl, float xr, float ul, float ur, float vl, float vr, float wl, float wr)
1705{
1706   dc_state *state = machine.driver_data<dc_state>();
1707   int xxl, xxr;
1708   float dx, ddx, dudx, dvdx, dwdx;
1709   UINT32 *tdata;
1710   float *wbufline;
1711
1712   // untextured cases aren't handled
1713   if (!ti->textured) return;
1714
1715   if(xr < 0 || xl >= 640)
1716      return;
1717
1718   xxl = round(xl);
1719   xxr = round(xr);
1720
1721   if(xxl == xxr)
1722      return;
1723
1724   dx = xr-xl;
1725   dudx = (ur-ul)/dx;
1726   dvdx = (vr-vl)/dx;
1727   dwdx = (wr-wl)/dx;
1728
1729   if(xxl < 0)
1730      xxl = 0;
1731   if(xxr > 640)
1732      xxr = 640;
1733
1734   // Target the pixel center
1735   ddx = xxl + 0.5 - xl;
1736   ul += ddx*dudx;
1737   vl += ddx*dvdx;
1738   wl += ddx*dwdx;
1739
1740
1741   tdata = &bitmap.pix32(y, xxl);
1742   wbufline = &wbuffer[y][xxl];
1743
1744   while(xxl < xxr) {
1745      if((wl >= *wbufline)) {
1746         UINT32 c;
1747         float u = ul/wl;
1748         float v = vl/wl;
1749
1750         /*
1751         if(ti->flip_u)
1752         {
1753             u = ti->sizex - u;
1754         }
1755
1756         if(ti->flip_v)
1757         {
1758             v = ti->sizey - v;
1759         }*/
1760
1761         c = ti->r(machine, ti, u, v);
1762
1763         // debug dip to turn on/off bilinear filtering, it's slooooow
1764         if (state->debug_dip_status&0x1)
1765         {
1766            if(ti->filter_mode >= TEX_FILTER_BILINEAR)
1767            {
1768               UINT32 c1 = ti->r(machine, ti, u+1.0, v);
1769               UINT32 c2 = ti->r(machine, ti, u+1.0, v+1.0);
1770               UINT32 c3 = ti->r(machine, ti, u, v+1.0);
1771               c = bilinear_filter(c, c1, c2, c3, u, v);
1772            }
1773         }
1774
1775         if(c & 0xff000000) {
1776            *tdata = ti->blend(c, *tdata);
1777            *wbufline = wl;
1778         }
1779      }
1780      wbufline++;
1781      tdata++;
1782
1783      ul += dudx;
1784      vl += dvdx;
1785      wl += dwdx;
1786      xxl ++;
1787   }
1788}
1789
1790static void render_span(running_machine &machine, bitmap_rgb32 &bitmap, texinfo *ti,
1791               float y0, float y1,
1792               float xl, float xr,
1793               float ul, float ur,
1794               float vl, float vr,
1795               float wl, float wr,
1796               float dxldy, float dxrdy,
1797               float duldy, float durdy,
1798               float dvldy, float dvrdy,
1799               float dwldy, float dwrdy)
1800{
1801   float dy;
1802   int yy0, yy1;
1803
1804   if(y1 <= 0)
1805      return;
1806   if(y1 > 480)
1807      y1 = 480;
1808
1809   if(y0 < 0) {
1810      xl += -dxldy*y0;
1811      xr += -dxrdy*y0;
1812      ul += -duldy*y0;
1813      ur += -durdy*y0;
1814      vl += -dvldy*y0;
1815      vr += -dvrdy*y0;
1816      wl += -dwldy*y0;
1817      wr += -dwrdy*y0;
1818      y0 = 0;
1819   }
1820
1821   yy0 = round(y0);
1822   yy1 = round(y1);
1823
1824   if((yy0 < 0 && y0 > 0) || (yy1 < 0 && y1 > 0)) //temp handling of int32 overflow, needed by hotd2/totd
1825      return;
1826
1827   dy = yy0+0.5-y0;
1828
1829   if(0)
1830      fprintf(stderr, "%f %f %f %f -> %f %f | %f %f -> %f %f\n",
1831            y0,
1832            dy, dxldy, dxrdy, dy*dxldy, dy*dxrdy,
1833            xl, xr, xl + dy*dxldy, xr + dy*dxrdy);
1834   xl += dy*dxldy;
1835   xr += dy*dxrdy;
1836   ul += dy*duldy;
1837   ur += dy*durdy;
1838   vl += dy*dvldy;
1839   vr += dy*dvrdy;
1840   wl += dy*dwldy;
1841   wr += dy*dwrdy;
1842
1843   while(yy0 < yy1) {
1844      render_hline(machine, bitmap, ti, yy0, xl, xr, ul, ur, vl, vr, wl, wr);
1845
1846      xl += dxldy;
1847      xr += dxrdy;
1848      ul += duldy;
1849      ur += durdy;
1850      vl += dvldy;
1851      vr += dvrdy;
1852      wl += dwldy;
1853      wr += dwrdy;
1854      yy0 ++;
1855   }
1856}
1857
1858static void sort_vertices(const vert *v, int *i0, int *i1, int *i2)
1859{
1860   float miny, maxy;
1861   int imin, imax, imid;
1862   miny = maxy = v[0].y;
1863   imin = imax = 0;
1864
1865   if(miny > v[1].y) {
1866      miny = v[1].y;
1867      imin = 1;
1868   } else if(maxy < v[1].y) {
1869      maxy = v[1].y;
1870      imax = 1;
1871   }
1872
1873   if(miny > v[2].y) {
1874      miny = v[2].y;
1875      imin = 2;
1876   } else if(maxy < v[2].y) {
1877      maxy = v[2].y;
1878      imax = 2;
1879   }
1880
1881   imid = (imin == 0 || imax == 0) ? (imin == 1 || imax == 1) ? 2 : 1 : 0;
1882
1883   *i0 = imin;
1884   *i1 = imid;
1885   *i2 = imax;
1886}
1887
1888
1889static void render_tri_sorted(running_machine &machine, bitmap_rgb32 &bitmap, texinfo *ti, const vert *v0, const vert *v1, const vert *v2)
1890{
1891   float dy01, dy02, dy12;
1892//  float dy; // unused, compiler complains about this
1893
1894   float dx01dy, dx02dy, dx12dy, du01dy, du02dy, du12dy, dv01dy, dv02dy, dv12dy, dw01dy, dw02dy, dw12dy;
1895
1896   if(v0->y >= 480 || v2->y < 0)
1897      return;
1898
1899   dy01 = v1->y - v0->y;
1900   dy02 = v2->y - v0->y;
1901   dy12 = v2->y - v1->y;
1902
1903   dx01dy = dy01 ? (v1->x-v0->x)/dy01 : 0;
1904   dx02dy = dy02 ? (v2->x-v0->x)/dy02 : 0;
1905   dx12dy = dy12 ? (v2->x-v1->x)/dy12 : 0;
1906
1907   du01dy = dy01 ? (v1->u-v0->u)/dy01 : 0;
1908   du02dy = dy02 ? (v2->u-v0->u)/dy02 : 0;
1909   du12dy = dy12 ? (v2->u-v1->u)/dy12 : 0;
1910
1911   dv01dy = dy01 ? (v1->v-v0->v)/dy01 : 0;
1912   dv02dy = dy02 ? (v2->v-v0->v)/dy02 : 0;
1913   dv12dy = dy12 ? (v2->v-v1->v)/dy12 : 0;
1914
1915   dw01dy = dy01 ? (v1->w-v0->w)/dy01 : 0;
1916   dw02dy = dy02 ? (v2->w-v0->w)/dy02 : 0;
1917   dw12dy = dy12 ? (v2->w-v1->w)/dy12 : 0;
1918
1919   if(!dy01) {
1920      if(!dy12)
1921         return;
1922
1923      if(v1->x > v0->x)
1924         render_span(machine, bitmap, ti, v1->y, v2->y, v0->x, v1->x, v0->u, v1->u, v0->v, v1->v, v0->w, v1->w, dx02dy, dx12dy, du02dy, du12dy, dv02dy, dv12dy, dw02dy, dw12dy);
1925      else
1926         render_span(machine, bitmap, ti, v1->y, v2->y, v1->x, v0->x, v1->u, v0->u, v1->v, v0->v, v1->w, v0->w, dx12dy, dx02dy, du12dy, du02dy, dv12dy, dv02dy, dw12dy, dw02dy);
1927
1928   } else if(!dy12) {
1929      if(v2->x > v1->x)
1930         render_span(machine, bitmap, ti, v0->y, v1->y, v0->x, v0->x, v0->u, v0->u, v0->v, v0->v, v0->w, v0->w, dx01dy, dx02dy, du01dy, du02dy, dv01dy, dv02dy, dw01dy, dw02dy);
1931      else
1932         render_span(machine, bitmap, ti, v0->y, v1->y, v0->x, v0->x, v0->u, v0->u, v0->v, v0->v, v0->w, v0->w, dx02dy, dx01dy, du02dy, du01dy, dv02dy, dv01dy, dw02dy, dw01dy);
1933
1934   } else {
1935      if(dx01dy < dx02dy) {
1936         render_span(machine, bitmap, ti, v0->y, v1->y,
1937                  v0->x, v0->x, v0->u, v0->u, v0->v, v0->v, v0->w, v0->w,
1938                  dx01dy, dx02dy, du01dy, du02dy, dv01dy, dv02dy, dw01dy, dw02dy);
1939         render_span(machine, bitmap, ti, v1->y, v2->y,
1940                  v1->x, v0->x + dx02dy*dy01, v1->u, v0->u + du02dy*dy01, v1->v, v0->v + dv02dy*dy01, v1->w, v0->w + dw02dy*dy01,
1941                  dx12dy, dx02dy, du12dy, du02dy, dv12dy, dv02dy, dw12dy, dw02dy);
1942      } else {
1943         render_span(machine, bitmap, ti, v0->y, v1->y,
1944                  v0->x, v0->x, v0->u, v0->u, v0->v, v0->v, v0->w, v0->w,
1945                  dx02dy, dx01dy, du02dy, du01dy, dv02dy, dv01dy, dw02dy, dw01dy);
1946         render_span(machine, bitmap, ti, v1->y, v2->y,
1947                  v0->x + dx02dy*dy01, v1->x, v0->u + du02dy*dy01, v1->u, v0->v + dv02dy*dy01, v1->v, v0->w + dw02dy*dy01, v1->w,
1948                  dx02dy, dx12dy, du02dy, du12dy, dv02dy, dv12dy, dw02dy, dw12dy);
1949      }
1950   }
1951}
1952
1953static void render_tri(running_machine &machine, bitmap_rgb32 &bitmap, texinfo *ti, const vert *v)
1954{
1955   int i0, i1, i2;
1956
1957   sort_vertices(v, &i0, &i1, &i2);
1958   render_tri_sorted(machine, bitmap, ti, v+i0, v+i1, v+i2);
1959}
1960
1961static void render_to_accumulation_buffer(running_machine &machine,bitmap_rgb32 &bitmap,const rectangle &cliprect)
1962{
1963   dc_state *state = machine.driver_data<dc_state>();
1964   address_space &space = state->m_maincpu->space(AS_PROGRAM);
1965   int cs,rs,ns;
1966   UINT32 c;
1967#if 0
1968   int stride;
1969   UINT16 *bmpaddr16;
1970   UINT32 k;
1971#endif
1972
1973
1974   if (state_ta.renderselect < 0)
1975      return;
1976
1977   //printf("drawtest!\n");
1978
1979   rs=state_ta.renderselect;
1980   c=state->pvrta_regs[ISP_BACKGND_T];
1981   c=space.read_dword(0x05000000+((c&0xfffff8)>>1)+(3+3)*4);
1982   bitmap.fill(c, cliprect);
1983
1984
1985   ns=state_ta.grab[rs].strips_size;
1986   if(ns)
1987      memset(wbuffer, 0x00, sizeof(wbuffer));
1988
1989   for (cs=0;cs < ns;cs++)
1990   {
1991      strip *ts = &state_ta.grab[rs].strips[cs];
1992      int sv = ts->svert;
1993      int ev = ts->evert;
1994      int i;
1995      if(ev == -1)
1996         continue;
1997
1998      for(i=sv; i <= ev; i++)
1999      {
2000         vert *tv = state_ta.grab[rs].verts + i;
2001         tv->u = tv->u * ts->ti.sizex * tv->w;
2002         tv->v = tv->v * ts->ti.sizey * tv->w;
2003      }
2004
2005      for(i=sv; i <= ev-2; i++)
2006      {
2007         if (!(state->debug_dip_status&0x2))
2008            render_tri(machine, bitmap, &ts->ti, state_ta.grab[rs].verts + i);
2009
2010      }
2011   }
2012   state_ta.grab[rs].busy=0;
2013}
2014
2015// copies the accumulation buffer into the framebuffer, converting to the specified format
2016// not accurate, ignores field stuff and just uses SOF1 for now
2017// also ignores scale effects (can scale accumulation buffer to half size with filtering etc.)
2018// also can specify dither etc.
2019// basically, just a crude implementation!
2020
2021/*
2022
20230x0 0555 KRGB 16 bit (default) Bit 15 is the value of fb_kval 7.
20240x1 565 RGB 16 bit
20250x2 4444 ARGB 16 bit
20260x3 1555 ARGB 16 bit The alpha value is determined by comparison with the value of fb_alpha_threshold.
20270x4 888 RGB 24 bit packed
20280x5 0888 KRGB 32 bit K is the value of fk_kval.
20290x6 8888 ARGB 32 bit
20300x7 Setting prohibited.
2031
2032*/
2033
2034static void pvr_accumulationbuffer_to_framebuffer(address_space &space, int x,int y)
2035{
2036   dc_state *state = space.machine().driver_data<dc_state>();
2037
2038   // the accumulation buffer is always 8888
2039   //
2040   // the standard format for the framebuffer appears to be 565
2041   // yes, this means colour data is lost in the conversion
2042
2043   UINT32 wc = state->pvrta_regs[FB_W_CTRL];
2044   UINT32 stride = state->pvrta_regs[FB_W_LINESTRIDE];
2045   UINT32 writeoffs = state->pvrta_regs[FB_W_SOF1];
2046
2047   UINT32* src;
2048
2049
2050   UINT8 packmode = wc & 0x7;
2051
2052   switch (packmode)
2053   {
2054      // used by ringout
2055      case 0x00: //0555 KRGB
2056      {
2057         int xcnt,ycnt;
2058         for (ycnt=0;ycnt<32;ycnt++)
2059         {
2060            UINT32 realwriteoffs = 0x05000000 + writeoffs + (y+ycnt) * (stride<<3) + (x*2);
2061            src = &fake_accumulationbuffer_bitmap->pix32(y+ycnt, x);
2062
2063
2064            for (xcnt=0;xcnt<32;xcnt++)
2065            {
2066               // data starts in 8888 format, downsample it
2067               UINT32 data = src[xcnt];
2068               UINT16 newdat = ((((data & 0x000000f8) >> 3)) << 0)   |
2069                           ((((data & 0x0000f800) >> 11)) << 5)  |
2070                           ((((data & 0x00f80000) >> 19)) << 10);
2071
2072               space.write_word(realwriteoffs+xcnt*2, newdat);
2073            }
2074         }
2075      }
2076      break;
2077
2078      // used by cleoftp
2079      case 0x01: //565 RGB 16 bit
2080      {
2081         int xcnt,ycnt;
2082         for (ycnt=0;ycnt<32;ycnt++)
2083         {
2084            UINT32 realwriteoffs = 0x05000000 + writeoffs + (y+ycnt) * (stride<<3) + (x*2);
2085            src = &fake_accumulationbuffer_bitmap->pix32(y+ycnt, x);
2086
2087
2088            for (xcnt=0;xcnt<32;xcnt++)
2089            {
2090               // data starts in 8888 format, downsample it
2091               UINT32 data = src[xcnt];
2092               UINT16 newdat = ((((data & 0x000000f8) >> 3)) << 0)   |
2093                           ((((data & 0x0000fc00) >> 10)) << 5)  |
2094                           ((((data & 0x00f80000) >> 19)) << 11);
2095
2096               space.write_word(realwriteoffs+xcnt*2, newdat);
2097            }
2098         }
2099      }
2100      break;
2101
2102      case 0x02:
2103         printf("pvr_accumulationbuffer_to_framebuffer buffer to tile at %d,%d - unsupported pack mode %02x (4444 ARGB)\n",x,y,packmode);
2104         break;
2105
2106      case 0x03: // 1555 ARGB 16 bit
2107      {
2108         int xcnt,ycnt;
2109         for (ycnt=0;ycnt<32;ycnt++)
2110         {
2111            UINT32 realwriteoffs = 0x05000000 + writeoffs + (y+ycnt) * (stride<<3) + (x*2);
2112            src = &fake_accumulationbuffer_bitmap->pix32(y+ycnt, x);
2113
2114
2115            for (xcnt=0;xcnt<32;xcnt++)
2116            {
2117               // data starts in 8888 format, downsample it
2118               UINT32 data = src[xcnt];
2119               UINT16 newdat = ((((data & 0x000000f8) >> 3)) << 0)   |
2120                           ((((data & 0x0000f800) >> 11)) << 5)  |
2121                           ((((data & 0x00f80000) >> 19)) << 10);
2122               // alpha?
2123
2124               space.write_word(realwriteoffs+xcnt*2, newdat);
2125            }
2126         }
2127      }
2128      break;
2129
2130      // used by Suchie3
2131      case 0x04: // 888 RGB 24-bit (HACK! should not downconvert and pvr_drawframebuffer should change accordingly)
2132      {
2133         int xcnt,ycnt;
2134         for (ycnt=0;ycnt<32;ycnt++)
2135         {
2136            UINT32 realwriteoffs = 0x05000000 + writeoffs + (y+ycnt) * (stride<<3) + (x*2);
2137            src = &fake_accumulationbuffer_bitmap->pix32(y+ycnt, x);
2138
2139
2140            for (xcnt=0;xcnt<32;xcnt++)
2141            {
2142               // data is 8888 format
2143               UINT32 data = src[xcnt];
2144               UINT16 newdat = ((((data & 0x000000f8) >> 3)) << 0)   |
2145                           ((((data & 0x0000fc00) >> 10)) << 5)  |
2146                           ((((data & 0x00f80000) >> 19)) << 11);
2147
2148               space.write_word(realwriteoffs+xcnt*2, newdat);
2149            }
2150         }
2151      }
2152      break;
2153
2154      case 0x05:
2155         printf("pvr_accumulationbuffer_to_framebuffer buffer to tile at %d,%d - unsupported pack mode %02x (0888 KGB 32-bit)\n",x,y,packmode);
2156         break;
2157
2158      case 0x06: // 8888 ARGB 32 bit (HACK! should not downconvert and pvr_drawframebuffer should change accordingly)
2159      {
2160         int xcnt,ycnt;
2161         for (ycnt=0;ycnt<32;ycnt++)
2162         {
2163            UINT32 realwriteoffs = 0x05000000 + writeoffs + (y+ycnt) * (stride<<3) + (x*2);
2164            src = &fake_accumulationbuffer_bitmap->pix32(y+ycnt, x);
2165
2166
2167            for (xcnt=0;xcnt<32;xcnt++)
2168            {
2169               // data is 8888 format
2170               UINT32 data = src[xcnt];
2171               UINT16 newdat = ((((data & 0x000000f8) >> 3)) << 0)   |
2172                           ((((data & 0x0000fc00) >> 10)) << 5)  |
2173                           ((((data & 0x00f80000) >> 19)) << 11);
2174
2175               space.write_word(realwriteoffs+xcnt*2, newdat);
2176            }
2177         }
2178      }
2179      break;
2180
2181      case 0x07:
2182         printf("pvr_accumulationbuffer_to_framebuffer buffer to tile at %d,%d - unsupported pack mode %02x (Reserved! Don't Use!)\n",x,y,packmode);
2183         break;
2184   }
2185
2186
2187}
2188
2189
2190static void pvr_drawframebuffer(running_machine &machine,bitmap_rgb32 &bitmap,const rectangle &cliprect)
2191{
2192   dc_state *state = machine.driver_data<dc_state>();
2193
2194   int x,y,dy,xi;
2195   UINT32 addrp;
2196   UINT32 *fbaddr;
2197   UINT32 c;
2198   UINT32 r,g,b;
2199
2200   UINT32 wc = state->pvrta_regs[FB_R_CTRL];
2201   UINT8 unpackmode = (wc & 0x0000000c) >>2;  // aka fb_depth
2202   UINT8 enable = (wc & 0x00000001);
2203
2204   // ??
2205   if (!enable) return;
2206
2207   // only for rgb565 framebuffer
2208   xi=((state->pvrta_regs[FB_R_SIZE] & 0x3ff)+1) << 1;
2209   dy=((state->pvrta_regs[FB_R_SIZE] >> 10) & 0x3ff)+1;
2210
2211   dy++;
2212   dy*=2; // probably depends on interlace mode, fields etc...
2213
2214   switch (unpackmode)
2215   {
2216      case 0x00: // 0555 RGB 16-bit, Cleo Fortune Plus
2217         // should upsample back to 8-bit output using fb_concat
2218         for (y=0;y <= dy;y++)
2219         {
2220            addrp=state->pvrta_regs[FB_R_SOF1]+y*xi*2;
2221            if(spg_pixel_double)
2222            {
2223               for (x=0;x < xi;x++)
2224               {
2225                  fbaddr=&bitmap.pix32(y, x*2+0);
2226                  c=*((reinterpret_cast<UINT16 *>(state->dc_framebuffer_ram.target())) + (WORD2_XOR_LE(addrp) >> 1));
2227
2228                  b = (c & 0x001f) << 3;
2229                  g = (c & 0x03e0) >> 2;
2230                  r = (c & 0x7c00) >> 7;
2231
2232                  if (y<=cliprect.max_y)
2233                     *fbaddr = b | (g<<8) | (r<<16);
2234
2235                  fbaddr=&bitmap.pix32(y, x*2+1);
2236                  if (y<=cliprect.max_y)
2237                     *fbaddr = b | (g<<8) | (r<<16);
2238                  addrp+=2;
2239               }
2240            }
2241            else
2242            {
2243               for (x=0;x < xi;x++)
2244               {
2245                  fbaddr=&bitmap.pix32(y, x);
2246                  c=*((reinterpret_cast<UINT16 *>(state->dc_framebuffer_ram.target())) + (WORD2_XOR_LE(addrp) >> 1));
2247
2248                  b = (c & 0x001f) << 3;
2249                  g = (c & 0x03e0) >> 2;
2250                  r = (c & 0x7c00) >> 7;
2251
2252                  if (y<=cliprect.max_y)
2253                     *fbaddr = b | (g<<8) | (r<<16);
2254                  addrp+=2;
2255               }
2256            }
2257         }
2258
2259         break;
2260      case 0x01: // 0565 RGB 16-bit
2261         // should upsample back to 8-bit output using fb_concat
2262         for (y=0;y <= dy;y++)
2263         {
2264            addrp=state->pvrta_regs[FB_R_SOF1]+y*xi*2;
2265            if(spg_pixel_double)
2266            {
2267               for (x=0;x < xi;x++)
2268               {
2269                  fbaddr=&bitmap.pix32(y, x*2+0);
2270                  c=*((reinterpret_cast<UINT16 *>(state->dc_framebuffer_ram.target())) + (WORD2_XOR_LE(addrp) >> 1));
2271
2272                  b = (c & 0x001f) << 3;
2273                  g = (c & 0x07e0) >> 3;
2274                  r = (c & 0xf800) >> 8;
2275
2276                  if (y<=cliprect.max_y)
2277                     *fbaddr = b | (g<<8) | (r<<16);
2278
2279                  fbaddr=&bitmap.pix32(y, x*2+1);
2280
2281                  if (y<=cliprect.max_y)
2282                     *fbaddr = b | (g<<8) | (r<<16);
2283
2284                  addrp+=2;
2285               }
2286            }
2287            else
2288            {
2289               for (x=0;x < xi;x++)
2290               {
2291                  fbaddr=&bitmap.pix32(y, x);
2292                  c=*((reinterpret_cast<UINT16 *>(state->dc_framebuffer_ram.target())) + (WORD2_XOR_LE(addrp) >> 1));
2293
2294                  b = (c & 0x001f) << 3;
2295                  g = (c & 0x07e0) >> 3;
2296                  r = (c & 0xf800) >> 8;
2297
2298                  if (y<=cliprect.max_y)
2299                     *fbaddr = b | (g<<8) | (r<<16);
2300                  addrp+=2;
2301               }
2302            }
2303         }
2304         break;
2305
2306      case 0x02: ; // 888 RGB 24-bit - suchie3 - HACKED, see pvr_accumulationbuffer_to_framebuffer!
2307         for (y=0;y <= dy;y++)
2308         {
2309            addrp=state->pvrta_regs[FB_R_SOF1]+y*xi*2;
2310            if(spg_pixel_double)
2311            {
2312               for (x=0;x < xi;x++)
2313               {
2314                  fbaddr=&bitmap.pix32(y, x*2+0);
2315                  c=*((reinterpret_cast<UINT16 *>(state->dc_framebuffer_ram.target())) + (WORD2_XOR_LE(addrp) >> 1));
2316
2317                  b = (c & 0x001f) << 3;
2318                  g = (c & 0x07e0) >> 3;
2319                  r = (c & 0xf800) >> 8;
2320
2321                  if (y<=cliprect.max_y)
2322                     *fbaddr = b | (g<<8) | (r<<16);
2323
2324                  fbaddr=&bitmap.pix32(y, x*2+1);
2325
2326                  if (y<=cliprect.max_y)
2327                     *fbaddr = b | (g<<8) | (r<<16);
2328                  addrp+=2;
2329               }
2330            }
2331            else
2332            {
2333               for (x=0;x < xi;x++)
2334               {
2335                  fbaddr=&bitmap.pix32(y, x);
2336                  c=*((reinterpret_cast<UINT16 *>(state->dc_framebuffer_ram.target())) + (WORD2_XOR_LE(addrp) >> 1));
2337
2338                  b = (c & 0x001f) << 3;
2339                  g = (c & 0x07e0) >> 3;
2340                  r = (c & 0xf800) >> 8;
2341
2342                  if (y<=cliprect.max_y)
2343                     *fbaddr = b | (g<<8) | (r<<16);
2344                  addrp+=2;
2345               }
2346            }
2347         }
2348         break;
2349
2350      case 0x03:        // 0888 ARGB 32-bit - HACKED, see pvr_accumulationbuffer_to_framebuffer!
2351         for (y=0;y <= dy;y++)
2352         {
2353            addrp=state->pvrta_regs[FB_R_SOF1]+y*xi*2;
2354            if(spg_pixel_double)
2355            {
2356               for (x=0;x < xi;x++)
2357               {
2358                  fbaddr=&bitmap.pix32(y, x*2+0);
2359                  c=*((reinterpret_cast<UINT16 *>(state->dc_framebuffer_ram.target())) + (WORD2_XOR_LE(addrp) >> 1));
2360
2361                  b = (c & 0x001f) << 3;
2362                  g = (c & 0x07e0) >> 3;
2363                  r = (c & 0xf800) >> 8;
2364
2365                  if (y<=cliprect.max_y)
2366                     *fbaddr = b | (g<<8) | (r<<16);
2367
2368                  fbaddr=&bitmap.pix32(y, x*2+1);
2369                  if (y<=cliprect.max_y)
2370                     *fbaddr = b | (g<<8) | (r<<16);
2371
2372                  addrp+=2;
2373               }
2374            }
2375            else
2376            {
2377               for (x=0;x < xi;x++)
2378               {
2379                  fbaddr=&bitmap.pix32(y, x);
2380                  c=*((reinterpret_cast<UINT16 *>(state->dc_framebuffer_ram.target())) + (WORD2_XOR_LE(addrp) >> 1));
2381
2382                  b = (c & 0x001f) << 3;
2383                  g = (c & 0x07e0) >> 3;
2384                  r = (c & 0xf800) >> 8;
2385
2386                  if (y<=cliprect.max_y)
2387                     *fbaddr = b | (g<<8) | (r<<16);
2388                  addrp+=2;
2389               }
2390            }
2391         }
2392         break;
2393   }
2394}
2395
2396
2397#if DEBUG_PALRAM
2398static void debug_paletteram(running_machine &machine)
2399{
2400   dc_state *state = machine.driver_data<dc_state>();
2401
2402   UINT64 pal;
2403   UINT32 r,g,b;
2404   int i;
2405
2406   //popmessage("%02x",state->pvrta_regs[PAL_RAM_CTRL]);
2407
2408   for(i=0;i<0x400;i++)
2409   {
2410      pal = state->pvrta_regs[((0x005F9000-0x005F8000)/4)+i];
2411      switch(state->pvrta_regs[PAL_RAM_CTRL])
2412      {
2413         case 0: //argb1555 <- guilty gear uses this mode
2414         {
2415            //a = (pal & 0x8000)>>15;
2416            r = (pal & 0x7c00)>>10;
2417            g = (pal & 0x03e0)>>5;
2418            b = (pal & 0x001f)>>0;
2419            //a = a ? 0xff : 0x00;
2420            palette_set_color_rgb(machine, i, pal5bit(r), pal5bit(g), pal5bit(b));
2421         }
2422         break;
2423         case 1: //rgb565
2424         {
2425            //a = 0xff;
2426            r = (pal & 0xf800)>>11;
2427            g = (pal & 0x07e0)>>5;
2428            b = (pal & 0x001f)>>0;
2429            palette_set_color_rgb(machine, i, pal5bit(r), pal6bit(g), pal5bit(b));
2430         }
2431         break;
2432         case 2: //argb4444
2433         {
2434            //a = (pal & 0xf000)>>12;
2435            r = (pal & 0x0f00)>>8;
2436            g = (pal & 0x00f0)>>4;
2437            b = (pal & 0x000f)>>0;
2438            palette_set_color_rgb(machine, i, pal4bit(r), pal4bit(g), pal4bit(b));
2439         }
2440         break;
2441         case 3: //argb8888
2442         {
2443            //a = (pal & 0xff000000)>>20;
2444            r = (pal & 0x00ff0000)>>16;
2445            g = (pal & 0x0000ff00)>>8;
2446            b = (pal & 0x000000ff)>>0;
2447            palette_set_color_rgb(machine, i, r, g, b);
2448         }
2449         break;
2450      }
2451   }
2452}
2453#endif
2454
2455/* test video end */
2456
2457static void pvr_build_parameterconfig(void)
2458{
2459   int a,b,c,d,e,p;
2460
2461   for (a = 0;a <= 63;a++)
2462      pvr_parameterconfig[a] = -1;
2463   p=0;
2464   // volume,col_type,texture,offset,16bit_uv
2465   for (a = 0;a <= 1;a++)
2466      for (b = 0;b <= 3;b++)
2467         for (c = 0;c <= 1;c++)
2468            if (c == 0)
2469            {
2470               for (d = 0;d <= 1;d++)
2471                  for (e = 0;e <= 1;e++)
2472                     pvr_parameterconfig[(a << 6) | (b << 4) | (c << 3) | (d << 2) | (e << 0)] = pvr_parconfseq[p];
2473               p++;
2474            }
2475            else
2476               for (d = 0;d <= 1;d++)
2477                  for (e = 0;e <= 1;e++)
2478                  {
2479                     pvr_parameterconfig[(a << 6) | (b << 4) | (c << 3) | (d << 2) | (e << 0)] = pvr_parconfseq[p];
2480                     p++;
2481                  }
2482   for (a = 1;a <= 63;a++)
2483      if (pvr_parameterconfig[a] < 0)
2484         pvr_parameterconfig[a] = pvr_parameterconfig[a-1];
2485}
2486
2487TIMER_CALLBACK_MEMBER(dc_state::vbin)
2488{
2489   dc_state *state = machine().driver_data<dc_state>();
2490
2491   dc_sysctrl_regs[SB_ISTNRM] |= IST_VBL_IN; // V Blank-in interrupt
2492   dc_update_interrupt_status();
2493
2494   vbin_timer->adjust(machine().primary_screen->time_until_pos(spg_vblank_in_irq_line_num));
2495}
2496
2497TIMER_CALLBACK_MEMBER(dc_state::vbout)
2498{
2499   dc_state *state = machine().driver_data<dc_state>();
2500
2501   dc_sysctrl_regs[SB_ISTNRM] |= IST_VBL_OUT; // V Blank-out interrupt
2502   dc_update_interrupt_status();
2503
2504   vbout_timer->adjust(machine().primary_screen->time_until_pos(spg_vblank_out_irq_line_num));
2505}
2506
2507TIMER_CALLBACK_MEMBER(dc_state::hbin)
2508{
2509   dc_state *state = machine().driver_data<dc_state>();
2510
2511   if(spg_hblank_int_mode & 1)
2512   {
2513      if(scanline == next_y)
2514      {
2515         dc_sysctrl_regs[SB_ISTNRM] |= IST_HBL_IN; // H Blank-in interrupt
2516         dc_update_interrupt_status();
2517         next_y+=spg_line_comp_val;
2518      }
2519   }
2520   else if((scanline == spg_line_comp_val) || (spg_hblank_int_mode & 2))
2521   {
2522      dc_sysctrl_regs[SB_ISTNRM] |= IST_HBL_IN; // H Blank-in interrupt
2523      dc_update_interrupt_status();
2524   }
2525
2526//  printf("hbin on scanline %d\n",scanline);
2527
2528   scanline++;
2529
2530   if(scanline >= spg_vblank_in_irq_line_num)
2531   {
2532      scanline = 0;
2533      next_y = spg_line_comp_val;
2534   }
2535
2536   hbin_timer->adjust(machine().primary_screen->time_until_pos(scanline, spg_hblank_in_irq-1));
2537}
2538
2539
2540
2541TIMER_CALLBACK_MEMBER(dc_state::endofrender_video)
2542{
2543   dc_sysctrl_regs[SB_ISTNRM] |= IST_EOR_VIDEO;// VIDEO end of render
2544   dc_update_interrupt_status();
2545   endofrender_timer_video->adjust(attotime::never);
2546}
2547
2548TIMER_CALLBACK_MEMBER(dc_state::endofrender_tsp)
2549{
2550   dc_sysctrl_regs[SB_ISTNRM] |= IST_EOR_TSP;  // TSP end of render
2551   dc_update_interrupt_status();
2552
2553   endofrender_timer_tsp->adjust(attotime::never);
2554   endofrender_timer_video->adjust(attotime::from_usec(500) );
2555}
2556
2557TIMER_CALLBACK_MEMBER(dc_state::endofrender_isp)
2558{
2559   dc_sysctrl_regs[SB_ISTNRM] |= IST_EOR_ISP;  // ISP end of render
2560   dc_update_interrupt_status();
2561
2562   endofrender_timer_isp->adjust(attotime::never);
2563   endofrender_timer_tsp->adjust(attotime::from_usec(500) );
2564}
2565
2566
2567void dc_state::video_start()
2568{
2569   memset(pvrctrl_regs, 0, sizeof(pvrctrl_regs));
2570   memset(pvrta_regs, 0, sizeof(pvrta_regs));
2571   memset(state_ta.grab, 0, sizeof(state_ta.grab));
2572   pvr_build_parameterconfig();
2573
2574   // if the next 2 registers do not have the correct values, the naomi bios will hang
2575   pvrta_regs[PVRID]=0x17fd11db;
2576   pvrta_regs[REVISION]=0x11;
2577   /* FIXME: move the following regs inside MACHINE_RESET */
2578   pvrta_regs[VO_CONTROL]=     0x00000108;
2579   pvrta_regs[SOFTRESET]=      0x00000007;
2580   pvrta_regs[VO_STARTX]=      0x0000009d;
2581   pvrta_regs[VO_STARTY]=      0x00150015;
2582   pvrta_regs[SPG_HBLANK]=     0x007e0345;
2583   pvrta_regs[SPG_LOAD]=       0x01060359;
2584   pvrta_regs[SPG_VBLANK]=     0x01500104;
2585   pvrta_regs[SPG_HBLANK_INT]= 0x031d0000;
2586   pvrta_regs[SPG_VBLANK_INT]= 0x01500104;
2587
2588   state_ta.tafifo_pos=0;
2589   state_ta.tafifo_mask=7;
2590   state_ta.tafifo_vertexwords=8;
2591   state_ta.tafifo_listtype= -1;
2592   state_ta.start_render_received=0;
2593   state_ta.renderselect= -1;
2594   state_ta.grabsel=0;
2595
2596   computedilated();
2597
2598   vbout_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(dc_state::vbout),this));
2599   vbout_timer->adjust(machine().primary_screen->time_until_pos(spg_vblank_out_irq_line_num_new));
2600
2601   vbin_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(dc_state::vbin),this));
2602   vbin_timer->adjust(machine().primary_screen->time_until_pos(spg_vblank_in_irq_line_num_new));
2603
2604   hbin_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(dc_state::hbin),this));
2605   hbin_timer->adjust(machine().primary_screen->time_until_pos(0, spg_hblank_in_irq_new-1));
2606
2607   scanline = 0;
2608   next_y = 0;
2609
2610   endofrender_timer_isp = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(dc_state::endofrender_isp),this));
2611   endofrender_timer_tsp = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(dc_state::endofrender_tsp),this));
2612   endofrender_timer_video = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(dc_state::endofrender_video),this));
2613
2614   endofrender_timer_isp->adjust(attotime::never);
2615   endofrender_timer_tsp->adjust(attotime::never);
2616   endofrender_timer_video->adjust(attotime::never);
2617
2618   fake_accumulationbuffer_bitmap = auto_bitmap_rgb32_alloc(machine(),1024,1024);
2619
2620}
2621
2622UINT32 dc_state::screen_update_dc(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
2623{
2624   /******************
2625     MAME note
2626   *******************
2627
2628   The video update function should NOT be generating interrupts, setting timers or doing _anything_ the game might be able to detect
2629   as it will be called at different times depending on frameskip etc.
2630
2631   Rendering should happen when the hardware requests it, to the framebuffer(s)
2632
2633   Everything else should depend on timers.
2634
2635   ******************/
2636
2637//  static int useframebuffer=1;
2638//  const rectangle &visarea = screen.visible_area();
2639//  int y,x;
2640
2641#if DEBUG_PALRAM
2642   debug_paletteram(machine());
2643#endif
2644
2645   // copy our fake framebuffer bitmap (where things have been rendered) to the screen
2646#if 0
2647   for (y = visarea->min_y ; y <= visarea->max_y ; y++)
2648   {
2649      for (x = visarea->min_x ; x <= visarea->max_x ; x++)
2650      {
2651         UINT32* src = &fake_accumulationbuffer_bitmap->pix32(y, x);
2652         UINT32* dst = &bitmap.pix32(y, x);
2653         dst[0] = src[0];
2654      }
2655   }
2656#endif
2657
2658   bitmap.fill(MAKE_ARGB(0xff,vo_border_R,vo_border_G,vo_border_B), cliprect); //FIXME: Chroma bit?
2659
2660   if(!spg_blank_video)
2661      pvr_drawframebuffer(machine(),bitmap,cliprect);
2662
2663   // update this here so we only do string lookup once per frame
2664   debug_dip_status = ioport("MAMEDEBUG")->read();
2665
2666   return 0;
2667}
2668
2669
2670/* Naomi 2 attempts (TBD) */
2671
2672READ64_HANDLER( pvr2_ta_r )
2673{
2674   int reg;
2675   UINT64 shift;
2676
2677   reg = decode_reg_64(offset, mem_mask, &shift);
2678
2679   switch (reg)
2680   {
2681   }
2682
2683   printf("PVR2 %08x R\n",reg);
2684
2685   return 0;
2686}
2687
2688WRITE64_HANDLER( pvr2_ta_w )
2689{
2690//  int reg;
2691//  UINT64 shift;
2692//  UINT32 dat;
2693
2694//  reg = decode_reg_64(offset, mem_mask, &shift);
2695//  dat = (UINT32)(data >> shift);
2696
2697   //printf("PVR2 %08x %08x\n",reg,dat);
2698}
2699
2700READ32_HANDLER( elan_regs_r )
2701{
2702   switch(offset)
2703   {
2704      case 0x00/4: // ID chip (TODO: BIOS crashes / gives a black screen with this as per now!)
2705         return 0xe1ad0000;
2706      case 0x04/4: // REVISION
2707         return 0x12; //or 0x01?
2708      case 0x10/4: // SH4 interface control (???)
2709         /* ---- -x-- enable second PVR */
2710         /* ---- --x- elan has channel 2 */
2711         /* ---- ---x broadcast on cs1 (?) */
2712         return 6;
2713      case 0x14/4: // SDRAM refresh register
2714         return 0x2029; //default 0x1429
2715      case 0x1c/4: // SDRAM CFG
2716         return 0xa7320961; //default 0xa7320961
2717      case 0x30/4: // Macro tiler configuration, bit 0 is enable
2718         return 0;
2719      case 0x74/4: // IRQ STAT
2720         return 0;
2721      case 0x78/4: // IRQ MASK
2722         return 0;
2723      default:
2724         printf("%08x %08x\n",space.device().safe_pc(),offset*4);
2725         break;
2726   }
2727
2728   return 0;
2729}
2730
2731WRITE32_HANDLER( elan_regs_w )
2732{
2733   switch(offset)
2734   {
2735      default:
2736         printf("%08x %08x %08x W\n",space.device().safe_pc(),offset*4,data);
2737         break;
2738   }
2739}
2740
2741
2742WRITE64_HANDLER( pvrs_ta_w )
2743{
2744   pvr_ta_w(space,offset,data,mem_mask);
2745   pvr2_ta_w(space,offset,data,mem_mask);
2746   //printf("PVR2 %08x %08x\n",reg,dat);
2747}
trunk/src/mame/video/powervr2.c
r0r23535
1/*
2    dc.c - Dreamcast video emulation
3
4*/
5
6#include "emu.h"
7#include "powervr2.h"
8#include "includes/dc.h"
9#include "cpu/sh4/sh4.h"
10#include "render.h"
11#include "rendutil.h"
12#include "video/rgbutil.h"
13
14const device_type POWERVR2 = &device_creator<powervr2_device>;
15
16const int powervr2_device::pvr_parconfseq[] = {1,2,3,2,3,4,5,6,5,6,7,8,9,10,11,12,13,14,13,14,15,16,17,16,17,0,0,0,0,0,18,19,20,19,20,21,22,23,22,23};
17const int powervr2_device::pvr_wordsvertex[24]  = {8,8,8,8,8,16,16,8,8,8, 8, 8,8,8,8,8,16,16, 8,16,16,8,16,16};
18const int powervr2_device::pvr_wordspolygon[24] = {8,8,8,8,8, 8, 8,8,8,8,16,16,8,8,8,8, 8, 8,16,16,16,8, 8, 8};
19
20#define DEBUG_FIFO_POLY (0)
21#define DEBUG_PVRTA (0)
22#define DEBUG_PVRTA_REGS (0)
23#define DEBUG_PVRDLIST  (0)
24#define DEBUG_PALRAM (1)
25#define DEBUG_PVRCTRL   (0)
26
27/* PVR TA macro defines */
28/*
29SPG_HBLANK_INT
30---- --xx xxxx xxxx ---- ---- ---- ---- hblank_in_interrupt
31---- ---- ---- ---- --xx ---- ---- ---- hblank_int_mode
32---- ---- ---- ---- ---- --xx xxxx xxxx line_comp_val
33*/
34#define spg_hblank_in_irq   ((pvrta_regs[SPG_HBLANK_INT] & 0x03ff0000) >> 16)
35#define spg_hblank_in_irq_new   ((pvrta_regs[SPG_HBLANK_INT] & 0x03ff0000) >> 16)
36#define spg_hblank_int_mode ((pvrta_regs[SPG_HBLANK_INT] & 0x00003000) >> 12)
37#define spg_line_comp_val   ((pvrta_regs[SPG_HBLANK_INT] & 0x000003ff) >> 0)
38
39/*
40SPG_VBLANK_INT
41---- --xx xxxx xxxx ---- ---- ---- ---- vblank_out_interrupt_line_number
42---- ---- ---- ---- ---- --xx xxxx xxxx vblank_in_interrupt_line_number
43*/
44#define spg_vblank_out_irq_line_num ((pvrta_regs[SPG_VBLANK_INT] & 0x03ff0000) >> 16)
45#define spg_vblank_in_irq_line_num  ((pvrta_regs[SPG_VBLANK_INT] & 0x000003ff) >> 0)
46#define spg_vblank_out_irq_line_num_new ((pvrta_regs[SPG_VBLANK_INT] & 0x03ff0000) >> 16)
47#define spg_vblank_in_irq_line_num_new  ((pvrta_regs[SPG_VBLANK_INT] & 0x000003ff) >> 0)
48
49
50/*
51VO_BORDER_COL
52---- ---x ---- ---- ---- ---- ---- ---- Chroma ;suchie3 sets 0xff there, maybe it's 8 bits too?
53---- ---- xxxx xxxx ---- ---- ---- ---- Red
54---- ---- ---- ---- xxxx xxxx ---- ---- Green
55---- ---- ---- ---- ---- ---- xxxx xxxx Blue
56*/
57#define vo_border_K ((pvrta_regs[VO_BORDER_COL] & 0x01000000) >> 24)
58#define vo_border_R ((pvrta_regs[VO_BORDER_COL] & 0x00ff0000) >> 16)
59#define vo_border_G ((pvrta_regs[VO_BORDER_COL] & 0x0000ff00) >> 8)
60#define vo_border_B ((pvrta_regs[VO_BORDER_COL] & 0x000000ff) >> 0)
61
62/*
63SPG_HBLANK
64---- ---- --xx xxxx xxxx ---- ---- ---- hbend
65---- ---- ---- ---- ---- --xx xxxx xxxx hbstart
66*/
67#define spg_hbend    ((pvrta_regs[SPG_HBLANK] & 0x03ff0000) >> 16)
68#define spg_hbstart  ((pvrta_regs[SPG_HBLANK] & 0x000003ff) >> 0)
69
70
71/*
72SPG_LOAD
73---- ---- --xx xxxx xxxx ---- ---- ---- vcount
74---- ---- ---- ---- ---- --xx xxxx xxxx hcount
75*/
76#define spg_vcount   ((pvrta_regs[SPG_LOAD] & 0x03ff0000) >> 16)
77#define spg_hcount   ((pvrta_regs[SPG_LOAD] & 0x000003ff) >> 0)
78
79/*
80SPG_VBLANK
81---- ---- --xx xxxx xxxx ---- ---- ---- vbend
82---- ---- ---- ---- ---- --xx xxxx xxxx vbstart
83*/
84#define spg_vbend    ((pvrta_regs[SPG_VBLANK] & 0x03ff0000) >> 16)
85#define spg_vbstart  ((pvrta_regs[SPG_VBLANK] & 0x000003ff) >> 0)
86
87
88/*
89VO_CONTROL
90---- ---- --xx xxxx ---- ---- ---- ---- pclk_delay
91---- ---- ---- ---- ---- ---x ---- ---- pixel_double ;used in test mode
92---- ---- ---- ---- ---- ---- xxxx ---- field_mode
93---- ---- ---- ---- ---- ---- ---- x--- blank_video
94---- ---- ---- ---- ---- ---- ---- -x-- blank_pol
95---- ---- ---- ---- ---- ---- ---- --x- vsync_pol
96---- ---- ---- ---- ---- ---- ---- ---x hsync_pol
97*/
98#define spg_pclk_delay   ((pvrta_regs[VO_CONTROL] & 0x003f0000) >> 16)
99#define spg_pixel_double ((pvrta_regs[VO_CONTROL] & 0x00000100) >> 8)
100#define spg_field_mode   ((pvrta_regs[VO_CONTROL] & 0x000000f0) >> 4)
101#define spg_blank_video  ((pvrta_regs[VO_CONTROL] & 0x00000008) >> 3)
102#define spg_blank_pol    ((pvrta_regs[VO_CONTROL] & 0x00000004) >> 2)
103#define spg_vsync_pol    ((pvrta_regs[VO_CONTROL] & 0x00000002) >> 1)
104#define spg_hsync_pol    ((pvrta_regs[VO_CONTROL] & 0x00000001) >> 0)
105
106/*
107VO_STARTX
108---- ---- ---- ---- ---- ---x xxxx xxxx horzontal start position
109*/
110#define vo_horz_start_pos ((pvrta_regs[VO_STARTX] & 0x000003ff) >> 0)
111
112/*
113VO_STARTY
114---- ---x xxxx xxxx ---- ---- ---- ---- vertical start position on field 2
115---- ---- ---- ---- ---- ---x xxxx xxxx vertical start position on field 1
116*/
117
118#define vo_vert_start_pos_f2 ((pvrta_regs[VO_STARTY] & 0x03ff0000) >> 16)
119#define vo_vert_start_pos_f1 ((pvrta_regs[VO_STARTY] & 0x000003ff) >> 0)
120
121/*
122SPG_STATUS
123---- ---- ---- ---- --x- ---- ---- ---- vsync
124---- ---- ---- ---- ---x ---- ---- ---- hsync
125---- ---- ---- ---- ---- x--- ---- ---- blank
126---- ---- ---- ---- ---- -x-- ---- ---- field number
127---- ---- ---- ---- ---- --xx xxxx xxxx state->scanline
128*/
129
130
131// Perform a standard bilinear filter across four pixels
132inline INT32 powervr2_device::clamp(INT32 in, INT32 min, INT32 max)
133{
134   if(in < min) return min;
135   if(in > max) return max;
136   return in;
137}
138
139inline UINT32 powervr2_device::bilinear_filter(UINT32 c0, UINT32 c1, UINT32 c2, UINT32 c3, float u, float v)
140{
141   UINT32 ui = (u * 256.0);
142   UINT32 vi = (v * 256.0);
143   return rgba_bilinear_filter(c0, c1, c3, c2, ui, vi);
144}
145
146// Multiply with alpha value in bits 31-24
147inline UINT32 powervr2_device::bla(UINT32 c, UINT32 a)
148{
149   a = a >> 24;
150   return ((((c & 0xff00ff)*a) & 0xff00ff00) >> 8) | ((((c >> 8) & 0xff00ff)*a) & 0xff00ff00);
151}
152
153// Multiply with 1-alpha value in bits 31-24
154inline UINT32 powervr2_device::blia(UINT32 c, UINT32 a)
155{
156   a = 0x100 - (a >> 24);
157   return ((((c & 0xff00ff)*a) & 0xff00ff00) >> 8) | ((((c >> 8) & 0xff00ff)*a) & 0xff00ff00);
158}
159
160// Per-component multiply with color value
161inline UINT32 powervr2_device::blc(UINT32 c1, UINT32 c2)
162{
163   UINT32 cr =
164      (((c1 & 0x000000ff)*(c2 & 0x000000ff) & 0x0000ff00) >> 8)  |
165      (((c1 & 0x0000ff00)*(c2 & 0x0000ff00) & 0x00ff0000) >> 8);
166   c1 >>= 16;
167   c2 >>= 16;
168   cr |=
169      (((c1 & 0x000000ff)*(c2 & 0x000000ff) & 0x0000ff00) << 8)  |
170      (((c1 & 0x0000ff00)*(c2 & 0x0000ff00) & 0x00ff0000) << 8);
171   return cr;
172}
173
174// Per-component multiply with 1-color value
175inline UINT32 powervr2_device::blic(UINT32 c1, UINT32 c2)
176{
177   UINT32 cr =
178      (((c1 & 0x000000ff)*(0x00100-(c2 & 0x000000ff)) & 0x0000ff00) >> 8)  |
179      (((c1 & 0x0000ff00)*(0x10000-(c2 & 0x0000ff00)) & 0x00ff0000) >> 8);
180   c1 >>= 16;
181   c2 >>= 16;
182   cr |=
183      (((c1 & 0x000000ff)*(0x00100-(c2 & 0x000000ff)) & 0x0000ff00) << 8)  |
184      (((c1 & 0x0000ff00)*(0x10000-(c2 & 0x0000ff00)) & 0x00ff0000) << 8);
185   return cr;
186}
187
188// Add two colors with saturation
189inline UINT32 powervr2_device::bls(UINT32 c1, UINT32 c2)
190{
191   UINT32 cr1, cr2;
192   cr1 = (c1 & 0x00ff00ff) + (c2 & 0x00ff00ff);
193   if(cr1 & 0x0000ff00)
194      cr1 = (cr1 & 0xffff00ff) | 0x000000ff;
195   if(cr1 & 0xff000000)
196      cr1 = (cr1 & 0x00ffffff) | 0x00ff0000;
197
198   cr2 = ((c1 >> 8) & 0x00ff00ff) + ((c2 >> 8) & 0x00ff00ff);
199   if(cr2 & 0x0000ff00)
200      cr2 = (cr2 & 0xffff00ff) | 0x000000ff;
201   if(cr2 & 0xff000000)
202      cr2 = (cr2 & 0x00ffffff) | 0x00ff0000;
203   return cr1|(cr2 << 8);
204}
205
206// All 64 blending modes, 3 top bits are source mode, 3 bottom bits are destination mode
207UINT32 powervr2_device::bl00(UINT32 s, UINT32 d) { return 0; }
208UINT32 powervr2_device::bl01(UINT32 s, UINT32 d) { return d; }
209UINT32 powervr2_device::bl02(UINT32 s, UINT32 d) { return blc(d, s); }
210UINT32 powervr2_device::bl03(UINT32 s, UINT32 d) { return blic(d, s); }
211UINT32 powervr2_device::bl04(UINT32 s, UINT32 d) { return bla(d, s); }
212UINT32 powervr2_device::bl05(UINT32 s, UINT32 d) { return blia(d, s); }
213UINT32 powervr2_device::bl06(UINT32 s, UINT32 d) { return bla(d, d); }
214UINT32 powervr2_device::bl07(UINT32 s, UINT32 d) { return blia(d, d); }
215UINT32 powervr2_device::bl10(UINT32 s, UINT32 d) { return s; }
216UINT32 powervr2_device::bl11(UINT32 s, UINT32 d) { return bls(s, d); }
217UINT32 powervr2_device::bl12(UINT32 s, UINT32 d) { return bls(s, blc(s, d)); }
218UINT32 powervr2_device::bl13(UINT32 s, UINT32 d) { return bls(s, blic(s, d)); }
219UINT32 powervr2_device::bl14(UINT32 s, UINT32 d) { return bls(s, bla(d, s)); }
220UINT32 powervr2_device::bl15(UINT32 s, UINT32 d) { return bls(s, blia(d, s)); }
221UINT32 powervr2_device::bl16(UINT32 s, UINT32 d) { return bls(s, bla(d, d)); }
222UINT32 powervr2_device::bl17(UINT32 s, UINT32 d) { return bls(s, blia(d, d)); }
223UINT32 powervr2_device::bl20(UINT32 s, UINT32 d) { return blc(d, s); }
224UINT32 powervr2_device::bl21(UINT32 s, UINT32 d) { return bls(blc(d, s), d); }
225UINT32 powervr2_device::bl22(UINT32 s, UINT32 d) { return bls(blc(d, s), blc(s, d)); }
226UINT32 powervr2_device::bl23(UINT32 s, UINT32 d) { return bls(blc(d, s), blic(s, d)); }
227UINT32 powervr2_device::bl24(UINT32 s, UINT32 d) { return bls(blc(d, s), bla(d, s)); }
228UINT32 powervr2_device::bl25(UINT32 s, UINT32 d) { return bls(blc(d, s), blia(d, s)); }
229UINT32 powervr2_device::bl26(UINT32 s, UINT32 d) { return bls(blc(d, s), bla(d, d)); }
230UINT32 powervr2_device::bl27(UINT32 s, UINT32 d) { return bls(blc(d, s), blia(d, d)); }
231UINT32 powervr2_device::bl30(UINT32 s, UINT32 d) { return blic(d, s); }
232UINT32 powervr2_device::bl31(UINT32 s, UINT32 d) { return bls(blic(d, s), d); }
233UINT32 powervr2_device::bl32(UINT32 s, UINT32 d) { return bls(blic(d, s), blc(s, d)); }
234UINT32 powervr2_device::bl33(UINT32 s, UINT32 d) { return bls(blic(d, s), blic(s, d)); }
235UINT32 powervr2_device::bl34(UINT32 s, UINT32 d) { return bls(blic(d, s), bla(d, s)); }
236UINT32 powervr2_device::bl35(UINT32 s, UINT32 d) { return bls(blic(d, s), blia(d, s)); }
237UINT32 powervr2_device::bl36(UINT32 s, UINT32 d) { return bls(blic(d, s), bla(d, d)); }
238UINT32 powervr2_device::bl37(UINT32 s, UINT32 d) { return bls(blic(d, s), blia(d, d)); }
239UINT32 powervr2_device::bl40(UINT32 s, UINT32 d) { return bla(s, s); }
240UINT32 powervr2_device::bl41(UINT32 s, UINT32 d) { return bls(bla(s, s), d); }
241UINT32 powervr2_device::bl42(UINT32 s, UINT32 d) { return bls(bla(s, s), blc(s, d)); }
242UINT32 powervr2_device::bl43(UINT32 s, UINT32 d) { return bls(bla(s, s), blic(s, d)); }
243UINT32 powervr2_device::bl44(UINT32 s, UINT32 d) { return bls(bla(s, s), bla(d, s)); }
244UINT32 powervr2_device::bl45(UINT32 s, UINT32 d) { return bls(bla(s, s), blia(d, s)); }
245UINT32 powervr2_device::bl46(UINT32 s, UINT32 d) { return bls(bla(s, s), bla(d, d)); }
246UINT32 powervr2_device::bl47(UINT32 s, UINT32 d) { return bls(bla(s, s), blia(d, d)); }
247UINT32 powervr2_device::bl50(UINT32 s, UINT32 d) { return blia(s, s); }
248UINT32 powervr2_device::bl51(UINT32 s, UINT32 d) { return bls(blia(s, s), d); }
249UINT32 powervr2_device::bl52(UINT32 s, UINT32 d) { return bls(blia(s, s), blc(s, d)); }
250UINT32 powervr2_device::bl53(UINT32 s, UINT32 d) { return bls(blia(s, s), blic(s, d)); }
251UINT32 powervr2_device::bl54(UINT32 s, UINT32 d) { return bls(blia(s, s), bla(d, s)); }
252UINT32 powervr2_device::bl55(UINT32 s, UINT32 d) { return bls(blia(s, s), blia(d, s)); }
253UINT32 powervr2_device::bl56(UINT32 s, UINT32 d) { return bls(blia(s, s), bla(d, d)); }
254UINT32 powervr2_device::bl57(UINT32 s, UINT32 d) { return bls(blia(s, s), blia(d, d)); }
255UINT32 powervr2_device::bl60(UINT32 s, UINT32 d) { return bla(s, d); }
256UINT32 powervr2_device::bl61(UINT32 s, UINT32 d) { return bls(bla(s, d), d); }
257UINT32 powervr2_device::bl62(UINT32 s, UINT32 d) { return bls(bla(s, d), blc(s, d)); }
258UINT32 powervr2_device::bl63(UINT32 s, UINT32 d) { return bls(bla(s, d), blic(s, d)); }
259UINT32 powervr2_device::bl64(UINT32 s, UINT32 d) { return bls(bla(s, d), bla(d, s)); }
260UINT32 powervr2_device::bl65(UINT32 s, UINT32 d) { return bls(bla(s, d), blia(d, s)); }
261UINT32 powervr2_device::bl66(UINT32 s, UINT32 d) { return bls(bla(s, d), bla(d, d)); }
262UINT32 powervr2_device::bl67(UINT32 s, UINT32 d) { return bls(bla(s, d), blia(d, d)); }
263UINT32 powervr2_device::bl70(UINT32 s, UINT32 d) { return blia(s, d); }
264UINT32 powervr2_device::bl71(UINT32 s, UINT32 d) { return bls(blia(s, d), d); }
265UINT32 powervr2_device::bl72(UINT32 s, UINT32 d) { return bls(blia(s, d), blc(s, d)); }
266UINT32 powervr2_device::bl73(UINT32 s, UINT32 d) { return bls(blia(s, d), blic(s, d)); }
267UINT32 powervr2_device::bl74(UINT32 s, UINT32 d) { return bls(blia(s, d), bla(d, s)); }
268UINT32 powervr2_device::bl75(UINT32 s, UINT32 d) { return bls(blia(s, d), blia(d, s)); }
269UINT32 powervr2_device::bl76(UINT32 s, UINT32 d) { return bls(blia(s, d), bla(d, d)); }
270UINT32 powervr2_device::bl77(UINT32 s, UINT32 d) { return bls(blia(s, d), blia(d, d)); }
271
272UINT32 (*const powervr2_device::blend_functions[64])(UINT32 s, UINT32 d) = {
273   bl00, bl01, bl02, bl03, bl04, bl05, bl06, bl07,
274   bl10, bl11, bl12, bl13, bl14, bl15, bl16, bl17,
275   bl20, bl21, bl22, bl23, bl24, bl25, bl26, bl27,
276   bl30, bl31, bl32, bl33, bl34, bl35, bl36, bl37,
277   bl40, bl41, bl42, bl43, bl44, bl45, bl46, bl47,
278   bl50, bl51, bl52, bl53, bl54, bl55, bl56, bl57,
279   bl60, bl61, bl62, bl63, bl64, bl65, bl66, bl67,
280   bl70, bl71, bl72, bl73, bl74, bl75, bl76, bl77,
281};
282
283inline UINT32 powervr2_device::cv_1555(UINT16 c)
284{
285   return
286      (c & 0x8000 ? 0xff000000 : 0) |
287      ((c << 9) & 0x00f80000) | ((c << 4) & 0x00070000) |
288      ((c << 6) & 0x0000f800) | ((c << 1) & 0x00000700) |
289      ((c << 3) & 0x000000f8) | ((c >> 2) & 0x00000007);
290}
291
292inline UINT32 powervr2_device::cv_1555z(UINT16 c)
293{
294   return
295      (c & 0x8000 ? 0xff000000 : 0) |
296      ((c << 9) & 0x00f80000) |
297      ((c << 6) & 0x0000f800) |
298      ((c << 3) & 0x000000f8);
299}
300
301inline UINT32 powervr2_device::cv_565(UINT16 c)
302{
303   return
304      0xff000000 |
305      ((c << 8) & 0x00f80000) | ((c << 3) & 0x00070000) |
306      ((c << 5) & 0x0000fc00) | ((c >> 1) & 0x00000300) |
307      ((c << 3) & 0x000000f8) | ((c >> 2) & 0x00000007);
308}
309
310inline UINT32 powervr2_device::cv_565z(UINT16 c)
311{
312   return
313      0xff000000 |
314      ((c << 8) & 0x00f80000) |
315      ((c << 5) & 0x0000fc00) |
316      ((c << 3) & 0x000000f8);
317}
318
319inline UINT32 powervr2_device::cv_4444(UINT16 c)
320{
321   return
322      ((c << 16) & 0xf0000000) | ((c << 12) & 0x0f000000) |
323      ((c << 12) & 0x00f00000) | ((c <<  8) & 0x000f0000) |
324      ((c <<  8) & 0x0000f000) | ((c <<  4) & 0x00000f00) |
325      ((c <<  4) & 0x000000f0) | ((c      ) & 0x0000000f);
326}
327
328inline UINT32 powervr2_device::cv_4444z(UINT16 c)
329{
330   return
331      ((c << 16) & 0xf0000000) |
332      ((c << 12) & 0x00f00000) |
333      ((c <<  8) & 0x0000f000) |
334      ((c <<  4) & 0x000000f0);
335}
336
337inline UINT32 powervr2_device::cv_yuv(UINT16 c1, UINT16 c2, int x)
338{
339   int u = 11*((c1 & 0xff) - 128);
340   int v = 11*((c2 & 0xff) - 128);
341   int y = (x & 1 ? c2 : c1) >> 8;
342   int r = y + v/8;
343   int g = y - u/32 - v/16;
344   int b = y + (3*u)/16;
345   r = r < 0 ? 0 : r > 255 ? 255 : r;
346   g = g < 0 ? 0 : g > 255 ? 255 : g;
347   b = b < 0 ? 0 : b > 255 ? 255 : b;
348   return 0xff000000 | (r << 16) | (g << 8) | b;
349}
350
351
352UINT32 powervr2_device::tex_r_yuv_n(texinfo *t, float x, float y)
353{
354   int xt = ((int)x) & (t->sizex-1);
355   int yt = ((int)y) & (t->sizey-1);
356   int addrp = t->address + (t->stride*yt + (xt & ~1))*2;
357   UINT16 c1 = *(UINT16 *)((reinterpret_cast<UINT8 *>(dc_texture_ram)) + WORD_XOR_LE(addrp));
358   UINT16 c2 = *(UINT16 *)((reinterpret_cast<UINT8 *>(dc_texture_ram)) + WORD_XOR_LE(addrp+2));
359   return cv_yuv(c1, c2, xt);
360}
361
362UINT32 powervr2_device::tex_r_1555_n(texinfo *t, float x, float y)
363{
364   int xt = ((int)x) & (t->sizex-1);
365   int yt = ((int)y) & (t->sizey-1);
366   int addrp = t->address + (t->stride*yt + xt)*2;
367   return cv_1555z(*(UINT16 *)((reinterpret_cast<UINT8 *>(dc_texture_ram)) + WORD_XOR_LE(addrp)));
368}
369
370UINT32 powervr2_device::tex_r_1555_tw(texinfo *t, float x, float y)
371{
372   int xt = ((int)x) & (t->sizex-1);
373   int yt = ((int)y) & (t->sizey-1);
374   int addrp = t->address + (dilated1[t->cd][xt] + dilated0[t->cd][yt])*2;
375   return cv_1555(*(UINT16 *)((reinterpret_cast<UINT8 *>(dc_texture_ram)) + WORD_XOR_LE(addrp)));
376}
377
378UINT32 powervr2_device::tex_r_1555_vq(texinfo *t, float x, float y)
379{
380   int xt = ((int)x) & (t->sizex-1);
381   int yt = ((int)y) & (t->sizey-1);
382   int idx = (reinterpret_cast<UINT8 *>(dc_texture_ram))[BYTE_XOR_LE(t->address + dilated1[t->cd][xt >> 1] + dilated0[t->cd][yt >> 1])];
383   int addrp = t->vqbase + 8*idx + (dilated1[t->cd][xt & 1] + dilated0[t->cd][yt & 1])*2;
384   return cv_1555(*(UINT16 *)((reinterpret_cast<UINT8 *>(dc_texture_ram)) + WORD_XOR_LE(addrp)));
385}
386
387UINT32 powervr2_device::tex_r_565_n(texinfo *t, float x, float y)
388{
389   int xt = ((int)x) & (t->sizex-1);
390   int yt = ((int)y) & (t->sizey-1);
391   int addrp = t->address + (t->stride*yt + xt)*2;
392   return cv_565z(*(UINT16 *)((reinterpret_cast<UINT8 *>(dc_texture_ram)) + WORD_XOR_LE(addrp)));
393}
394
395UINT32 powervr2_device::tex_r_565_tw(texinfo *t, float x, float y)
396{
397   int xt = ((int)x) & (t->sizex-1);
398   int yt = ((int)y) & (t->sizey-1);
399   int addrp = t->address + (dilated1[t->cd][xt] + dilated0[t->cd][yt])*2;
400   return cv_565(*(UINT16 *)((reinterpret_cast<UINT8 *>(dc_texture_ram)) + WORD_XOR_LE(addrp)));
401}
402
403UINT32 powervr2_device::tex_r_565_vq(texinfo *t, float x, float y)
404{
405   int xt = ((int)x) & (t->sizex-1);
406   int yt = ((int)y) & (t->sizey-1);
407   int idx = (reinterpret_cast<UINT8 *>(dc_texture_ram))[BYTE_XOR_LE(t->address + dilated1[t->cd][xt >> 1] + dilated0[t->cd][yt >> 1])];
408   int addrp = t->vqbase + 8*idx + (dilated1[t->cd][xt & 1] + dilated0[t->cd][yt & 1])*2;
409   return cv_565(*(UINT16 *)((reinterpret_cast<UINT8 *>(dc_texture_ram)) + WORD_XOR_LE(addrp)));
410}
411
412UINT32 powervr2_device::tex_r_4444_n(texinfo *t, float x, float y)
413{
414   int xt = ((int)x) & (t->sizex-1);
415   int yt = ((int)y) & (t->sizey-1);
416   int addrp = t->address + (t->stride*yt + xt)*2;
417   return cv_4444z(*(UINT16 *)((reinterpret_cast<UINT8 *>(dc_texture_ram)) + WORD_XOR_LE(addrp)));
418}
419
420UINT32 powervr2_device::tex_r_4444_tw(texinfo *t, float x, float y)
421{
422   int xt = ((int)x) & (t->sizex-1);
423   int yt = ((int)y) & (t->sizey-1);
424   int addrp = t->address + (dilated1[t->cd][xt] + dilated0[t->cd][yt])*2;
425   return cv_4444(*(UINT16 *)((reinterpret_cast<UINT8 *>(dc_texture_ram)) + WORD_XOR_LE(addrp)));
426}
427
428UINT32 powervr2_device::tex_r_4444_vq(texinfo *t, float x, float y)
429{
430   int xt = ((int)x) & (t->sizex-1);
431   int yt = ((int)y) & (t->sizey-1);
432   int idx = (reinterpret_cast<UINT8 *>(dc_texture_ram))[BYTE_XOR_LE(t->address + dilated1[t->cd][xt >> 1] + dilated0[t->cd][yt >> 1])];
433   int addrp = t->vqbase + 8*idx + (dilated1[t->cd][xt & 1] + dilated0[t->cd][yt & 1])*2;
434   return cv_4444(*(UINT16 *)((reinterpret_cast<UINT8 *>(dc_texture_ram)) + WORD_XOR_LE(addrp)));
435}
436
437UINT32 powervr2_device::tex_r_p4_1555_tw(texinfo *t, float x, float y)
438{
439   int xt = ((int)x) & (t->sizex-1);
440   int yt = ((int)y) & (t->sizey-1);
441   int off = dilated1[t->cd][xt] + dilated0[t->cd][yt];
442   int addrp = t->address + (off >> 1);
443   int c = ((reinterpret_cast<UINT8 *>(dc_texture_ram))[BYTE_XOR_LE(addrp)] >> ((off & 1) << 2)) & 0xf;
444   return cv_1555(pvrta_regs[t->palbase + c]);
445}
446
447UINT32 powervr2_device::tex_r_p4_1555_vq(texinfo *t, float x, float y)
448{
449   int xt = ((int)x) & (t->sizex-1);
450   int yt = ((int)y) & (t->sizey-1);
451   int idx = (reinterpret_cast<UINT8 *>(dc_texture_ram))[BYTE_XOR_LE(t->address + dilated1[t->cd][xt >> 1] + dilated0[t->cd][yt >> 1])];
452   int addrp = t->vqbase + 8*idx + dilated1[t->cd][xt & 1] + dilated0[t->cd][yt & 3];
453   int c = (reinterpret_cast<UINT8 *>(dc_texture_ram))[BYTE_XOR_LE(addrp)] & 0xf;
454   return cv_1555(pvrta_regs[t->palbase + c]);
455}
456
457UINT32 powervr2_device::tex_r_p4_565_tw(texinfo *t, float x, float y)
458{
459   int xt = ((int)x) & (t->sizex-1);
460   int yt = ((int)y) & (t->sizey-1);
461   int off = dilated1[t->cd][xt] + dilated0[t->cd][yt];
462   int addrp = t->address + (off >> 1);
463   int c = ((reinterpret_cast<UINT8 *>(dc_texture_ram))[BYTE_XOR_LE(addrp)] >> ((off & 1) << 2)) & 0xf;
464   return cv_565(pvrta_regs[t->palbase + c]);
465}
466
467UINT32 powervr2_device::tex_r_p4_565_vq(texinfo *t, float x, float y)
468{
469   int xt = ((int)x) & (t->sizex-1);
470   int yt = ((int)y) & (t->sizey-1);
471   int idx = (reinterpret_cast<UINT8 *>(dc_texture_ram))[BYTE_XOR_LE(t->address + dilated1[t->cd][xt >> 1] + dilated0[t->cd][yt >> 1])];
472   int addrp = t->vqbase + 8*idx + dilated1[t->cd][xt & 1] + dilated0[t->cd][yt & 3];
473   int c = (reinterpret_cast<UINT8 *>(dc_texture_ram))[BYTE_XOR_LE(addrp)] & 0xf;
474   return cv_565(pvrta_regs[t->palbase + c]);
475}
476
477UINT32 powervr2_device::tex_r_p4_4444_tw(texinfo *t, float x, float y)
478{
479   int xt = ((int)x) & (t->sizex-1);
480   int yt = ((int)y) & (t->sizey-1);
481   int off = dilated1[t->cd][xt] + dilated0[t->cd][yt];
482   int addrp = t->address + (off >> 1);
483   int c = ((reinterpret_cast<UINT8 *>(dc_texture_ram))[BYTE_XOR_LE(addrp)] >> ((off & 1) << 2)) & 0xf;
484   return cv_4444(pvrta_regs[t->palbase + c]);
485}
486
487UINT32 powervr2_device::tex_r_p4_4444_vq(texinfo *t, float x, float y)
488{
489   int xt = ((int)x) & (t->sizex-1);
490   int yt = ((int)y) & (t->sizey-1);
491   int idx = (reinterpret_cast<UINT8 *>(dc_texture_ram))[BYTE_XOR_LE(t->address + dilated1[t->cd][xt >> 1] + dilated0[t->cd][yt >> 1])];
492   int addrp = t->vqbase + 8*idx + dilated1[t->cd][xt & 1] + dilated0[t->cd][yt & 3];
493   int c = (reinterpret_cast<UINT8 *>(dc_texture_ram))[BYTE_XOR_LE(addrp)] & 0xf;
494   return cv_4444(pvrta_regs[t->palbase + c]);
495}
496
497UINT32 powervr2_device::tex_r_p4_8888_tw(texinfo *t, float x, float y)
498{
499   int xt = ((int)x) & (t->sizex-1);
500   int yt = ((int)y) & (t->sizey-1);
501   int off = dilated1[t->cd][xt] + dilated0[t->cd][yt];
502   int addrp = t->address + (off >> 1);
503   int c = ((reinterpret_cast<UINT8 *>(dc_texture_ram))[BYTE_XOR_LE(addrp)] >> ((off & 1) << 2)) & 0xf;
504   return pvrta_regs[t->palbase + c];
505}
506
507UINT32 powervr2_device::tex_r_p4_8888_vq(texinfo *t, float x, float y)
508{
509   int xt = ((int)x) & (t->sizex-1);
510   int yt = ((int)y) & (t->sizey-1);
511   int idx = (reinterpret_cast<UINT8 *>(dc_texture_ram))[BYTE_XOR_LE(t->address + dilated1[t->cd][xt >> 1] + dilated0[t->cd][yt >> 1])];
512   int addrp = t->vqbase + 8*idx + dilated1[t->cd][xt & 1] + dilated0[t->cd][yt & 3];
513   int c = (reinterpret_cast<UINT8 *>(dc_texture_ram))[BYTE_XOR_LE(addrp)] & 0xf;
514   return pvrta_regs[t->palbase + c];
515}
516
517UINT32 powervr2_device::tex_r_p8_1555_tw(texinfo *t, float x, float y)
518{
519   int xt = ((int)x) & (t->sizex-1);
520   int yt = ((int)y) & (t->sizey-1);
521   int addrp = t->address + dilated1[t->cd][xt] + dilated0[t->cd][yt];
522   int c = (reinterpret_cast<UINT8 *>(dc_texture_ram))[BYTE_XOR_LE(addrp)];
523   return cv_1555(pvrta_regs[t->palbase + c]);
524}
525
526UINT32 powervr2_device::tex_r_p8_1555_vq(texinfo *t, float x, float y)
527{
528   int xt = ((int)x) & (t->sizex-1);
529   int yt = ((int)y) & (t->sizey-1);
530   int idx = (reinterpret_cast<UINT8 *>(dc_texture_ram))[BYTE_XOR_LE(t->address + dilated1[t->cd][xt >> 1] + dilated0[t->cd][yt >> 1])];
531   int addrp = t->vqbase + 8*idx + dilated1[t->cd][xt & 1] + dilated0[t->cd][yt & 3];
532   int c = (reinterpret_cast<UINT8 *>(dc_texture_ram))[BYTE_XOR_LE(addrp)];
533   return cv_1555(pvrta_regs[t->palbase + c]);
534}
535
536UINT32 powervr2_device::tex_r_p8_565_tw(texinfo *t, float x, float y)
537{
538   int xt = ((int)x) & (t->sizex-1);
539   int yt = ((int)y) & (t->sizey-1);
540   int addrp = t->address + dilated1[t->cd][xt] + dilated0[t->cd][yt];
541   int c = (reinterpret_cast<UINT8 *>(dc_texture_ram))[BYTE_XOR_LE(addrp)];
542   return cv_565(pvrta_regs[t->palbase + c]);
543}
544
545UINT32 powervr2_device::tex_r_p8_565_vq(texinfo *t, float x, float y)
546{
547   int xt = ((int)x) & (t->sizex-1);
548   int yt = ((int)y) & (t->sizey-1);
549   int idx = (reinterpret_cast<UINT8 *>(dc_texture_ram))[BYTE_XOR_LE(t->address + dilated1[t->cd][xt >> 1] + dilated0[t->cd][yt >> 1])];
550   int addrp = t->vqbase + 8*idx + dilated1[t->cd][xt & 1] + dilated0[t->cd][yt & 3];
551   int c = (reinterpret_cast<UINT8 *>(dc_texture_ram))[BYTE_XOR_LE(addrp)];
552   return cv_565(pvrta_regs[t->palbase + c]);
553}
554
555UINT32 powervr2_device::tex_r_p8_4444_tw(texinfo *t, float x, float y)
556{
557   int xt = ((int)x) & (t->sizex-1);
558   int yt = ((int)y) & (t->sizey-1);
559   int addrp = t->address + dilated1[t->cd][xt] + dilated0[t->cd][yt];
560   int c = (reinterpret_cast<UINT8 *>(dc_texture_ram))[BYTE_XOR_LE(addrp)];
561   return cv_4444(pvrta_regs[t->palbase + c]);
562}
563
564UINT32 powervr2_device::tex_r_p8_4444_vq(texinfo *t, float x, float y)
565{
566   int xt = ((int)x) & (t->sizex-1);
567   int yt = ((int)y) & (t->sizey-1);
568   int idx = (reinterpret_cast<UINT8 *>(dc_texture_ram))[BYTE_XOR_LE(t->address + dilated1[t->cd][xt >> 1] + dilated0[t->cd][yt >> 1])];
569   int addrp = t->vqbase + 8*idx + dilated1[t->cd][xt & 1] + dilated0[t->cd][yt & 3];
570   int c = (reinterpret_cast<UINT8 *>(dc_texture_ram))[BYTE_XOR_LE(addrp)];
571   return cv_4444(pvrta_regs[t->palbase + c]);
572}
573
574UINT32 powervr2_device::tex_r_p8_8888_tw(texinfo *t, float x, float y)
575{
576   int xt = ((int)x) & (t->sizex-1);
577   int yt = ((int)y) & (t->sizey-1);
578   int addrp = t->address + dilated1[t->cd][xt] + dilated0[t->cd][yt];
579   int c = (reinterpret_cast<UINT8 *>(dc_texture_ram))[BYTE_XOR_LE(addrp)];
580   return pvrta_regs[t->palbase + c];
581}
582
583UINT32 powervr2_device::tex_r_p8_8888_vq(texinfo *t, float x, float y)
584{
585   int xt = ((int)x) & (t->sizex-1);
586   int yt = ((int)y) & (t->sizey-1);
587   int idx = (reinterpret_cast<UINT8 *>(dc_texture_ram))[BYTE_XOR_LE(t->address + dilated1[t->cd][xt >> 1] + dilated0[t->cd][yt >> 1])];
588   int addrp = t->vqbase + 8*idx + dilated1[t->cd][xt & 1] + dilated0[t->cd][yt & 3];
589   int c = (reinterpret_cast<UINT8 *>(dc_texture_ram))[BYTE_XOR_LE(addrp)];
590   return pvrta_regs[t->palbase + c];
591}
592
593
594UINT32 powervr2_device::tex_r_default(texinfo *t, float x, float y)
595{
596   return ((int)x ^ (int)y) & 4 ? 0xffffff00 : 0xff0000ff;
597}
598
599void powervr2_device::tex_get_info(texinfo *t)
600{
601   int miptype = 0;
602
603   t->textured    = texture;
604
605   // not textured, abort.
606   if (!t->textured) return;
607
608   t->address     = textureaddress;
609   t->pf          = pixelformat;
610   t->palette     = 0;
611
612   t->mode = (vqcompressed<<1);
613
614   // scanorder is ignored for palettized textures (palettized textures are ALWAYS twiddled)
615   // (the same bits are used for palette select instead)
616   if ((t->pf == 5) || (t->pf == 6))
617   {
618      t->palette = paletteselector;
619   }
620   else
621   {
622      t->mode |= scanorder;
623   }
624
625   /* When scan order is 1 (non-twiddled) mipmap is ignored */
626   t->mipmapped  = t->mode & 1 ? 0 : mipmapped;
627
628   // Mipmapped textures are always square, ignore v size
629   if (t->mipmapped)
630   {
631      t->sizes = (texturesizes & 0x38) | ((texturesizes & 0x38) >> 3);
632   }
633   else
634   {
635      t->sizes = texturesizes;
636   }
637
638   t->sizex = 1 << (3+((t->sizes >> 3) & 7));
639   t->sizey = 1 << (3+(t->sizes & 7));
640
641
642   /* Stride select is used only in the non-twiddled case */
643   t->stride = (t->mode & 1) && strideselect ? (pvrta_regs[TEXT_CONTROL] & 0x1f) << 5 : t->sizex;
644
645   t->blend_mode  = blend_mode;
646   t->filter_mode = filtermode;
647   t->flip_u      = (flipuv >> 1) & 1;
648   t->flip_v      = flipuv & 1;
649
650   t->r = &powervr2_device::tex_r_default;
651   t->cd = dilatechose[t->sizes];
652   t->palbase = 0;
653   t->vqbase = t->address;
654   t->blend = use_alpha ? blend_functions[t->blend_mode] : bl10;
655
656   //  fprintf(stderr, "tex %d %d %d %d\n", t->pf, t->mode, pvrta_regs[PAL_RAM_CTRL], t->mipmapped);
657
658   switch(t->pf) {
659   case 0: // 1555
660      switch(t->mode) {
661      case 0:  t->r = &powervr2_device::tex_r_1555_tw; miptype = 2; break;
662      case 1:  t->r = &powervr2_device::tex_r_1555_n;  miptype = 2; break;
663      case 2:
664      case 3:  t->r = &powervr2_device::tex_r_1555_vq; miptype = 3; t->address += 0x800; break;
665
666      default:
667         //
668         break;
669      }
670      break;
671
672   case 1: // 565
673      switch(t->mode) {
674      case 0:  t->r = &powervr2_device::tex_r_565_tw; miptype = 2; break;
675      case 1:  t->r = &powervr2_device::tex_r_565_n;  miptype = 2; break;
676      case 2:
677      case 3:  t->r = &powervr2_device::tex_r_565_vq; miptype = 3; t->address += 0x800; break;
678
679      default:
680         //
681         break;
682      }
683      break;
684
685   case 2: // 4444
686      switch(t->mode) {
687      case 0:  t->r = &powervr2_device::tex_r_4444_tw; miptype = 2; break;
688      case 1:  t->r = &powervr2_device::tex_r_4444_n;  miptype = 2; break;
689      case 2:
690      case 3:  t->r = &powervr2_device::tex_r_4444_vq; miptype = 3; t->address += 0x800; break;
691
692      default:
693         //
694         break;
695      }
696      break;
697
698   case 3: // yuv422
699      switch(t->mode) {
700      case 0:  /*t->r = &powervr2_device::tex_r_yuv_tw*/; miptype = -1; break;
701      case 1:  t->r = &powervr2_device::tex_r_yuv_n; miptype = -1; break;
702      default: /*t->r = &powervr2_device::tex_r_yuv_vq*/; miptype = -1; break;
703      }
704      break;
705
706   case 4: // bumpmap
707      break;
708
709   case 5: // 4bpp palette
710      t->palbase = 0x400 | ((t->palette & 0x3f) << 4);
711      switch(t->mode) {
712      case 0: case 1:
713         miptype = 0;
714
715         switch(pvrta_regs[PAL_RAM_CTRL]) {
716         case 0: t->r = &powervr2_device::tex_r_p4_1555_tw; break;
717         case 1: t->r = &powervr2_device::tex_r_p4_565_tw;  break;
718         case 2: t->r = &powervr2_device::tex_r_p4_4444_tw; break;
719         case 3: t->r = &powervr2_device::tex_r_p4_8888_tw; break;
720         }
721         break;
722      case 2: case 3:
723         miptype = 3; // ?
724         switch(pvrta_regs[PAL_RAM_CTRL]) {
725         case 0: t->r = &powervr2_device::tex_r_p4_1555_vq; t->address += 0x800; break;
726         case 1: t->r = &powervr2_device::tex_r_p4_565_vq;  t->address += 0x800; break;
727         case 2: t->r = &powervr2_device::tex_r_p4_4444_vq; t->address += 0x800; break;
728         case 3: t->r = &powervr2_device::tex_r_p4_8888_vq; t->address += 0x800; break;
729         }
730         break;
731
732      default:
733         //
734         break;
735      }
736      break;
737
738   case 6: // 8bpp palette
739      t->palbase = 0x400 | ((t->palette & 0x30) << 4);
740      switch(t->mode) {
741      case 0: case 1:
742         miptype = 1;
743
744         switch(pvrta_regs[PAL_RAM_CTRL]) {
745         case 0: t->r = &powervr2_device::tex_r_p8_1555_tw; break;
746         case 1: t->r = &powervr2_device::tex_r_p8_565_tw; break;
747         case 2: t->r = &powervr2_device::tex_r_p8_4444_tw; break;
748         case 3: t->r = &powervr2_device::tex_r_p8_8888_tw; break;
749         }
750         break;
751      case 2: case 3:
752         miptype = 3; // ?
753         switch(pvrta_regs[PAL_RAM_CTRL]) {
754         case 0: t->r = &powervr2_device::tex_r_p8_1555_vq; t->address += 0x800; break;
755         case 1: t->r = &powervr2_device::tex_r_p8_565_vq;  t->address += 0x800; break;
756         case 2: t->r = &powervr2_device::tex_r_p8_4444_vq; t->address += 0x800; break;
757         case 3: t->r = &powervr2_device::tex_r_p8_8888_vq; t->address += 0x800; break;
758         }
759         break;
760
761      default:
762         //
763         break;
764      }
765      break;
766
767   case 9: // reserved
768      break;
769   }
770
771   if (t->mipmapped)
772   {
773      // full offset tables for reference,
774      // we don't do mipmapping, so don't use anything < 8x8
775      // first table is half-bytes
776
777      // 4BPP palette textures
778      // Texture size _4-bit_ offset value for starting address
779      // 1x1          0x00003
780      // 2x2          0x00004
781      // 4x4          0x00008
782      // 8x8          0x00018
783      // 16x16        0x00058
784      // 32x32        0x00158
785      // 64x64        0x00558
786      // 128x128      0x01558
787      // 256x256      0x05558
788      // 512x512      0x15558
789      // 1024x1024    0x55558
790
791      // 8BPP palette textures
792      // Texture size Byte offset value for starting address
793      // 1x1          0x00003
794      // 2x2          0x00004
795      // 4x4          0x00008
796      // 8x8          0x00018
797      // 16x16        0x00058
798      // 32x32        0x00158
799      // 64x64        0x00558
800      // 128x128      0x01558
801      // 256x256      0x05558
802      // 512x512      0x15558
803      // 1024x1024    0x55558
804
805      // Non-palette textures
806      // Texture size Byte offset value for starting address
807      // 1x1          0x00006
808      // 2x2          0x00008
809      // 4x4          0x00010
810      // 8x8          0x00030
811      // 16x16        0x000B0
812      // 32x32        0x002B0
813      // 64x64        0x00AB0
814      // 128x128      0x02AB0
815      // 256x256      0x0AAB0
816      // 512x512      0x2AAB0
817      // 1024x1024    0xAAAB0
818
819      // VQ textures
820      // Texture size Byte offset value for starting address
821      // 1x1          0x00000
822      // 2x2          0x00001
823      // 4x4          0x00002
824      // 8x8          0x00006
825      // 16x16        0x00016
826      // 32x32        0x00056
827      // 64x64        0x00156
828      // 128x128      0x00556
829      // 256x256      0x01556
830      // 512x512      0x05556
831      // 1024x1024    0x15556
832
833      static const int mipmap_4_8_offset[8] = { 0x00018, 0x00058, 0x00158, 0x00558, 0x01558, 0x05558, 0x15558, 0x55558 };  // 4bpp (4bit offset) / 8bpp (8bit offset)
834      static const int mipmap_np_offset[8] =  { 0x00030, 0x000B0, 0x002B0, 0x00AB0, 0x02AB0, 0x0AAB0, 0x2AAB0, 0xAAAB0 };  // nonpalette textures
835      static const int mipmap_vq_offset[8] =  { 0x00006, 0x00016, 0x00056, 0x00156, 0x00556, 0x01556, 0x05556, 0x15556 }; // vq textures
836
837      switch (miptype)
838      {
839         case 0: // 4bpp
840            //printf("4bpp\n");
841            t->address += mipmap_4_8_offset[(t->sizes)&7]>>1;
842            break;
843
844         case 1: // 8bpp
845            //printf("8bpp\n");
846            t->address += mipmap_4_8_offset[(t->sizes)&7];
847            break;
848
849         case 2: // nonpalette
850            //printf("np\n");
851            t->address += mipmap_np_offset[(t->sizes)&7];
852            break;
853
854         case 3: // vq
855            //printf("vq\n");
856            t->address += mipmap_vq_offset[(t->sizes)&7];
857            break;
858      }
859   }
860
861}
862
863// register decode helper
864static inline int decode_reg_64(UINT32 offset, UINT64 mem_mask, UINT64 *shift)
865{
866   int reg = offset * 2;
867
868   *shift = 0;
869
870   // non 32-bit accesses have not yet been seen here, we need to know when they are
871   if ((mem_mask != U64(0xffffffff00000000)) && (mem_mask != U64(0x00000000ffffffff)))
872   {
873      /*assume to return the lower 32-bits ONLY*/
874      return reg & 0xffffffff;
875   }
876
877   if (mem_mask == U64(0xffffffff00000000))
878   {
879      reg++;
880      *shift = 32;
881   }
882
883   return reg;
884}
885
886READ64_MEMBER( powervr2_device::pvr_ta_r )
887{
888   int reg;
889   UINT64 shift;
890
891   reg = decode_reg_64(offset, mem_mask, &shift);
892
893   switch (reg)
894   {
895   case SPG_STATUS:
896      {
897         UINT8 fieldnum,vsync,hsync,blank;
898
899         fieldnum = (space.machine().primary_screen->frame_number() & 1) ? 1 : 0;
900
901         vsync = space.machine().primary_screen->vblank() ? 1 : 0;
902         if(spg_vsync_pol) { vsync^=1; }
903
904         hsync = space.machine().primary_screen->hblank() ? 1 : 0;
905         if(spg_hsync_pol) { hsync^=1; }
906
907         /* FIXME: following is just a wild guess */
908         blank = (space.machine().primary_screen->vblank() | space.machine().primary_screen->hblank()) ? 0 : 1;
909         if(spg_blank_pol) { blank^=1; }
910
911         pvrta_regs[reg] = (vsync << 13) | (hsync << 12) | (blank << 11) | (fieldnum << 10) | (space.machine().primary_screen->vpos() & 0x3ff);
912         break;
913      }
914   case SPG_TRIGGER_POS:
915      printf("Warning: read at h/v counter ext latches\n");
916      break;
917   case TA_LIST_INIT:
918      return 0; //bit 31 always return 0, a probable left-over in Crazy Taxi reads this and discards the read (?)
919   }
920
921   #if DEBUG_PVRTA_REGS
922   if (reg != 0x43)
923      mame_printf_verbose("PVRTA: [%08x] read %x @ %x (reg %x), mask %" I64FMT "x (PC=%x)\n", 0x5f8000+reg*4, pvrta_regs[reg], offset, reg, mem_mask, space.device().safe_pc());
924   #endif
925   return (UINT64)pvrta_regs[reg] << shift;
926}
927
928WRITE64_MEMBER( powervr2_device::pvr_ta_w )
929{
930   int reg;
931   UINT64 shift;
932   UINT32 dat;
933   UINT32 sizera,offsetra;
934   int a;
935   int sanitycount;
936
937   reg = decode_reg_64(offset, mem_mask, &shift);
938   dat = (UINT32)(data >> shift);
939   //old = pvrta_regs[reg];
940
941   // Dreamcast BIOS attempts to set PVRID to zero and then dies
942   // if it succeeds.  Don't allow.
943   if ((reg != PVRID) && (reg != REVISION))
944   {
945      pvrta_regs[reg] = dat; // 5f8000+reg*4=dat
946   }
947
948   switch (reg)
949   {
950   case SOFTRESET:
951      if (dat & 1)
952      {
953         #if DEBUG_PVRTA
954         mame_printf_verbose("pvr_ta_w:  TA soft reset\n");
955         #endif
956         listtype_used=0;
957      }
958      if (dat & 2)
959      {
960         #if DEBUG_PVRTA
961         mame_printf_verbose("pvr_ta_w:  Core Pipeline soft reset\n");
962         #endif
963         if (start_render_received == 1)
964         {
965            for (a=0;a < NUM_BUFFERS;a++)
966               if (grab[a].busy == 1)
967                  grab[a].busy = 0;
968            start_render_received = 0;
969         }
970      }
971      if (dat & 4)
972      {
973         #if DEBUG_PVRTA
974         mame_printf_verbose("pvr_ta_w:  sdram I/F soft reset\n");
975         #endif
976      }
977      break;
978   case STARTRENDER:
979      g_profiler.start(PROFILER_USER1);
980      #if DEBUG_PVRTA
981      mame_printf_verbose("Start Render Received:\n");
982      mame_printf_verbose("  Region Array at %08x\n",pvrta_regs[REGION_BASE]);
983      mame_printf_verbose("  ISP/TSP Parameters at %08x\n",pvrta_regs[PARAM_BASE]);
984
985      #endif
986      // select buffer to draw using PARAM_BASE
987      for (a=0;a < NUM_BUFFERS;a++)
988      {
989         if ((grab[a].ispbase == pvrta_regs[PARAM_BASE]) && (grab[a].valid == 1) && (grab[a].busy == 0))
990         {
991            grab[a].busy = 1;
992            renderselect = a;
993            start_render_received=1;
994
995
996            grab[a].fbwsof1=pvrta_regs[FB_W_SOF1];
997            grab[a].fbwsof2=pvrta_regs[FB_W_SOF2];
998
999            rectangle clip(0, 1023, 0, 1023);
1000
1001            // we've got a request to draw, so, draw to the accumulation buffer!
1002            // this should really be done for each tile!
1003            render_to_accumulation_buffer(*fake_accumulationbuffer_bitmap,clip);
1004
1005            endofrender_timer_isp->adjust(attotime::from_usec(4000) ); // hack, make sure render takes some amount of time
1006
1007            /* copy the tiles to the framebuffer (really the rendering should be in this loop too) */
1008            if (pvrta_regs[FPU_PARAM_CFG] & 0x200000)
1009               sizera=6;
1010            else
1011               sizera=5;
1012            offsetra=pvrta_regs[REGION_BASE];
1013
1014            //printf("base is %08x\n", offsetra);
1015
1016            // sanity
1017            sanitycount = 0;
1018            for (;;)
1019            {
1020               UINT32 st[6];
1021
1022               st[0]=space.read_dword((0x05000000+offsetra));
1023               st[1]=space.read_dword((0x05000004+offsetra)); // Opaque List Pointer
1024               st[2]=space.read_dword((0x05000008+offsetra)); // Opaque Modifier Volume List Pointer
1025               st[3]=space.read_dword((0x0500000c+offsetra)); // Translucent List Pointer
1026               st[4]=space.read_dword((0x05000010+offsetra)); // Translucent Modifier Volume List Pointer
1027
1028               if (sizera == 6)
1029               {
1030                  st[5] = space.read_dword((0x05000014+offsetra)); // Punch Through List Pointer
1031                  offsetra+=0x18;
1032               }
1033               else
1034               {
1035                  st[5] = 0;
1036                  offsetra+=0x14;
1037               }
1038
1039               {
1040                  int x = ((st[0]&0x000000fc)>>2)*32;
1041                  int y = ((st[0]&0x00003f00)>>8)*32;
1042                  //printf("tiledata %08x %d %d - %08x %08x %08x %08x %08x\n",st[0],x,y,st[1],st[2],st[3],st[4],st[5]);
1043
1044                  // should render to the accumulation buffer here using pointers we filled in when processing the data
1045                  // sent to the TA.  HOWEVER, we don't process the TA data and create the real format object lists, so
1046                  // instead just use these co-ordinates to copy data from our fake full-screnen accumnulation buffer into
1047                  // the framebuffer
1048
1049                  pvr_accumulationbuffer_to_framebuffer(space, x,y);
1050               }
1051
1052               if (st[0] & 0x80000000)
1053                  break;
1054
1055               // prevent infinite loop if asked to process invalid data
1056               if(sanitycount>2000)
1057                  break;
1058            }
1059
1060
1061
1062
1063            break;
1064         }
1065      }
1066      if (a != NUM_BUFFERS)
1067         break;
1068      assert_always(0, "TA grabber error A!\n");
1069      break;
1070   case TA_LIST_INIT:
1071      if(dat & 0x80000000)
1072      {
1073         tafifo_pos=0;
1074         tafifo_mask=7;
1075         tafifo_vertexwords=8;
1076         tafifo_listtype= -1;
1077   #if DEBUG_PVRTA
1078         mame_printf_verbose("TA_OL_BASE       %08x TA_OL_LIMIT  %08x\n", pvrta_regs[TA_OL_BASE], pvrta_regs[TA_OL_LIMIT]);
1079         mame_printf_verbose("TA_ISP_BASE      %08x TA_ISP_LIMIT %08x\n", pvrta_regs[TA_ISP_BASE], pvrta_regs[TA_ISP_LIMIT]);
1080         mame_printf_verbose("TA_ALLOC_CTRL    %08x\n", pvrta_regs[TA_ALLOC_CTRL]);
1081         mame_printf_verbose("TA_NEXT_OPB_INIT %08x\n", pvrta_regs[TA_NEXT_OPB_INIT]);
1082   #endif
1083         pvrta_regs[TA_NEXT_OPB] = pvrta_regs[TA_NEXT_OPB_INIT];
1084         pvrta_regs[TA_ITP_CURRENT] = pvrta_regs[TA_ISP_BASE];
1085         alloc_ctrl_OPB_Mode = pvrta_regs[TA_ALLOC_CTRL] & 0x100000; // 0 up 1 down
1086         alloc_ctrl_PT_OPB = (4 << ((pvrta_regs[TA_ALLOC_CTRL] >> 16) & 3)) & 0x38; // number of 32 bit words (0,8,16,32)
1087         alloc_ctrl_TM_OPB = (4 << ((pvrta_regs[TA_ALLOC_CTRL] >> 12) & 3)) & 0x38;
1088         alloc_ctrl_T_OPB = (4 << ((pvrta_regs[TA_ALLOC_CTRL] >> 8) & 3)) & 0x38;
1089         alloc_ctrl_OM_OPB = (4 << ((pvrta_regs[TA_ALLOC_CTRL] >> 4) & 3)) & 0x38;
1090         alloc_ctrl_O_OPB = (4 << ((pvrta_regs[TA_ALLOC_CTRL] >> 0) & 3)) & 0x38;
1091         listtype_used |= (1+4);
1092         // use TA_ISP_BASE and select buffer for grab data
1093         grabsel = -1;
1094         // try to find already used buffer but not busy
1095         for (a=0;a < NUM_BUFFERS;a++)
1096         {
1097            if ((grab[a].ispbase == pvrta_regs[TA_ISP_BASE]) && (grab[a].busy == 0) && (grab[a].valid == 1))
1098            {
1099               grabsel=a;
1100               break;
1101            }
1102         }
1103         // try a buffer not used yet
1104         if (grabsel < 0)
1105         {
1106            for (a=0;a < NUM_BUFFERS;a++)
1107            {
1108               if (grab[a].valid == 0)
1109               {
1110                  grabsel=a;
1111                  break;
1112               }
1113            }
1114         }
1115         // find a non busy buffer starting from the last one used
1116         if (grabsel < 0)
1117         {
1118            for (a=0;a < 3;a++)
1119            {
1120               if (grab[(grabsellast+1+a) & 3].busy == 0)
1121               {
1122                  grabsel=a;
1123                  break;
1124               }
1125            }
1126         }
1127         if (grabsel < 0)
1128            assert_always(0, "TA grabber error B!\n");
1129         grabsellast=grabsel;
1130         grab[grabsel].ispbase=pvrta_regs[TA_ISP_BASE];
1131         grab[grabsel].busy=0;
1132         grab[grabsel].valid=1;
1133         grab[grabsel].verts_size=0;
1134         grab[grabsel].strips_size=0;
1135
1136         g_profiler.stop();
1137      }
1138      break;
1139//#define TA_YUV_TEX_BASE       ((0x005f8148-0x005f8000)/4)
1140   case TA_YUV_TEX_BASE:
1141      printf("TA_YUV_TEX_BASE initialized to %08x\n", dat);
1142
1143      // hack, this interrupt is generated after transfering a set amount of data
1144      //state->state->dc_sysctrl_regs[SB_ISTNRM] |= IST_EOXFER_YUV;
1145      //state->state->dc_update_interrupt_status();
1146
1147      break;
1148   case TA_YUV_TEX_CTRL:
1149      printf("TA_YUV_TEX_CTRL initialized to %08x\n", dat);
1150      break;
1151
1152   case SPG_VBLANK_INT:
1153      /* clear pending irqs and modify them with the updated ones */
1154      vbin_timer->adjust(attotime::never);
1155      vbout_timer->adjust(attotime::never);
1156
1157      vbin_timer->adjust(space.machine().primary_screen->time_until_pos(spg_vblank_in_irq_line_num));
1158      vbout_timer->adjust(space.machine().primary_screen->time_until_pos(spg_vblank_out_irq_line_num));
1159      break;
1160   /* TODO: timer adjust for SPG_HBLANK_INT too */
1161   case TA_LIST_CONT:
1162   #if DEBUG_PVRTA
1163      mame_printf_verbose("List continuation processing\n");
1164   #endif
1165      if(dat & 0x80000000)
1166      {
1167         tafifo_listtype= -1; // no list being received
1168         listtype_used |= (1+4);
1169      }
1170      break;
1171   case SPG_VBLANK:
1172   case SPG_HBLANK:
1173   case SPG_LOAD:
1174   case VO_STARTX:
1175   case VO_STARTY:
1176      {
1177         rectangle visarea = space.machine().primary_screen->visible_area();
1178         /* FIXME: right visible area calculations aren't known yet*/
1179         visarea.min_x = 0;
1180         visarea.max_x = ((spg_hbstart - spg_hbend - vo_horz_start_pos) <= 0x180 ? 320 : 640) - 1;
1181         visarea.min_y = 0;
1182         visarea.max_y = ((spg_vbstart - spg_vbend - vo_vert_start_pos_f1) <= 0x100 ? 240 : 480) - 1;
1183
1184
1185         space.machine().primary_screen->configure(spg_hbstart, spg_vbstart, visarea, space.machine().primary_screen->frame_period().attoseconds );
1186      }
1187      break;
1188   }
1189
1190   #if DEBUG_PVRTA_REGS
1191   if ((reg != 0x14) && (reg != 0x15))
1192      mame_printf_verbose("PVRTA: [%08x=%x] write %" I64FMT "x to %x (reg %x %x), mask %" I64FMT "x\n", 0x5f8000+reg*4, dat, data>>shift, offset, reg, (reg*4)+0x8000, mem_mask);
1193   #endif
1194}
1195
1196TIMER_CALLBACK_MEMBER(powervr2_device::transfer_opaque_list_irq)
1197{
1198   dc_state *state = machine().driver_data<dc_state>();
1199   state->dc_sysctrl_regs[SB_ISTNRM] |= IST_EOXFER_OPLST;
1200   state->dc_update_interrupt_status();
1201}
1202
1203TIMER_CALLBACK_MEMBER(powervr2_device::transfer_opaque_modifier_volume_list_irq)
1204{
1205   dc_state *state = machine().driver_data<dc_state>();
1206   state->dc_sysctrl_regs[SB_ISTNRM] |= IST_EOXFER_OPMV;
1207   state->dc_update_interrupt_status();
1208}
1209
1210TIMER_CALLBACK_MEMBER(powervr2_device::transfer_translucent_list_irq)
1211{
1212   dc_state *state = machine().driver_data<dc_state>();
1213   state->dc_sysctrl_regs[SB_ISTNRM] |= IST_EOXFER_TRLST;
1214   state->dc_update_interrupt_status();
1215}
1216
1217TIMER_CALLBACK_MEMBER(powervr2_device::transfer_translucent_modifier_volume_list_irq)
1218{
1219   dc_state *state = machine().driver_data<dc_state>();
1220   state->dc_sysctrl_regs[SB_ISTNRM] |= IST_EOXFER_TRMV;
1221   state->dc_update_interrupt_status();
1222}
1223
1224TIMER_CALLBACK_MEMBER(powervr2_device::transfer_punch_through_list_irq)
1225{
1226   dc_state *state = machine().driver_data<dc_state>();
1227   state->dc_sysctrl_regs[SB_ISTNRM] |= (1 << 21);
1228   state->dc_update_interrupt_status();
1229}
1230
1231void powervr2_device::process_ta_fifo()
1232{
1233   /* first byte in the buffer is the Parameter Control Word
1234
1235    pppp pppp gggg gggg oooo oooo oooo oooo
1236
1237    p = para control
1238    g = group control
1239    o = object control
1240
1241   */
1242
1243   receiveddata *rd = &grab[grabsel];
1244
1245   // Para Control
1246   paracontrol=(tafifo_buff[0] >> 24) & 0xff;
1247   // 0 end of list
1248   // 1 user tile clip
1249   // 2 object list set
1250   // 3 reserved
1251   // 4 polygon/modifier volume
1252   // 5 sprite
1253   // 6 reserved
1254   // 7 vertex
1255   paratype=(paracontrol >> 5) & 7;
1256   endofstrip=(paracontrol >> 4) & 1;
1257   listtype=(paracontrol >> 0) & 7;
1258   if ((paratype >= 4) && (paratype <= 6))
1259   {
1260      global_paratype = paratype;
1261      // Group Control
1262      groupcontrol=(tafifo_buff[0] >> 16) & 0xff;
1263      groupen=(groupcontrol >> 7) & 1;
1264      striplen=(groupcontrol >> 2) & 3;
1265      userclip=(groupcontrol >> 0) & 3;
1266      // Obj Control
1267      objcontrol=(tafifo_buff[0] >> 0) & 0xffff;
1268      shadow=(objcontrol >> 7) & 1;
1269      volume=(objcontrol >> 6) & 1;
1270      coltype=(objcontrol >> 4) & 3;
1271      texture=(objcontrol >> 3) & 1;
1272      offfset=(objcontrol >> 2) & 1;
1273      gouraud=(objcontrol >> 1) & 1;
1274      uv16bit=(objcontrol >> 0) & 1;
1275   }
1276
1277   // check if we need 8 words more
1278   if (tafifo_mask == 7)
1279   {
1280      parameterconfig = pvr_parameterconfig[objcontrol & 0x3d];
1281      // decide number of words per vertex
1282      if (paratype == 7)
1283      {
1284         if ((global_paratype == 5) || (tafifo_listtype == 1) || (tafifo_listtype == 3))
1285            tafifo_vertexwords = 16;
1286         if (tafifo_vertexwords == 16)
1287         {
1288            tafifo_mask = 15;
1289            tafifo_pos = 8;
1290            return;
1291         }
1292      }
1293      // decide number of words when not a vertex
1294      tafifo_vertexwords=pvr_wordsvertex[parameterconfig];
1295      if ((paratype == 4) && ((listtype != 1) && (listtype != 3)))
1296         if (pvr_wordspolygon[parameterconfig] == 16)
1297         {
1298            tafifo_mask = 15;
1299            tafifo_pos = 8;
1300            return;
1301         }
1302   }
1303   tafifo_mask = 7;
1304
1305   // now we heve all the needed words
1306   // here we should generate the data for the various tiles
1307   // for now, just interpret their meaning
1308   if (paratype == 0)
1309   { // end of list
1310      #if DEBUG_PVRDLIST
1311      mame_printf_verbose("Para Type 0 End of List\n");
1312      #endif
1313      /* Process transfer FIFO done irqs here */
1314      /* FIXME: timing of these */
1315      switch (tafifo_listtype)
1316      {
1317      case 0: machine().scheduler().timer_set(attotime::from_usec(100), timer_expired_delegate(FUNC(powervr2_device::transfer_opaque_list_irq), this)); break;
1318      case 1: machine().scheduler().timer_set(attotime::from_usec(100), timer_expired_delegate(FUNC(powervr2_device::transfer_opaque_modifier_volume_list_irq), this)); break;
1319      case 2: machine().scheduler().timer_set(attotime::from_usec(100), timer_expired_delegate(FUNC(powervr2_device::transfer_translucent_list_irq), this)); break;
1320      case 3: machine().scheduler().timer_set(attotime::from_usec(100), timer_expired_delegate(FUNC(powervr2_device::transfer_translucent_modifier_volume_list_irq), this)); break;
1321      case 4: machine().scheduler().timer_set(attotime::from_usec(100), timer_expired_delegate(FUNC(powervr2_device::transfer_punch_through_list_irq), this)); break;
1322      }
1323      tafifo_listtype= -1; // no list being received
1324      listtype_used |= (2+8);
1325   }
1326   else if (paratype == 1)
1327   { // user tile clip
1328      #if DEBUG_PVRDLIST
1329      mame_printf_verbose("Para Type 1 User Tile Clip\n");
1330      mame_printf_verbose(" (%d , %d)-(%d , %d)\n", tafifo_buff[4], tafifo_buff[5], tafifo_buff[6], tafifo_buff[7]);
1331      #endif
1332   }
1333   else if (paratype == 2)
1334   { // object list set
1335      #if DEBUG_PVRDLIST
1336      mame_printf_verbose("Para Type 2 Object List Set at %08x\n", tafifo_buff[1]);
1337      mame_printf_verbose(" (%d , %d)-(%d , %d)\n", tafifo_buff[4], tafifo_buff[5], tafifo_buff[6], tafifo_buff[7]);
1338      #endif
1339   }
1340   else if (paratype == 3)
1341   {
1342      #if DEBUG_PVRDLIST
1343      mame_printf_verbose("Para Type %x Unknown!\n", tafifo_buff[0]);
1344      #endif
1345   }
1346   else
1347   { // global parameter or vertex parameter
1348      #if DEBUG_PVRDLIST
1349      mame_printf_verbose("Para Type %d", paratype);
1350      if (paratype == 7)
1351         mame_printf_verbose(" End of Strip %d", endofstrip);
1352      if (listtype_used & 3)
1353         mame_printf_verbose(" List Type %d", listtype);
1354      mame_printf_verbose("\n");
1355      #endif
1356
1357      // set type of list currently being received
1358      if ((paratype == 4) || (paratype == 5) || (paratype == 6))
1359      {
1360         if (tafifo_listtype < 0)
1361         {
1362            tafifo_listtype = listtype;
1363         }
1364      }
1365      listtype_used = listtype_used ^ (listtype_used & 3);
1366
1367      if ((paratype == 4) || (paratype == 5))
1368      { // quad or polygon
1369         depthcomparemode=(tafifo_buff[1] >> 29) & 7;
1370         cullingmode=(tafifo_buff[1] >> 27) & 3;
1371         zwritedisable=(tafifo_buff[1] >> 26) & 1;
1372         cachebypass=(tafifo_buff[1] >> 21) & 1;
1373         dcalcctrl=(tafifo_buff[1] >> 20) & 1;
1374         volumeinstruction=(tafifo_buff[1] >> 29) & 7;
1375
1376         //textureusize=1 << (3+((tafifo_buff[2] >> 3) & 7));
1377         //texturevsize=1 << (3+(tafifo_buff[2] & 7));
1378         texturesizes=tafifo_buff[2] & 0x3f;
1379         blend_mode = tafifo_buff[2] >> 26;
1380         srcselect=(tafifo_buff[2] >> 25) & 1;
1381         dstselect=(tafifo_buff[2] >> 24) & 1;
1382         fogcontrol=(tafifo_buff[2] >> 22) & 3;
1383         colorclamp=(tafifo_buff[2] >> 21) & 1;
1384         use_alpha = (tafifo_buff[2] >> 20) & 1;
1385         ignoretexalpha=(tafifo_buff[2] >> 19) & 1;
1386         flipuv=(tafifo_buff[2] >> 17) & 3;
1387         clampuv=(tafifo_buff[2] >> 15) & 3;
1388         filtermode=(tafifo_buff[2] >> 13) & 3;
1389         sstexture=(tafifo_buff[2] >> 12) & 1;
1390         mmdadjust=(tafifo_buff[2] >> 8) & 1;
1391         tsinstruction=(tafifo_buff[2] >> 6) & 3;
1392         if (texture == 1)
1393         {
1394            textureaddress=(tafifo_buff[3] & 0x1FFFFF) << 3;
1395            scanorder=(tafifo_buff[3] >> 26) & 1;
1396            pixelformat=(tafifo_buff[3] >> 27) & 7;
1397            mipmapped=(tafifo_buff[3] >> 31) & 1;
1398            vqcompressed=(tafifo_buff[3] >> 30) & 1;
1399            strideselect=(tafifo_buff[3] >> 25) & 1;
1400            paletteselector=(tafifo_buff[3] >> 21) & 0x3F;
1401            #if DEBUG_PVRDLIST
1402            mame_printf_verbose(" Texture at %08x format %d\n", (tafifo_buff[3] & 0x1FFFFF) << 3, pixelformat);
1403            #endif
1404         }
1405         if (paratype == 4)
1406         { // polygon or mv
1407            if ((tafifo_listtype == 1) || (tafifo_listtype == 3))
1408            {
1409            #if DEBUG_PVRDLIST
1410               mame_printf_verbose(" Modifier Volume\n");
1411            #endif
1412            }
1413            else
1414            {
1415            #if DEBUG_PVRDLIST
1416               mame_printf_verbose(" Polygon\n");
1417            #endif
1418            }
1419         }
1420         if (paratype == 5)
1421         { // quad
1422            #if DEBUG_PVRDLIST
1423            mame_printf_verbose(" Sprite\n");
1424            #endif
1425         }
1426      }
1427
1428      if (paratype == 7)
1429      { // vertex
1430         if ((tafifo_listtype == 1) || (tafifo_listtype == 3))
1431         {
1432            #if DEBUG_PVRDLIST
1433            mame_printf_verbose(" Vertex modifier volume");
1434            mame_printf_verbose(" A(%f,%f,%f) B(%f,%f,%f) C(%f,%f,%f)", u2f(tafifo_buff[1]), u2f(tafifo_buff[2]),
1435               u2f(tafifo_buff[3]), u2f(tafifo_buff[4]), u2f(tafifo_buff[5]), u2f(tafifo_buff[6]), u2f(tafifo_buff[7]),
1436               u2f(tafifo_buff[8]), u2f(tafifo_buff[9]));
1437            mame_printf_verbose("\n");
1438            #endif
1439         }
1440         else if (global_paratype == 5)
1441         {
1442            #if DEBUG_PVRDLIST
1443            mame_printf_verbose(" Vertex sprite");
1444            mame_printf_verbose(" A(%f,%f,%f) B(%f,%f,%f) C(%f,%f,%f) D(%f,%f,)", u2f(tafifo_buff[1]), u2f(tafifo_buff[2]),
1445               u2f(tafifo_buff[3]), u2f(tafifo_buff[4]), u2f(tafifo_buff[5]), u2f(tafifo_buff[6]), u2f(tafifo_buff[7]),
1446               u2f(tafifo_buff[8]), u2f(tafifo_buff[9]), u2f(tafifo_buff[10]), u2f(tafifo_buff[11]));
1447            mame_printf_verbose("\n");
1448            #endif
1449            if (texture == 1)
1450            {
1451               if (rd->verts_size <= 65530)
1452               {
1453                  strip *ts;
1454                  vert *tv = &rd->verts[rd->verts_size];
1455                  tv[0].x = u2f(tafifo_buff[0x1]);
1456                  tv[0].y = u2f(tafifo_buff[0x2]);
1457                  tv[0].w = u2f(tafifo_buff[0x3]);
1458                  tv[1].x = u2f(tafifo_buff[0x4]);
1459                  tv[1].y = u2f(tafifo_buff[0x5]);
1460                  tv[1].w = u2f(tafifo_buff[0x6]);
1461                  tv[3].x = u2f(tafifo_buff[0x7]);
1462                  tv[3].y = u2f(tafifo_buff[0x8]);
1463                  tv[3].w = u2f(tafifo_buff[0x9]);
1464                  tv[2].x = u2f(tafifo_buff[0xa]);
1465                  tv[2].y = u2f(tafifo_buff[0xb]);
1466                  tv[2].w = tv[0].w+tv[3].w-tv[1].w;
1467                  tv[0].u = u2f(tafifo_buff[0xd] & 0xffff0000);
1468                  tv[0].v = u2f(tafifo_buff[0xd] << 16);
1469                  tv[1].u = u2f(tafifo_buff[0xe] & 0xffff0000);
1470                  tv[1].v = u2f(tafifo_buff[0xe] << 16);
1471                  tv[3].u = u2f(tafifo_buff[0xf] & 0xffff0000);
1472                  tv[3].v = u2f(tafifo_buff[0xf] << 16);
1473                  tv[2].u = tv[0].u+tv[3].u-tv[1].u;
1474                  tv[2].v = tv[0].v+tv[3].v-tv[1].v;
1475
1476                  ts = &rd->strips[rd->strips_size++];
1477                  tex_get_info(&ts->ti);
1478                  ts->svert = rd->verts_size;
1479                  ts->evert = rd->verts_size + 3;
1480
1481                  rd->verts_size += 4;
1482               }
1483            }
1484         }
1485         else if (global_paratype == 4)
1486         {
1487            #if DEBUG_PVRDLIST
1488            mame_printf_verbose(" Vertex polygon");
1489            mame_printf_verbose(" V(%f,%f,%f) T(%f,%f)", u2f(tafifo_buff[1]), u2f(tafifo_buff[2]), u2f(tafifo_buff[3]), u2f(tafifo_buff[4]), u2f(tafifo_buff[5]));
1490            mame_printf_verbose("\n");
1491            #endif
1492            if (rd->verts_size <= 65530)
1493            {
1494               /* add a vertex to our list */
1495               /* this is used for 3d stuff, ie most of the graphics (see guilty gear, confidential mission, maze of the kings etc.) */
1496               /* -- this is also wildly inaccurate! */
1497               vert *tv = &rd->verts[rd->verts_size];
1498
1499               tv->x=u2f(tafifo_buff[1]);
1500               tv->y=u2f(tafifo_buff[2]);
1501               tv->w=u2f(tafifo_buff[3]);
1502               tv->u=u2f(tafifo_buff[4]);
1503               tv->v=u2f(tafifo_buff[5]);
1504
1505
1506               if((!rd->strips_size) ||
1507                  rd->strips[rd->strips_size-1].evert != -1)
1508               {
1509                  strip *ts = &rd->strips[rd->strips_size++];
1510                  tex_get_info(&ts->ti);
1511                  ts->svert = rd->verts_size;
1512                  ts->evert = -1;
1513               }
1514               if(endofstrip)
1515                  rd->strips[rd->strips_size-1].evert = rd->verts_size;
1516               rd->verts_size++;
1517            }
1518         }
1519      }
1520   }
1521}
1522
1523WRITE64_MEMBER( powervr2_device::ta_fifo_poly_w )
1524{
1525   if (mem_mask == U64(0xffffffffffffffff))    // 64 bit
1526   {
1527      tafifo_buff[tafifo_pos]=(UINT32)data;
1528      tafifo_buff[tafifo_pos+1]=(UINT32)(data >> 32);
1529      #if DEBUG_FIFO_POLY
1530      mame_printf_debug("ta_fifo_poly_w:  Unmapped write64 %08x = %" I64FMT "x -> %08x %08x\n", 0x10000000+offset*8, data, tafifo_buff[tafifo_pos], tafifo_buff[tafifo_pos+1]);
1531      #endif
1532      tafifo_pos += 2;
1533   }
1534   else
1535   {
1536      fatalerror("ta_fifo_poly_w:  Only 64 bit writes supported!\n");
1537   }
1538
1539   tafifo_pos &= tafifo_mask;
1540
1541   // if the command is complete, process it
1542   if (tafifo_pos == 0)
1543      process_ta_fifo();
1544
1545}
1546
1547WRITE64_MEMBER( powervr2_device::ta_fifo_yuv_w )
1548{
1549   //dc_state *state = space.machine().driver_data<dc_state>();
1550
1551//  int reg;
1552//  UINT64 shift;
1553//  UINT32 dat;
1554
1555//  reg = decode_reg_64(offset, mem_mask, &shift);
1556//  dat = (UINT32)(data >> shift);
1557
1558//  printf("YUV FIFO: [%08x=%x] write %" I64FMT "x to %x, mask %" I64FMT "x %08x\n", 0x10800000+reg*4, dat, data, offset, mem_mask,test);
1559}
1560
1561// SB_LMMODE0
1562WRITE64_MEMBER(powervr2_device::ta_texture_directpath0_w )
1563{
1564   int mode = pvrctrl_regs[SB_LMMODE0]&1;
1565   if (mode&1)
1566   {
1567      printf("ta_texture_directpath0_w 32-bit access!\n");
1568      COMBINE_DATA(&dc_framebuffer_ram[offset]);
1569   }
1570   else
1571   {
1572      COMBINE_DATA(&dc_texture_ram[offset]);
1573   }
1574}
1575
1576// SB_LMMODE1
1577WRITE64_MEMBER(powervr2_device::ta_texture_directpath1_w )
1578{
1579   int mode = pvrctrl_regs[SB_LMMODE1]&1;
1580   if (mode&1)
1581   {
1582      printf("ta_texture_directpath1_w 32-bit access!\n");
1583      COMBINE_DATA(&dc_framebuffer_ram[offset]);
1584   }
1585   else
1586   {
1587      COMBINE_DATA(&dc_texture_ram[offset]);
1588   }
1589}
1590
1591/* test video start */
1592UINT32 powervr2_device::dilate0(UINT32 value,int bits) // dilate first "bits" bits in "value"
1593{
1594   UINT32 x,m1,m2,m3;
1595   int a;
1596
1597   x = value;
1598   for (a=0;a < bits;a++)
1599   {
1600      m2 = 1 << (a << 1);
1601      m1 = m2 - 1;
1602      m3 = (~m1) << 1;
1603      x = (x & m1) + (x & m2) + ((x & m3) << 1);
1604   }
1605   return x;
1606}
1607
1608UINT32 powervr2_device::dilate1(UINT32 value,int bits) // dilate first "bits" bits in "value"
1609{
1610   UINT32 x,m1,m2,m3;
1611   int a;
1612
1613   x = value;
1614   for (a=0;a < bits;a++)
1615   {
1616      m2 = 1 << (a << 1);
1617      m1 = m2 - 1;
1618      m3 = (~m1) << 1;
1619      x = (x & m1) + ((x & m2) << 1) + ((x & m3) << 1);
1620   }
1621   return x;
1622}
1623
1624void powervr2_device::computedilated()
1625{
1626   int a,b;
1627
1628   for (b=0;b <= 14;b++)
1629      for (a=0;a < 1024;a++) {
1630         dilated0[b][a]=dilate0(a,b);
1631         dilated1[b][a]=dilate1(a,b);
1632      }
1633   for (b=0;b <= 7;b++)
1634      for (a=0;a <= 7;a++)
1635         dilatechose[(b << 3) + a]=3+(a < b ? a : b);
1636}
1637
1638void powervr2_device::render_hline(bitmap_rgb32 &bitmap, texinfo *ti, int y, float xl, float xr, float ul, float ur, float vl, float vr, float wl, float wr)
1639{
1640   int xxl, xxr;
1641   float dx, ddx, dudx, dvdx, dwdx;
1642   UINT32 *tdata;
1643   float *wbufline;
1644
1645   // untextured cases aren't handled
1646   if (!ti->textured) return;
1647
1648   if(xr < 0 || xl >= 640)
1649      return;
1650
1651   xxl = round(xl);
1652   xxr = round(xr);
1653
1654   if(xxl == xxr)
1655      return;
1656
1657   dx = xr-xl;
1658   dudx = (ur-ul)/dx;
1659   dvdx = (vr-vl)/dx;
1660   dwdx = (wr-wl)/dx;
1661
1662   if(xxl < 0)
1663      xxl = 0;
1664   if(xxr > 640)
1665      xxr = 640;
1666
1667   // Target the pixel center
1668   ddx = xxl + 0.5 - xl;
1669   ul += ddx*dudx;
1670   vl += ddx*dvdx;
1671   wl += ddx*dwdx;
1672
1673
1674   tdata = &bitmap.pix32(y, xxl);
1675   wbufline = &wbuffer[y][xxl];
1676
1677   while(xxl < xxr) {
1678      if((wl >= *wbufline)) {
1679         UINT32 c;
1680         float u = ul/wl;
1681         float v = vl/wl;
1682
1683         /*
1684         if(ti->flip_u)
1685         {
1686             u = ti->sizex - u;
1687         }
1688
1689         if(ti->flip_v)
1690         {
1691             v = ti->sizey - v;
1692         }*/
1693
1694         c = (this->*(ti->r))(ti, u, v);
1695
1696         // debug dip to turn on/off bilinear filtering, it's slooooow
1697         if (debug_dip_status&0x1)
1698         {
1699            if(ti->filter_mode >= TEX_FILTER_BILINEAR)
1700            {
1701               UINT32 c1 = (this->*(ti->r))(ti, u+1.0, v);
1702               UINT32 c2 = (this->*(ti->r))(ti, u+1.0, v+1.0);
1703               UINT32 c3 = (this->*(ti->r))(ti, u, v+1.0);
1704               c = bilinear_filter(c, c1, c2, c3, u, v);
1705            }
1706         }
1707
1708         if(c & 0xff000000) {
1709            *tdata = ti->blend(c, *tdata);
1710            *wbufline = wl;
1711         }
1712      }
1713      wbufline++;
1714      tdata++;
1715
1716      ul += dudx;
1717      vl += dvdx;
1718      wl += dwdx;
1719      xxl ++;
1720   }
1721}
1722
1723void powervr2_device::render_span(bitmap_rgb32 &bitmap, texinfo *ti,
1724                          float y0, float y1,
1725                          float xl, float xr,
1726                          float ul, float ur,
1727                          float vl, float vr,
1728                          float wl, float wr,
1729                          float dxldy, float dxrdy,
1730                          float duldy, float durdy,
1731                          float dvldy, float dvrdy,
1732                          float dwldy, float dwrdy)
1733{
1734   float dy;
1735   int yy0, yy1;
1736
1737   if(y1 <= 0)
1738      return;
1739   if(y1 > 480)
1740      y1 = 480;
1741
1742   if(y0 < 0) {
1743      xl += -dxldy*y0;
1744      xr += -dxrdy*y0;
1745      ul += -duldy*y0;
1746      ur += -durdy*y0;
1747      vl += -dvldy*y0;
1748      vr += -dvrdy*y0;
1749      wl += -dwldy*y0;
1750      wr += -dwrdy*y0;
1751      y0 = 0;
1752   }
1753
1754   yy0 = round(y0);
1755   yy1 = round(y1);
1756
1757   if((yy0 < 0 && y0 > 0) || (yy1 < 0 && y1 > 0)) //temp handling of int32 overflow, needed by hotd2/totd
1758      return;
1759
1760   dy = yy0+0.5-y0;
1761
1762   if(0)
1763      fprintf(stderr, "%f %f %f %f -> %f %f | %f %f -> %f %f\n",
1764            y0,
1765            dy, dxldy, dxrdy, dy*dxldy, dy*dxrdy,
1766            xl, xr, xl + dy*dxldy, xr + dy*dxrdy);
1767   xl += dy*dxldy;
1768   xr += dy*dxrdy;
1769   ul += dy*duldy;
1770   ur += dy*durdy;
1771   vl += dy*dvldy;
1772   vr += dy*dvrdy;
1773   wl += dy*dwldy;
1774   wr += dy*dwrdy;
1775
1776   while(yy0 < yy1) {
1777      render_hline(bitmap, ti, yy0, xl, xr, ul, ur, vl, vr, wl, wr);
1778
1779      xl += dxldy;
1780      xr += dxrdy;
1781      ul += duldy;
1782      ur += durdy;
1783      vl += dvldy;
1784      vr += dvrdy;
1785      wl += dwldy;
1786      wr += dwrdy;
1787      yy0 ++;
1788   }
1789}
1790
1791void powervr2_device::sort_vertices(const vert *v, int *i0, int *i1, int *i2)
1792{
1793   float miny, maxy;
1794   int imin, imax, imid;
1795   miny = maxy = v[0].y;
1796   imin = imax = 0;
1797
1798   if(miny > v[1].y) {
1799      miny = v[1].y;
1800      imin = 1;
1801   } else if(maxy < v[1].y) {
1802      maxy = v[1].y;
1803      imax = 1;
1804   }
1805
1806   if(miny > v[2].y) {
1807      miny = v[2].y;
1808      imin = 2;
1809   } else if(maxy < v[2].y) {
1810      maxy = v[2].y;
1811      imax = 2;
1812   }
1813
1814   imid = (imin == 0 || imax == 0) ? (imin == 1 || imax == 1) ? 2 : 1 : 0;
1815
1816   *i0 = imin;
1817   *i1 = imid;
1818   *i2 = imax;
1819}
1820
1821
1822void powervr2_device::render_tri_sorted(bitmap_rgb32 &bitmap, texinfo *ti, const vert *v0, const vert *v1, const vert *v2)
1823{
1824   float dy01, dy02, dy12;
1825
1826   float dx01dy, dx02dy, dx12dy, du01dy, du02dy, du12dy, dv01dy, dv02dy, dv12dy, dw01dy, dw02dy, dw12dy;
1827
1828   if(v0->y >= 480 || v2->y < 0)
1829      return;
1830
1831   dy01 = v1->y - v0->y;
1832   dy02 = v2->y - v0->y;
1833   dy12 = v2->y - v1->y;
1834
1835   dx01dy = dy01 ? (v1->x-v0->x)/dy01 : 0;
1836   dx02dy = dy02 ? (v2->x-v0->x)/dy02 : 0;
1837   dx12dy = dy12 ? (v2->x-v1->x)/dy12 : 0;
1838
1839   du01dy = dy01 ? (v1->u-v0->u)/dy01 : 0;
1840   du02dy = dy02 ? (v2->u-v0->u)/dy02 : 0;
1841   du12dy = dy12 ? (v2->u-v1->u)/dy12 : 0;
1842
1843   dv01dy = dy01 ? (v1->v-v0->v)/dy01 : 0;
1844   dv02dy = dy02 ? (v2->v-v0->v)/dy02 : 0;
1845   dv12dy = dy12 ? (v2->v-v1->v)/dy12 : 0;
1846
1847   dw01dy = dy01 ? (v1->w-v0->w)/dy01 : 0;
1848   dw02dy = dy02 ? (v2->w-v0->w)/dy02 : 0;
1849   dw12dy = dy12 ? (v2->w-v1->w)/dy12 : 0;
1850
1851   if(!dy01) {
1852      if(!dy12)
1853         return;
1854
1855      if(v1->x > v0->x)
1856         render_span(bitmap, ti, v1->y, v2->y, v0->x, v1->x, v0->u, v1->u, v0->v, v1->v, v0->w, v1->w, dx02dy, dx12dy, du02dy, du12dy, dv02dy, dv12dy, dw02dy, dw12dy);
1857      else
1858         render_span(bitmap, ti, v1->y, v2->y, v1->x, v0->x, v1->u, v0->u, v1->v, v0->v, v1->w, v0->w, dx12dy, dx02dy, du12dy, du02dy, dv12dy, dv02dy, dw12dy, dw02dy);
1859
1860   } else if(!dy12) {
1861      if(v2->x > v1->x)
1862         render_span(bitmap, ti, v0->y, v1->y, v0->x, v0->x, v0->u, v0->u, v0->v, v0->v, v0->w, v0->w, dx01dy, dx02dy, du01dy, du02dy, dv01dy, dv02dy, dw01dy, dw02dy);
1863      else
1864         render_span(bitmap, ti, v0->y, v1->y, v0->x, v0->x, v0->u, v0->u, v0->v, v0->v, v0->w, v0->w, dx02dy, dx01dy, du02dy, du01dy, dv02dy, dv01dy, dw02dy, dw01dy);
1865
1866   } else {
1867      if(dx01dy < dx02dy) {
1868         render_span(bitmap, ti, v0->y, v1->y,
1869                  v0->x, v0->x, v0->u, v0->u, v0->v, v0->v, v0->w, v0->w,
1870                  dx01dy, dx02dy, du01dy, du02dy, dv01dy, dv02dy, dw01dy, dw02dy);
1871         render_span(bitmap, ti, v1->y, v2->y,
1872                  v1->x, v0->x + dx02dy*dy01, v1->u, v0->u + du02dy*dy01, v1->v, v0->v + dv02dy*dy01, v1->w, v0->w + dw02dy*dy01,
1873                  dx12dy, dx02dy, du12dy, du02dy, dv12dy, dv02dy, dw12dy, dw02dy);
1874      } else {
1875         render_span(bitmap, ti, v0->y, v1->y,
1876                  v0->x, v0->x, v0->u, v0->u, v0->v, v0->v, v0->w, v0->w,
1877                  dx02dy, dx01dy, du02dy, du01dy, dv02dy, dv01dy, dw02dy, dw01dy);
1878         render_span(bitmap, ti, v1->y, v2->y,
1879                  v0->x + dx02dy*dy01, v1->x, v0->u + du02dy*dy01, v1->u, v0->v + dv02dy*dy01, v1->v, v0->w + dw02dy*dy01, v1->w,
1880                  dx02dy, dx12dy, du02dy, du12dy, dv02dy, dv12dy, dw02dy, dw12dy);
1881      }
1882   }
1883}
1884
1885void powervr2_device::render_tri(bitmap_rgb32 &bitmap, texinfo *ti, const vert *v)
1886{
1887   int i0, i1, i2;
1888
1889   sort_vertices(v, &i0, &i1, &i2);
1890   render_tri_sorted(bitmap, ti, v+i0, v+i1, v+i2);
1891}
1892
1893void powervr2_device::render_to_accumulation_buffer(bitmap_rgb32 &bitmap,const rectangle &cliprect)
1894{
1895   dc_state *state = machine().driver_data<dc_state>();
1896   address_space &space = state->m_maincpu->space(AS_PROGRAM);
1897   int cs,rs,ns;
1898   UINT32 c;
1899#if 0
1900   int stride;
1901   UINT16 *bmpaddr16;
1902   UINT32 k;
1903#endif
1904
1905
1906   if (renderselect < 0)
1907      return;
1908
1909   //printf("drawtest!\n");
1910
1911   rs=renderselect;
1912   c=pvrta_regs[ISP_BACKGND_T];
1913   c=space.read_dword(0x05000000+((c&0xfffff8)>>1)+(3+3)*4);
1914   bitmap.fill(c, cliprect);
1915
1916
1917   ns=grab[rs].strips_size;
1918   if(ns)
1919      memset(wbuffer, 0x00, sizeof(wbuffer));
1920
1921   for (cs=0;cs < ns;cs++)
1922   {
1923      strip *ts = &grab[rs].strips[cs];
1924      int sv = ts->svert;
1925      int ev = ts->evert;
1926      int i;
1927      if(ev == -1)
1928         continue;
1929
1930      for(i=sv; i <= ev; i++)
1931      {
1932         vert *tv = grab[rs].verts + i;
1933         tv->u = tv->u * ts->ti.sizex * tv->w;
1934         tv->v = tv->v * ts->ti.sizey * tv->w;
1935      }
1936
1937      for(i=sv; i <= ev-2; i++)
1938      {
1939         if (!(debug_dip_status&0x2))
1940            render_tri(bitmap, &ts->ti, grab[rs].verts + i);
1941
1942      }
1943   }
1944   grab[rs].busy=0;
1945}
1946
1947// copies the accumulation buffer into the framebuffer, converting to the specified format
1948// not accurate, ignores field stuff and just uses SOF1 for now
1949// also ignores scale effects (can scale accumulation buffer to half size with filtering etc.)
1950// also can specify dither etc.
1951// basically, just a crude implementation!
1952
1953/*
1954
19550x0 0555 KRGB 16 bit (default) Bit 15 is the value of fb_kval 7.
19560x1 565 RGB 16 bit
19570x2 4444 ARGB 16 bit
19580x3 1555 ARGB 16 bit The alpha value is determined by comparison with the value of fb_alpha_threshold.
19590x4 888 RGB 24 bit packed
19600x5 0888 KRGB 32 bit K is the value of fk_kval.
19610x6 8888 ARGB 32 bit
19620x7 Setting prohibited.
1963
1964*/
1965
1966void powervr2_device::pvr_accumulationbuffer_to_framebuffer(address_space &space, int x,int y)
1967{
1968   // the accumulation buffer is always 8888
1969   //
1970   // the standard format for the framebuffer appears to be 565
1971   // yes, this means colour data is lost in the conversion
1972
1973   UINT32 wc = pvrta_regs[FB_W_CTRL];
1974   UINT32 stride = pvrta_regs[FB_W_LINESTRIDE];
1975   UINT32 writeoffs = pvrta_regs[FB_W_SOF1];
1976
1977   UINT32* src;
1978
1979
1980   UINT8 packmode = wc & 0x7;
1981
1982   switch (packmode)
1983   {
1984      // used by ringout
1985      case 0x00: //0555 KRGB
1986      {
1987         int xcnt,ycnt;
1988         for (ycnt=0;ycnt<32;ycnt++)
1989         {
1990            UINT32 realwriteoffs = 0x05000000 + writeoffs + (y+ycnt) * (stride<<3) + (x*2);
1991            src = &fake_accumulationbuffer_bitmap->pix32(y+ycnt, x);
1992
1993
1994            for (xcnt=0;xcnt<32;xcnt++)
1995            {
1996               // data starts in 8888 format, downsample it
1997               UINT32 data = src[xcnt];
1998               UINT16 newdat = ((((data & 0x000000f8) >> 3)) << 0)   |
1999                           ((((data & 0x0000f800) >> 11)) << 5)  |
2000                           ((((data & 0x00f80000) >> 19)) << 10);
2001
2002               space.write_word(realwriteoffs+xcnt*2, newdat);
2003            }
2004         }
2005      }
2006      break;
2007
2008      // used by cleoftp
2009      case 0x01: //565 RGB 16 bit
2010      {
2011         int xcnt,ycnt;
2012         for (ycnt=0;ycnt<32;ycnt++)
2013         {
2014            UINT32 realwriteoffs = 0x05000000 + writeoffs + (y+ycnt) * (stride<<3) + (x*2);
2015            src = &fake_accumulationbuffer_bitmap->pix32(y+ycnt, x);
2016
2017
2018            for (xcnt=0;xcnt<32;xcnt++)
2019            {
2020               // data starts in 8888 format, downsample it
2021               UINT32 data = src[xcnt];
2022               UINT16 newdat = ((((data & 0x000000f8) >> 3)) << 0)   |
2023                           ((((data & 0x0000fc00) >> 10)) << 5)  |
2024                           ((((data & 0x00f80000) >> 19)) << 11);
2025
2026               space.write_word(realwriteoffs+xcnt*2, newdat);
2027            }
2028         }
2029      }
2030      break;
2031
2032      case 0x02:
2033         printf("pvr_accumulationbuffer_to_framebuffer buffer to tile at %d,%d - unsupported pack mode %02x (4444 ARGB)\n",x,y,packmode);
2034         break;
2035
2036      case 0x03: // 1555 ARGB 16 bit
2037      {
2038         int xcnt,ycnt;
2039         for (ycnt=0;ycnt<32;ycnt++)
2040         {
2041            UINT32 realwriteoffs = 0x05000000 + writeoffs + (y+ycnt) * (stride<<3) + (x*2);
2042            src = &fake_accumulationbuffer_bitmap->pix32(y+ycnt, x);
2043
2044
2045            for (xcnt=0;xcnt<32;xcnt++)
2046            {
2047               // data starts in 8888 format, downsample it
2048               UINT32 data = src[xcnt];
2049               UINT16 newdat = ((((data & 0x000000f8) >> 3)) << 0)   |
2050                           ((((data & 0x0000f800) >> 11)) << 5)  |
2051                           ((((data & 0x00f80000) >> 19)) << 10);
2052               // alpha?
2053
2054               space.write_word(realwriteoffs+xcnt*2, newdat);
2055            }
2056         }
2057      }
2058      break;
2059
2060      // used by Suchie3
2061      case 0x04: // 888 RGB 24-bit (HACK! should not downconvert and pvr_drawframebuffer should change accordingly)
2062      {
2063         int xcnt,ycnt;
2064         for (ycnt=0;ycnt<32;ycnt++)
2065         {
2066            UINT32 realwriteoffs = 0x05000000 + writeoffs + (y+ycnt) * (stride<<3) + (x*2);
2067            src = &fake_accumulationbuffer_bitmap->pix32(y+ycnt, x);
2068
2069
2070            for (xcnt=0;xcnt<32;xcnt++)
2071            {
2072               // data is 8888 format
2073               UINT32 data = src[xcnt];
2074               UINT16 newdat = ((((data & 0x000000f8) >> 3)) << 0)   |
2075                           ((((data & 0x0000fc00) >> 10)) << 5)  |
2076                           ((((data & 0x00f80000) >> 19)) << 11);
2077
2078               space.write_word(realwriteoffs+xcnt*2, newdat);
2079            }
2080         }
2081      }
2082      break;
2083
2084      case 0x05:
2085         printf("pvr_accumulationbuffer_to_framebuffer buffer to tile at %d,%d - unsupported pack mode %02x (0888 KGB 32-bit)\n",x,y,packmode);
2086         break;
2087
2088      case 0x06: // 8888 ARGB 32 bit (HACK! should not downconvert and pvr_drawframebuffer should change accordingly)
2089      {
2090         int xcnt,ycnt;
2091         for (ycnt=0;ycnt<32;ycnt++)
2092         {
2093            UINT32 realwriteoffs = 0x05000000 + writeoffs + (y+ycnt) * (stride<<3) + (x*2);
2094            src = &fake_accumulationbuffer_bitmap->pix32(y+ycnt, x);
2095
2096
2097            for (xcnt=0;xcnt<32;xcnt++)
2098            {
2099               // data is 8888 format
2100               UINT32 data = src[xcnt];
2101               UINT16 newdat = ((((data & 0x000000f8) >> 3)) << 0)   |
2102                           ((((data & 0x0000fc00) >> 10)) << 5)  |
2103                           ((((data & 0x00f80000) >> 19)) << 11);
2104
2105               space.write_word(realwriteoffs+xcnt*2, newdat);
2106            }
2107         }
2108      }
2109      break;
2110
2111      case 0x07:
2112         printf("pvr_accumulationbuffer_to_framebuffer buffer to tile at %d,%d - unsupported pack mode %02x (Reserved! Don't Use!)\n",x,y,packmode);
2113         break;
2114   }
2115
2116
2117}
2118
2119void powervr2_device::pvr_drawframebuffer(bitmap_rgb32 &bitmap,const rectangle &cliprect)
2120{
2121   int x,y,dy,xi;
2122   UINT32 addrp;
2123   UINT32 *fbaddr;
2124   UINT32 c;
2125   UINT32 r,g,b;
2126
2127   UINT32 wc = pvrta_regs[FB_R_CTRL];
2128   UINT8 unpackmode = (wc & 0x0000000c) >>2;  // aka fb_depth
2129   UINT8 enable = (wc & 0x00000001);
2130
2131   // ??
2132   if (!enable) return;
2133
2134   // only for rgb565 framebuffer
2135   xi=((pvrta_regs[FB_R_SIZE] & 0x3ff)+1) << 1;
2136   dy=((pvrta_regs[FB_R_SIZE] >> 10) & 0x3ff)+1;
2137
2138   dy++;
2139   dy*=2; // probably depends on interlace mode, fields etc...
2140
2141   switch (unpackmode)
2142   {
2143      case 0x00: // 0555 RGB 16-bit, Cleo Fortune Plus
2144         // should upsample back to 8-bit output using fb_concat
2145         for (y=0;y <= dy;y++)
2146         {
2147            addrp=pvrta_regs[FB_R_SOF1]+y*xi*2;
2148            if(spg_pixel_double)
2149            {
2150               for (x=0;x < xi;x++)
2151               {
2152                  fbaddr=&bitmap.pix32(y, x*2+0);
2153                  c=*((reinterpret_cast<UINT16 *>(dc_framebuffer_ram)) + (WORD2_XOR_LE(addrp) >> 1));
2154
2155                  b = (c & 0x001f) << 3;
2156                  g = (c & 0x03e0) >> 2;
2157                  r = (c & 0x7c00) >> 7;
2158
2159                  if (y<=cliprect.max_y)
2160                     *fbaddr = b | (g<<8) | (r<<16);
2161
2162                  fbaddr=&bitmap.pix32(y, x*2+1);
2163                  if (y<=cliprect.max_y)
2164                     *fbaddr = b | (g<<8) | (r<<16);
2165                  addrp+=2;
2166               }
2167            }
2168            else
2169            {
2170               for (x=0;x < xi;x++)
2171               {
2172                  fbaddr=&bitmap.pix32(y, x);
2173                  c=*((reinterpret_cast<UINT16 *>(dc_framebuffer_ram)) + (WORD2_XOR_LE(addrp) >> 1));
2174
2175                  b = (c & 0x001f) << 3;
2176                  g = (c & 0x03e0) >> 2;
2177                  r = (c & 0x7c00) >> 7;
2178
2179                  if (y<=cliprect.max_y)
2180                     *fbaddr = b | (g<<8) | (r<<16);
2181                  addrp+=2;
2182               }
2183            }
2184         }
2185
2186         break;
2187      case 0x01: // 0565 RGB 16-bit
2188         // should upsample back to 8-bit output using fb_concat
2189         for (y=0;y <= dy;y++)
2190         {
2191            addrp=pvrta_regs[FB_R_SOF1]+y*xi*2;
2192            if(spg_pixel_double)
2193            {
2194               for (x=0;x < xi;x++)
2195               {
2196                  fbaddr=&bitmap.pix32(y, x*2+0);
2197                  c=*((reinterpret_cast<UINT16 *>(dc_framebuffer_ram)) + (WORD2_XOR_LE(addrp) >> 1));
2198
2199                  b = (c & 0x001f) << 3;
2200                  g = (c & 0x07e0) >> 3;
2201                  r = (c & 0xf800) >> 8;
2202
2203                  if (y<=cliprect.max_y)
2204                     *fbaddr = b | (g<<8) | (r<<16);
2205
2206                  fbaddr=&bitmap.pix32(y, x*2+1);
2207
2208                  if (y<=cliprect.max_y)
2209                     *fbaddr = b | (g<<8) | (r<<16);
2210
2211                  addrp+=2;
2212               }
2213            }
2214            else
2215            {
2216               for (x=0;x < xi;x++)
2217               {
2218                  fbaddr=&bitmap.pix32(y, x);
2219                  c=*((reinterpret_cast<UINT16 *>(dc_framebuffer_ram)) + (WORD2_XOR_LE(addrp) >> 1));
2220
2221                  b = (c & 0x001f) << 3;
2222                  g = (c & 0x07e0) >> 3;
2223                  r = (c & 0xf800) >> 8;
2224
2225                  if (y<=cliprect.max_y)
2226                     *fbaddr = b | (g<<8) | (r<<16);
2227                  addrp+=2;
2228               }
2229            }
2230         }
2231         break;
2232
2233      case 0x02: ; // 888 RGB 24-bit - suchie3 - HACKED, see pvr_accumulationbuffer_to_framebuffer!
2234         for (y=0;y <= dy;y++)
2235         {
2236            addrp=pvrta_regs[FB_R_SOF1]+y*xi*2;
2237            if(spg_pixel_double)
2238            {
2239               for (x=0;x < xi;x++)
2240               {
2241                  fbaddr=&bitmap.pix32(y, x*2+0);
2242                  c=*((reinterpret_cast<UINT16 *>(dc_framebuffer_ram)) + (WORD2_XOR_LE(addrp) >> 1));
2243
2244                  b = (c & 0x001f) << 3;
2245                  g = (c & 0x07e0) >> 3;
2246                  r = (c & 0xf800) >> 8;
2247
2248                  if (y<=cliprect.max_y)
2249                     *fbaddr = b | (g<<8) | (r<<16);
2250
2251                  fbaddr=&bitmap.pix32(y, x*2+1);
2252
2253                  if (y<=cliprect.max_y)
2254                     *fbaddr = b | (g<<8) | (r<<16);
2255                  addrp+=2;
2256               }
2257            }
2258            else
2259            {
2260               for (x=0;x < xi;x++)
2261               {
2262                  fbaddr=&bitmap.pix32(y, x);
2263                  c=*((reinterpret_cast<UINT16 *>(dc_framebuffer_ram)) + (WORD2_XOR_LE(addrp) >> 1));
2264
2265                  b = (c & 0x001f) << 3;
2266                  g = (c & 0x07e0) >> 3;
2267                  r = (c & 0xf800) >> 8;
2268
2269                  if (y<=cliprect.max_y)
2270                     *fbaddr = b | (g<<8) | (r<<16);
2271                  addrp+=2;
2272               }
2273            }
2274         }
2275         break;
2276
2277      case 0x03:        // 0888 ARGB 32-bit - HACKED, see pvr_accumulationbuffer_to_framebuffer!
2278         for (y=0;y <= dy;y++)
2279         {
2280            addrp=pvrta_regs[FB_R_SOF1]+y*xi*2;
2281            if(spg_pixel_double)
2282            {
2283               for (x=0;x < xi;x++)
2284               {
2285                  fbaddr=&bitmap.pix32(y, x*2+0);
2286                  c=*((reinterpret_cast<UINT16 *>(dc_framebuffer_ram)) + (WORD2_XOR_LE(addrp) >> 1));
2287
2288                  b = (c & 0x001f) << 3;
2289                  g = (c & 0x07e0) >> 3;
2290                  r = (c & 0xf800) >> 8;
2291
2292                  if (y<=cliprect.max_y)
2293                     *fbaddr = b | (g<<8) | (r<<16);
2294
2295                  fbaddr=&bitmap.pix32(y, x*2+1);
2296                  if (y<=cliprect.max_y)
2297                     *fbaddr = b | (g<<8) | (r<<16);
2298
2299                  addrp+=2;
2300               }
2301            }
2302            else
2303            {
2304               for (x=0;x < xi;x++)
2305               {
2306                  fbaddr=&bitmap.pix32(y, x);
2307                  c=*((reinterpret_cast<UINT16 *>(dc_framebuffer_ram)) + (WORD2_XOR_LE(addrp) >> 1));
2308
2309                  b = (c & 0x001f) << 3;
2310                  g = (c & 0x07e0) >> 3;
2311                  r = (c & 0xf800) >> 8;
2312
2313                  if (y<=cliprect.max_y)
2314                     *fbaddr = b | (g<<8) | (r<<16);
2315                  addrp+=2;
2316               }
2317            }
2318         }
2319         break;
2320   }
2321}
2322
2323
2324#if DEBUG_PALRAM
2325void powervr2_device::debug_paletteram()
2326{
2327   UINT64 pal;
2328   UINT32 r,g,b;
2329   int i;
2330
2331   //popmessage("%02x",pvrta_regs[PAL_RAM_CTRL]);
2332
2333   for(i=0;i<0x400;i++)
2334   {
2335      pal = pvrta_regs[((0x005F9000-0x005F8000)/4)+i];
2336      switch(pvrta_regs[PAL_RAM_CTRL])
2337      {
2338         case 0: //argb1555 <- guilty gear uses this mode
2339         {
2340            //a = (pal & 0x8000)>>15;
2341            r = (pal & 0x7c00)>>10;
2342            g = (pal & 0x03e0)>>5;
2343            b = (pal & 0x001f)>>0;
2344            //a = a ? 0xff : 0x00;
2345            palette_set_color_rgb(machine(), i, pal5bit(r), pal5bit(g), pal5bit(b));
2346         }
2347         break;
2348         case 1: //rgb565
2349         {
2350            //a = 0xff;
2351            r = (pal & 0xf800)>>11;
2352            g = (pal & 0x07e0)>>5;
2353            b = (pal & 0x001f)>>0;
2354            palette_set_color_rgb(machine(), i, pal5bit(r), pal6bit(g), pal5bit(b));
2355         }
2356         break;
2357         case 2: //argb4444
2358         {
2359            //a = (pal & 0xf000)>>12;
2360            r = (pal & 0x0f00)>>8;
2361            g = (pal & 0x00f0)>>4;
2362            b = (pal & 0x000f)>>0;
2363            palette_set_color_rgb(machine(), i, pal4bit(r), pal4bit(g), pal4bit(b));
2364         }
2365         break;
2366         case 3: //argb8888
2367         {
2368            //a = (pal & 0xff000000)>>20;
2369            r = (pal & 0x00ff0000)>>16;
2370            g = (pal & 0x0000ff00)>>8;
2371            b = (pal & 0x000000ff)>>0;
2372            palette_set_color_rgb(machine(), i, r, g, b);
2373         }
2374         break;
2375      }
2376   }
2377}
2378#endif
2379
2380/* test video end */
2381
2382void powervr2_device::pvr_build_parameterconfig()
2383{
2384   int a,b,c,d,e,p;
2385
2386   for (a = 0;a <= 63;a++)
2387      pvr_parameterconfig[a] = -1;
2388   p=0;
2389   // volume,col_type,texture,offset,16bit_uv
2390   for (a = 0;a <= 1;a++)
2391      for (b = 0;b <= 3;b++)
2392         for (c = 0;c <= 1;c++)
2393            if (c == 0)
2394            {
2395               for (d = 0;d <= 1;d++)
2396                  for (e = 0;e <= 1;e++)
2397                     pvr_parameterconfig[(a << 6) | (b << 4) | (c << 3) | (d << 2) | (e << 0)] = pvr_parconfseq[p];
2398               p++;
2399            }
2400            else
2401               for (d = 0;d <= 1;d++)
2402                  for (e = 0;e <= 1;e++)
2403                  {
2404                     pvr_parameterconfig[(a << 6) | (b << 4) | (c << 3) | (d << 2) | (e << 0)] = pvr_parconfseq[p];
2405                     p++;
2406                  }
2407   for (a = 1;a <= 63;a++)
2408      if (pvr_parameterconfig[a] < 0)
2409         pvr_parameterconfig[a] = pvr_parameterconfig[a-1];
2410}
2411
2412TIMER_CALLBACK_MEMBER(powervr2_device::vbin)
2413{
2414   dc_state *state = machine().driver_data<dc_state>();
2415   state->dc_sysctrl_regs[SB_ISTNRM] |= IST_VBL_IN; // V Blank-in interrupt
2416   state->dc_update_interrupt_status();
2417
2418   vbin_timer->adjust(machine().primary_screen->time_until_pos(spg_vblank_in_irq_line_num));
2419}
2420
2421TIMER_CALLBACK_MEMBER(powervr2_device::vbout)
2422{
2423   dc_state *state = machine().driver_data<dc_state>();
2424   state->dc_sysctrl_regs[SB_ISTNRM] |= IST_VBL_OUT; // V Blank-out interrupt
2425   state->dc_update_interrupt_status();
2426
2427   vbout_timer->adjust(machine().primary_screen->time_until_pos(spg_vblank_out_irq_line_num));
2428}
2429
2430TIMER_CALLBACK_MEMBER(powervr2_device::hbin)
2431{
2432   if(spg_hblank_int_mode & 1)
2433   {
2434      if(scanline == next_y)
2435      {
2436         dc_state *state = machine().driver_data<dc_state>();
2437         state->dc_sysctrl_regs[SB_ISTNRM] |= IST_HBL_IN; // H Blank-in interrupt
2438         state->dc_update_interrupt_status();
2439         next_y+=spg_line_comp_val;
2440      }
2441   }
2442   else if((scanline == spg_line_comp_val) || (spg_hblank_int_mode & 2))
2443   {
2444      dc_state *state = machine().driver_data<dc_state>();
2445      state->dc_sysctrl_regs[SB_ISTNRM] |= IST_HBL_IN; // H Blank-in interrupt
2446      state->dc_update_interrupt_status();
2447   }
2448
2449//  printf("hbin on scanline %d\n",scanline);
2450
2451   scanline++;
2452
2453   if(scanline >= spg_vblank_in_irq_line_num)
2454   {
2455      scanline = 0;
2456      next_y = spg_line_comp_val;
2457   }
2458
2459   hbin_timer->adjust(machine().primary_screen->time_until_pos(scanline, spg_hblank_in_irq-1));
2460}
2461
2462
2463
2464TIMER_CALLBACK_MEMBER(powervr2_device::endofrender_video)
2465{
2466   dc_state *state = machine().driver_data<dc_state>();
2467   state->dc_sysctrl_regs[SB_ISTNRM] |= IST_EOR_VIDEO;// VIDEO end of render
2468   state->dc_update_interrupt_status();
2469   endofrender_timer_video->adjust(attotime::never);
2470}
2471
2472TIMER_CALLBACK_MEMBER(powervr2_device::endofrender_tsp)
2473{
2474   dc_state *state = machine().driver_data<dc_state>();
2475   state->dc_sysctrl_regs[SB_ISTNRM] |= IST_EOR_TSP;  // TSP end of render
2476   state->dc_update_interrupt_status();
2477
2478   endofrender_timer_tsp->adjust(attotime::never);
2479   endofrender_timer_video->adjust(attotime::from_usec(500) );
2480}
2481
2482TIMER_CALLBACK_MEMBER(powervr2_device::endofrender_isp)
2483{
2484   dc_state *state = machine().driver_data<dc_state>();
2485   state->dc_sysctrl_regs[SB_ISTNRM] |= IST_EOR_ISP;  // ISP end of render
2486   state->dc_update_interrupt_status();
2487
2488   endofrender_timer_isp->adjust(attotime::never);
2489   endofrender_timer_tsp->adjust(attotime::from_usec(500) );
2490}
2491
2492UINT32 powervr2_device::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
2493{
2494   /******************
2495     MAME note
2496   *******************
2497
2498   The video update function should NOT be generating interrupts, setting timers or doing _anything_ the game might be able to detect
2499   as it will be called at different times depending on frameskip etc.
2500
2501   Rendering should happen when the hardware requests it, to the framebuffer(s)
2502
2503   Everything else should depend on timers.
2504
2505   ******************/
2506
2507//  static int useframebuffer=1;
2508//  const rectangle &visarea = screen.visible_area();
2509//  int y,x;
2510
2511#if DEBUG_PALRAM
2512   debug_paletteram();
2513#endif
2514
2515   // copy our fake framebuffer bitmap (where things have been rendered) to the screen
2516#if 0
2517   for (y = visarea->min_y ; y <= visarea->max_y ; y++)
2518   {
2519      for (x = visarea->min_x ; x <= visarea->max_x ; x++)
2520      {
2521         UINT32* src = &fake_accumulationbuffer_bitmap->pix32(y, x);
2522         UINT32* dst = &bitmap.pix32(y, x);
2523         dst[0] = src[0];
2524      }
2525   }
2526#endif
2527
2528   bitmap.fill(MAKE_ARGB(0xff,vo_border_R,vo_border_G,vo_border_B), cliprect); //FIXME: Chroma bit?
2529
2530   if(!spg_blank_video)
2531      pvr_drawframebuffer(bitmap, cliprect);
2532
2533   // update this here so we only do string lookup once per frame
2534   debug_dip_status = ioport(":MAMEDEBUG")->read();
2535
2536   return 0;
2537}
2538
2539
2540/* Naomi 2 attempts (TBD) */
2541
2542READ64_MEMBER( powervr2_device::pvr2_ta_r )
2543{
2544   int reg;
2545   UINT64 shift;
2546
2547   reg = decode_reg_64(offset, mem_mask, &shift);
2548
2549   switch (reg)
2550   {
2551   }
2552
2553   printf("PVR2 %08x R\n",reg);
2554
2555   return 0;
2556}
2557
2558WRITE64_MEMBER( powervr2_device::pvr2_ta_w )
2559{
2560//  int reg;
2561//  UINT64 shift;
2562//  UINT32 dat;
2563
2564//  reg = decode_reg_64(offset, mem_mask, &shift);
2565//  dat = (UINT32)(data >> shift);
2566
2567   //printf("PVR2 %08x %08x\n",reg,dat);
2568}
2569
2570READ32_MEMBER( powervr2_device::elan_regs_r )
2571{
2572   switch(offset)
2573   {
2574      case 0x00/4: // ID chip (TODO: BIOS crashes / gives a black screen with this as per now!)
2575         return 0xe1ad0000;
2576      case 0x04/4: // REVISION
2577         return 0x12; //or 0x01?
2578      case 0x10/4: // SH4 interface control (???)
2579         /* ---- -x-- enable second PVR */
2580         /* ---- --x- elan has channel 2 */
2581         /* ---- ---x broadcast on cs1 (?) */
2582         return 6;
2583      case 0x14/4: // SDRAM refresh register
2584         return 0x2029; //default 0x1429
2585      case 0x1c/4: // SDRAM CFG
2586         return 0xa7320961; //default 0xa7320961
2587      case 0x30/4: // Macro tiler configuration, bit 0 is enable
2588         return 0;
2589      case 0x74/4: // IRQ STAT
2590         return 0;
2591      case 0x78/4: // IRQ MASK
2592         return 0;
2593      default:
2594         printf("%08x %08x\n",space.device().safe_pc(),offset*4);
2595         break;
2596   }
2597
2598   return 0;
2599}
2600
2601WRITE32_MEMBER( powervr2_device::elan_regs_w )
2602{
2603   switch(offset)
2604   {
2605      default:
2606         printf("%08x %08x %08x W\n",space.device().safe_pc(),offset*4,data);
2607         break;
2608   }
2609}
2610
2611
2612WRITE64_MEMBER( powervr2_device::pvrs_ta_w )
2613{
2614   pvr_ta_w(space,offset,data,mem_mask);
2615   pvr2_ta_w(space,offset,data,mem_mask);
2616   //printf("PVR2 %08x %08x\n",reg,dat);
2617}
2618
2619TIMER_CALLBACK_MEMBER(powervr2_device::pvr_dma_irq)
2620{
2621   dc_state *state = machine().driver_data<dc_state>();
2622   m_pvr_dma.start = pvrctrl_regs[SB_PDST] = 0;
2623   state->dc_sysctrl_regs[SB_ISTNRM] |= IST_DMA_PVR;
2624   state->dc_update_interrupt_status();
2625}
2626
2627READ64_MEMBER(powervr2_device::pvr_ctrl_r )
2628{
2629   int reg;
2630   UINT64 shift;
2631
2632   reg = decode_reg_64(offset, mem_mask, &shift);
2633
2634   #if DEBUG_PVRCTRL
2635   mame_printf_verbose("PVRCTRL: [%08x] read %x @ %x (reg %x), mask %" I64FMT "x (PC=%x)\n", 0x5f7c00+reg*4, pvrctrl_regs[reg], offset, reg, mem_mask, space.device().safe_pc());
2636   #endif
2637
2638   return (UINT64)pvrctrl_regs[reg] << shift;
2639}
2640
2641WRITE64_MEMBER(powervr2_device::pvr_ctrl_w )
2642{
2643   int reg;
2644   UINT64 shift;
2645   UINT32 dat;
2646   UINT8 old;
2647
2648   reg = decode_reg_64(offset, mem_mask, &shift);
2649   dat = (UINT32)(data >> shift);
2650
2651   switch (reg)
2652   {
2653      case SB_PDSTAP: m_pvr_dma.pvr_addr = dat; break;
2654      case SB_PDSTAR: m_pvr_dma.sys_addr = dat; break;
2655      case SB_PDLEN: m_pvr_dma.size = dat; break;
2656      case SB_PDDIR: m_pvr_dma.dir = dat & 1; break;
2657      case SB_PDTSEL:
2658         m_pvr_dma.sel = dat & 1;
2659         //if(m_pvr_dma.sel & 1)
2660         //  printf("Warning: Unsupported irq mode trigger PVR-DMA\n");
2661         break;
2662      case SB_PDEN: m_pvr_dma.flag = dat & 1; break;
2663      case SB_PDST:
2664         old = m_pvr_dma.start & 1;
2665         m_pvr_dma.start = dat & 1;
2666
2667         if(((old & 1) == 0) && m_pvr_dma.flag && m_pvr_dma.start && ((m_pvr_dma.sel & 1) == 0)) // 0 -> 1
2668            pvr_dma_execute(space);
2669         break;
2670   }
2671
2672   #if DEBUG_PVRCTRL
2673   mame_printf_verbose("PVRCTRL: [%08x=%x] write %" I64FMT "x to %x (reg %x), mask %" I64FMT "x\n", 0x5f7c00+reg*4, dat, data>>shift, offset, reg, mem_mask);
2674   #endif
2675
2676//  pvrctrl_regs[reg] |= dat;
2677   pvrctrl_regs[reg] = dat;
2678}
2679
2680void powervr2_device::pvr_dma_execute(address_space &space)
2681{
2682   UINT32 src,dst,size;
2683   dst = m_pvr_dma.pvr_addr;
2684   src = m_pvr_dma.sys_addr;
2685   size = 0;
2686
2687   /* used so far by usagui and sprtjam*/
2688   //printf("PVR-DMA start\n");
2689   //printf("%08x %08x %08x\n",m_pvr_dma.pvr_addr,m_pvr_dma.sys_addr,m_pvr_dma.size);
2690   //printf("src %s dst %08x\n",m_pvr_dma.dir ? "->" : "<-",m_pvr_dma.sel);
2691
2692   /* 0 rounding size = 16 Mbytes */
2693   if(m_pvr_dma.size == 0) { m_pvr_dma.size = 0x100000; }
2694
2695   if(m_pvr_dma.dir == 0)
2696   {
2697      for(;size<m_pvr_dma.size;size+=4)
2698      {
2699         space.write_dword(dst,space.read_dword(src));
2700         src+=4;
2701         dst+=4;
2702      }
2703   }
2704   else
2705   {
2706      for(;size<m_pvr_dma.size;size+=4)
2707      {
2708         space.write_dword(src,space.read_dword(dst));
2709         src+=4;
2710         dst+=4;
2711      }
2712   }
2713   /* Note: do not update the params, since this DMA type doesn't support it. */
2714   /* TODO: timing of this */
2715   machine().scheduler().timer_set(attotime::from_usec(250), timer_expired_delegate(FUNC(powervr2_device::pvr_dma_irq), this));
2716}
2717
2718powervr2_device::powervr2_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
2719   : device_t(mconfig, POWERVR2, "PowerVR 2", tag, owner, clock)
2720{
2721}
2722
2723void powervr2_device::device_start()
2724{
2725   memset(pvrctrl_regs, 0, sizeof(pvrctrl_regs));
2726   memset(pvrta_regs, 0, sizeof(pvrta_regs));
2727   memset(grab, 0, sizeof(grab));
2728   pvr_build_parameterconfig();
2729
2730   computedilated();
2731
2732   vbout_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(powervr2_device::vbout),this));
2733   vbin_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(powervr2_device::vbin),this));
2734   hbin_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(powervr2_device::hbin),this));
2735
2736   endofrender_timer_isp = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(powervr2_device::endofrender_isp),this));
2737   endofrender_timer_tsp = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(powervr2_device::endofrender_tsp),this));
2738   endofrender_timer_video = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(powervr2_device::endofrender_video),this));
2739
2740   fake_accumulationbuffer_bitmap = auto_bitmap_rgb32_alloc(machine(),1024,1024);
2741
2742   save_item(NAME(m_pvr_dma.pvr_addr));
2743   save_item(NAME(m_pvr_dma.sys_addr));
2744   save_item(NAME(m_pvr_dma.size));
2745   save_item(NAME(m_pvr_dma.sel));
2746   save_item(NAME(m_pvr_dma.dir));
2747   save_item(NAME(m_pvr_dma.flag));
2748   save_item(NAME(m_pvr_dma.start));
2749   save_pointer(NAME(pvrta_regs),0x2000/4);
2750   save_pointer(NAME(pvrctrl_regs),0x100/4);
2751   save_item(NAME(debug_dip_status));
2752   save_pointer(NAME(tafifo_buff),32);
2753   save_item(NAME(scanline));
2754   save_item(NAME(next_y));
2755}
2756
2757void powervr2_device::device_reset()
2758{
2759   pvrta_regs[VO_CONTROL]=     0x00000108;
2760   pvrta_regs[SOFTRESET]=      0x00000007;
2761   pvrta_regs[VO_STARTX]=      0x0000009d;
2762   pvrta_regs[VO_STARTY]=      0x00150015;
2763   pvrta_regs[SPG_HBLANK]=     0x007e0345;
2764   pvrta_regs[SPG_LOAD]=       0x01060359;
2765   pvrta_regs[SPG_VBLANK]=     0x01500104;
2766   pvrta_regs[SPG_HBLANK_INT]= 0x031d0000;
2767   pvrta_regs[SPG_VBLANK_INT]= 0x01500104;
2768
2769   // if the next 2 registers do not have the correct values, the naomi bios will hang
2770   pvrta_regs[PVRID]=0x17fd11db;
2771   pvrta_regs[REVISION]=0x11;
2772
2773   tafifo_pos=0;
2774   tafifo_mask=7;
2775   tafifo_vertexwords=8;
2776   tafifo_listtype= -1;
2777   start_render_received=0;
2778   renderselect= -1;
2779   grabsel=0;
2780
2781   vbout_timer->adjust(machine().primary_screen->time_until_pos(spg_vblank_out_irq_line_num_new));
2782   vbin_timer->adjust(machine().primary_screen->time_until_pos(spg_vblank_in_irq_line_num_new));
2783   hbin_timer->adjust(machine().primary_screen->time_until_pos(0, spg_hblank_in_irq_new-1));
2784
2785   scanline = 0;
2786   next_y = 0;
2787
2788   endofrender_timer_isp->adjust(attotime::never);
2789   endofrender_timer_tsp->adjust(attotime::never);
2790   endofrender_timer_video->adjust(attotime::never);
2791
2792   dc_state *state = machine().driver_data<dc_state>();
2793   dc_texture_ram = state->dc_texture_ram.target();
2794   dc_framebuffer_ram = state->dc_framebuffer_ram.target();
2795}
Property changes on: trunk/src/mame/video/powervr2.c
Added: svn:mime-type
   + text/plain
Added: svn:eol-style
   + native
trunk/src/mame/video/powervr2.h
r23534r23535
1#ifndef __POWERVR2_H__
2#define __POWERVR2_H__
3
4#define MCFG_POWERVR2_ADD(_tag)  \
5   MCFG_DEVICE_ADD(_tag, POWERVR2, 0)
6
7class powervr2_device : public device_t
8{
9public:
10   enum { NUM_BUFFERS = 4 };
11
12   struct {
13      UINT32 pvr_addr;
14      UINT32 sys_addr;
15      UINT32 size;
16      UINT8 sel;
17      UINT8 dir;
18      UINT8 flag;
19      UINT8 start;
20   } m_pvr_dma;
21
22   static const int pvr_parconfseq[];
23   static const int pvr_wordsvertex[24];
24   static const int pvr_wordspolygon[24];
25   int pvr_parameterconfig[128];
26   UINT32 dilated0[15][1024];
27   UINT32 dilated1[15][1024];
28   int dilatechose[64];
29   float wbuffer[480][640];
30
31
32   // the real accumulation buffer is a 32x32x8bpp buffer into which tiles get rendered before they get copied to the framebuffer
33   //  our implementation is not currently tile based, and thus the accumulation buffer is screen sized
34   bitmap_rgb32 *fake_accumulationbuffer_bitmap;
35
36   struct texinfo  {
37      UINT32 address, vqbase;
38      int textured, sizex, sizey, stride, sizes, pf, palette, mode, mipmapped, blend_mode, filter_mode, flip_u, flip_v;
39
40      UINT32 (powervr2_device::*r)(struct texinfo *t, float x, float y);
41      UINT32 (*blend)(UINT32 s, UINT32 d);
42      int palbase, cd;
43   };
44
45   typedef struct
46   {
47      float x, y, w, u, v;
48   } vert;
49
50   struct strip
51   {
52      int svert, evert;
53      texinfo ti;
54   };
55
56   struct receiveddata {
57      vert verts[65536];
58      strip strips[65536];
59
60      int verts_size, strips_size;
61      UINT32 ispbase;
62      UINT32 fbwsof1;
63      UINT32 fbwsof2;
64      int busy;
65      int valid;
66   };
67
68   enum {
69      TEX_FILTER_NEAREST = 0,
70      TEX_FILTER_BILINEAR,
71      TEX_FILTER_TRILINEAR_A,
72      TEX_FILTER_TRILINEAR_B
73   };
74
75   int tafifo_pos, tafifo_mask, tafifo_vertexwords, tafifo_listtype;
76   int start_render_received;
77   int renderselect;
78   int listtype_used;
79   int alloc_ctrl_OPB_Mode, alloc_ctrl_PT_OPB, alloc_ctrl_TM_OPB, alloc_ctrl_T_OPB, alloc_ctrl_OM_OPB, alloc_ctrl_O_OPB;
80   receiveddata grab[NUM_BUFFERS];
81   int grabsel;
82   int grabsellast;
83   UINT32 paracontrol,paratype,endofstrip,listtype,global_paratype,parameterconfig;
84   UINT32 groupcontrol,groupen,striplen,userclip;
85   UINT32 objcontrol,shadow,volume,coltype,texture,offfset,gouraud,uv16bit;
86   UINT32 texturesizes,textureaddress,scanorder,pixelformat;
87   UINT32 blend_mode, srcselect,dstselect,fogcontrol,colorclamp, use_alpha;
88   UINT32 ignoretexalpha,flipuv,clampuv,filtermode,sstexture,mmdadjust,tsinstruction;
89   UINT32 depthcomparemode,cullingmode,zwritedisable,cachebypass,dcalcctrl,volumeinstruction,mipmapped,vqcompressed,strideselect,paletteselector;
90
91
92   UINT64 *dc_texture_ram;
93   UINT64 *dc_framebuffer_ram;
94   
95   UINT64 *pvr2_texture_ram;
96   UINT64 *pvr2_framebuffer_ram;
97   UINT64 *elan_ram;
98
99   UINT32 pvrta_regs[0x2000/4];
100   UINT32 pvrctrl_regs[0x100/4];
101   UINT32 debug_dip_status;
102   emu_timer *vbout_timer;
103   emu_timer *vbin_timer;
104   emu_timer *hbin_timer;
105   emu_timer *endofrender_timer_isp;
106   emu_timer *endofrender_timer_tsp;
107   emu_timer *endofrender_timer_video;
108   UINT32 tafifo_buff[32];
109   int scanline;
110   int next_y;
111
112   powervr2_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
113
114   DECLARE_READ64_MEMBER( pvr_ctrl_r );
115   DECLARE_WRITE64_MEMBER( pvr_ctrl_w );
116   DECLARE_READ64_MEMBER( pvr_ta_r );
117   DECLARE_WRITE64_MEMBER( pvr_ta_w );
118   DECLARE_READ64_MEMBER( pvr2_ta_r );
119   DECLARE_WRITE64_MEMBER( pvr2_ta_w );
120   DECLARE_READ64_MEMBER( pvrs_ta_r );
121   DECLARE_WRITE64_MEMBER( pvrs_ta_w );
122   DECLARE_READ32_MEMBER( elan_regs_r );
123   DECLARE_WRITE32_MEMBER( elan_regs_w );
124   DECLARE_WRITE64_MEMBER( ta_fifo_poly_w );
125   DECLARE_WRITE64_MEMBER( ta_fifo_yuv_w );
126   DECLARE_WRITE64_MEMBER( ta_texture_directpath0_w );
127   DECLARE_WRITE64_MEMBER( ta_texture_directpath1_w );
128
129   TIMER_CALLBACK_MEMBER(vbin);
130   TIMER_CALLBACK_MEMBER(vbout);
131   TIMER_CALLBACK_MEMBER(hbin);
132   TIMER_CALLBACK_MEMBER(endofrender_video);
133   TIMER_CALLBACK_MEMBER(endofrender_tsp);
134   TIMER_CALLBACK_MEMBER(endofrender_isp);
135   TIMER_CALLBACK_MEMBER(transfer_opaque_list_irq);
136   TIMER_CALLBACK_MEMBER(transfer_opaque_modifier_volume_list_irq);
137   TIMER_CALLBACK_MEMBER(transfer_translucent_list_irq);
138   TIMER_CALLBACK_MEMBER(transfer_translucent_modifier_volume_list_irq);
139   TIMER_CALLBACK_MEMBER(transfer_punch_through_list_irq);
140   TIMER_CALLBACK_MEMBER(pvr_dma_irq);
141
142   void pvr_dma_execute(address_space &space);
143   UINT32 screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
144
145protected:
146   virtual void device_start();
147   virtual void device_reset();
148
149private:
150   static UINT32 (*const blend_functions[64])(UINT32 s, UINT32 d);
151
152   static inline INT32 clamp(INT32 in, INT32 min, INT32 max);
153   static inline UINT32 bilinear_filter(UINT32 c0, UINT32 c1, UINT32 c2, UINT32 c3, float u, float v);
154   static inline UINT32 bla(UINT32 c, UINT32 a);
155   static inline UINT32 blia(UINT32 c, UINT32 a);
156   static inline UINT32 blc(UINT32 c1, UINT32 c2);
157   static inline UINT32 blic(UINT32 c1, UINT32 c2);
158   static inline UINT32 bls(UINT32 c1, UINT32 c2);
159   static UINT32 bl00(UINT32 s, UINT32 d);
160   static UINT32 bl01(UINT32 s, UINT32 d);
161   static UINT32 bl02(UINT32 s, UINT32 d);
162   static UINT32 bl03(UINT32 s, UINT32 d);
163   static UINT32 bl04(UINT32 s, UINT32 d);
164   static UINT32 bl05(UINT32 s, UINT32 d);
165   static UINT32 bl06(UINT32 s, UINT32 d);
166   static UINT32 bl07(UINT32 s, UINT32 d);
167   static UINT32 bl10(UINT32 s, UINT32 d);
168   static UINT32 bl11(UINT32 s, UINT32 d);
169   static UINT32 bl12(UINT32 s, UINT32 d);
170   static UINT32 bl13(UINT32 s, UINT32 d);
171   static UINT32 bl14(UINT32 s, UINT32 d);
172   static UINT32 bl15(UINT32 s, UINT32 d);
173   static UINT32 bl16(UINT32 s, UINT32 d);
174   static UINT32 bl17(UINT32 s, UINT32 d);
175   static UINT32 bl20(UINT32 s, UINT32 d);
176   static UINT32 bl21(UINT32 s, UINT32 d);
177   static UINT32 bl22(UINT32 s, UINT32 d);
178   static UINT32 bl23(UINT32 s, UINT32 d);
179   static UINT32 bl24(UINT32 s, UINT32 d);
180   static UINT32 bl25(UINT32 s, UINT32 d);
181   static UINT32 bl26(UINT32 s, UINT32 d);
182   static UINT32 bl27(UINT32 s, UINT32 d);
183   static UINT32 bl30(UINT32 s, UINT32 d);
184   static UINT32 bl31(UINT32 s, UINT32 d);
185   static UINT32 bl32(UINT32 s, UINT32 d);
186   static UINT32 bl33(UINT32 s, UINT32 d);
187   static UINT32 bl34(UINT32 s, UINT32 d);
188   static UINT32 bl35(UINT32 s, UINT32 d);
189   static UINT32 bl36(UINT32 s, UINT32 d);
190   static UINT32 bl37(UINT32 s, UINT32 d);
191   static UINT32 bl40(UINT32 s, UINT32 d);
192   static UINT32 bl41(UINT32 s, UINT32 d);
193   static UINT32 bl42(UINT32 s, UINT32 d);
194   static UINT32 bl43(UINT32 s, UINT32 d);
195   static UINT32 bl44(UINT32 s, UINT32 d);
196   static UINT32 bl45(UINT32 s, UINT32 d);
197   static UINT32 bl46(UINT32 s, UINT32 d);
198   static UINT32 bl47(UINT32 s, UINT32 d);
199   static UINT32 bl50(UINT32 s, UINT32 d);
200   static UINT32 bl51(UINT32 s, UINT32 d);
201   static UINT32 bl52(UINT32 s, UINT32 d);
202   static UINT32 bl53(UINT32 s, UINT32 d);
203   static UINT32 bl54(UINT32 s, UINT32 d);
204   static UINT32 bl55(UINT32 s, UINT32 d);
205   static UINT32 bl56(UINT32 s, UINT32 d);
206   static UINT32 bl57(UINT32 s, UINT32 d);
207   static UINT32 bl60(UINT32 s, UINT32 d);
208   static UINT32 bl61(UINT32 s, UINT32 d);
209   static UINT32 bl62(UINT32 s, UINT32 d);
210   static UINT32 bl63(UINT32 s, UINT32 d);
211   static UINT32 bl64(UINT32 s, UINT32 d);
212   static UINT32 bl65(UINT32 s, UINT32 d);
213   static UINT32 bl66(UINT32 s, UINT32 d);
214   static UINT32 bl67(UINT32 s, UINT32 d);
215   static UINT32 bl70(UINT32 s, UINT32 d);
216   static UINT32 bl71(UINT32 s, UINT32 d);
217   static UINT32 bl72(UINT32 s, UINT32 d);
218   static UINT32 bl73(UINT32 s, UINT32 d);
219   static UINT32 bl74(UINT32 s, UINT32 d);
220   static UINT32 bl75(UINT32 s, UINT32 d);
221   static UINT32 bl76(UINT32 s, UINT32 d);
222   static UINT32 bl77(UINT32 s, UINT32 d);
223   static inline UINT32 cv_1555(UINT16 c);
224   static inline UINT32 cv_1555z(UINT16 c);
225   static inline UINT32 cv_565(UINT16 c);
226   static inline UINT32 cv_565z(UINT16 c);
227   static inline UINT32 cv_4444(UINT16 c);
228   static inline UINT32 cv_4444z(UINT16 c);
229   static inline UINT32 cv_yuv(UINT16 c1, UINT16 c2, int x);
230   UINT32 tex_r_yuv_n(texinfo *t, float x, float y);
231   UINT32 tex_r_1555_n(texinfo *t, float x, float y);
232   UINT32 tex_r_1555_tw(texinfo *t, float x, float y);
233   UINT32 tex_r_1555_vq(texinfo *t, float x, float y);
234   UINT32 tex_r_565_n(texinfo *t, float x, float y);
235   UINT32 tex_r_565_tw(texinfo *t, float x, float y);
236   UINT32 tex_r_565_vq(texinfo *t, float x, float y);
237   UINT32 tex_r_4444_n(texinfo *t, float x, float y);
238   UINT32 tex_r_4444_tw(texinfo *t, float x, float y);
239   UINT32 tex_r_4444_vq(texinfo *t, float x, float y);
240   UINT32 tex_r_p4_1555_tw(texinfo *t, float x, float y);
241   UINT32 tex_r_p4_1555_vq(texinfo *t, float x, float y);
242   UINT32 tex_r_p4_565_tw(texinfo *t, float x, float y);
243   UINT32 tex_r_p4_565_vq(texinfo *t, float x, float y);
244   UINT32 tex_r_p4_4444_tw(texinfo *t, float x, float y);
245   UINT32 tex_r_p4_4444_vq(texinfo *t, float x, float y);
246   UINT32 tex_r_p4_8888_tw(texinfo *t, float x, float y);
247   UINT32 tex_r_p4_8888_vq(texinfo *t, float x, float y);
248   UINT32 tex_r_p8_1555_tw(texinfo *t, float x, float y);
249   UINT32 tex_r_p8_1555_vq(texinfo *t, float x, float y);
250   UINT32 tex_r_p8_565_tw(texinfo *t, float x, float y);
251   UINT32 tex_r_p8_565_vq(texinfo *t, float x, float y);
252   UINT32 tex_r_p8_4444_tw(texinfo *t, float x, float y);
253   UINT32 tex_r_p8_4444_vq(texinfo *t, float x, float y);
254   UINT32 tex_r_p8_8888_tw(texinfo *t, float x, float y);
255   UINT32 tex_r_p8_8888_vq(texinfo *t, float x, float y);
256   UINT32 tex_r_default(texinfo *t, float x, float y);
257   void tex_get_info(texinfo *t);
258
259   void render_hline(bitmap_rgb32 &bitmap, texinfo *ti, int y, float xl, float xr, float ul, float ur, float vl, float vr, float wl, float wr);
260   void render_span(bitmap_rgb32 &bitmap, texinfo *ti,
261                float y0, float y1,
262                float xl, float xr,
263                float ul, float ur,
264                float vl, float vr,
265                float wl, float wr,
266                float dxldy, float dxrdy,
267                float duldy, float durdy,
268                float dvldy, float dvrdy,
269                float dwldy, float dwrdy);
270   void sort_vertices(const vert *v, int *i0, int *i1, int *i2);
271   void render_tri_sorted(bitmap_rgb32 &bitmap, texinfo *ti, const vert *v0, const vert *v1, const vert *v2);
272   void render_tri(bitmap_rgb32 &bitmap, texinfo *ti, const vert *v);
273   void render_to_accumulation_buffer(bitmap_rgb32 &bitmap, const rectangle &cliprect);
274   void pvr_accumulationbuffer_to_framebuffer(address_space &space, int x, int y);
275   void pvr_drawframebuffer(bitmap_rgb32 &bitmap,const rectangle &cliprect);
276   static UINT32 dilate0(UINT32 value,int bits);
277   static UINT32 dilate1(UINT32 value,int bits);
278   void computedilated();
279   void pvr_build_parameterconfig();
280   void process_ta_fifo();   
281   void debug_paletteram();
282};
283
284extern const device_type POWERVR2;
285
286#endif
trunk/src/mame/mame.mak
r23534r23535
15011501   $(AUDIO)/dsbz80.o \
15021502   $(DRIVERS)/model2.o $(VIDEO)/model2.o \
15031503   $(DRIVERS)/model3.o $(VIDEO)/model3.o $(MACHINE)/model3.o \
1504   $(DRIVERS)/naomi.o $(MACHINE)/dc.o $(VIDEO)/dc.o $(MACHINE)/naomi.o \
1504   $(DRIVERS)/naomi.o $(MACHINE)/dc.o $(VIDEO)/powervr2.o $(MACHINE)/naomi.o \
15051505   $(MACHINE)/naomig1.o $(MACHINE)/naomibd.o $(MACHINE)/naomirom.o $(MACHINE)/naomigd.o \
15061506   $(MACHINE)/naomicrypt.o $(MACHINE)/naomim1.o $(MACHINE)/naomim2.o $(MACHINE)/naomim4.o \
15071507   $(MACHINE)/awboard.o \
trunk/src/mame/includes/dc.h
r23534r23535
77#ifndef __DC_H__
88#define __DC_H__
99
10#include "video/powervr2.h"
11
1012class dc_state : public driver_device
1113{
1214   public:
r23534r23535
1719      dc_sound_ram(*this, "dc_sound_ram"),
1820      dc_ram(*this, "dc_ram"),
1921      m_maincpu(*this, "maincpu"),
20      m_soundcpu(*this, "soundcpu") { }
22      m_soundcpu(*this, "soundcpu"),
23      m_powervr2(*this, "powervr2") { }
2124
2225   required_shared_ptr<UINT64> dc_framebuffer_ram; // '32-bit access area'
2326   required_shared_ptr<UINT64> dc_texture_ram; // '64-bit access area'
r23534r23535
4447      UINT8 sel;
4548   }m_wave_dma;
4649
47   struct {
48      UINT32 pvr_addr;
49      UINT32 sys_addr;
50      UINT32 size;
51      UINT8 sel;
52      UINT8 dir;
53      UINT8 flag;
54      UINT8 start;
55   }m_pvr_dma;
56
5750   /* video related */
58   UINT32 pvrta_regs[0x2000/4];
59   UINT32 pvrctrl_regs[0x100/4];
60   UINT32 debug_dip_status;
61   emu_timer *vbout_timer;
62   emu_timer *vbin_timer;
63   emu_timer *hbin_timer;
64   emu_timer *endofrender_timer_isp;
65   emu_timer *endofrender_timer_tsp;
66   emu_timer *endofrender_timer_video;
67   UINT32 tafifo_buff[32];
68   int scanline;
69   int next_y;
7051
7152   virtual void machine_start();
7253   virtual void machine_reset();
73   virtual void video_start();
74   UINT32 screen_update_dc(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
7554   TIMER_CALLBACK_MEMBER(aica_dma_irq);
7655   TIMER_CALLBACK_MEMBER(pvr_dma_irq);
7756   TIMER_CALLBACK_MEMBER(ch2_dma_irq);
7857   TIMER_CALLBACK_MEMBER(yuv_fifo_irq);
7958   TIMER_CALLBACK_MEMBER(dc_rtc_increment);
80   TIMER_CALLBACK_MEMBER(transfer_opaque_list_irq);
81   TIMER_CALLBACK_MEMBER(transfer_opaque_modifier_volume_list_irq);
82   TIMER_CALLBACK_MEMBER(transfer_translucent_list_irq);
83   TIMER_CALLBACK_MEMBER(transfer_translucent_modifier_volume_list_irq);
84   TIMER_CALLBACK_MEMBER(transfer_punch_through_list_irq);
85   TIMER_CALLBACK_MEMBER(vbin);
86   TIMER_CALLBACK_MEMBER(vbout);
87   TIMER_CALLBACK_MEMBER(hbin);
88   TIMER_CALLBACK_MEMBER(endofrender_video);
89   TIMER_CALLBACK_MEMBER(endofrender_tsp);
90   TIMER_CALLBACK_MEMBER(endofrender_isp);
9159   DECLARE_READ64_MEMBER(dc_aica_reg_r);
9260   DECLARE_WRITE64_MEMBER(dc_aica_reg_w);
9361   DECLARE_READ32_MEMBER(dc_arm_aica_r);
9462   DECLARE_WRITE32_MEMBER(dc_arm_aica_w);
9563   void wave_dma_execute(address_space &space);
96   void pvr_dma_execute(address_space &space);
9764   inline int decode_reg32_64(UINT32 offset, UINT64 mem_mask, UINT64 *shift);
9865   inline int decode_reg3216_64(UINT32 offset, UINT64 mem_mask, UINT64 *shift);
9966   int dc_compute_interrupt_level();
r23534r23535
10673   DECLARE_WRITE64_MEMBER( dc_gdrom_w );
10774   DECLARE_READ64_MEMBER( dc_g2_ctrl_r );
10875   DECLARE_WRITE64_MEMBER( dc_g2_ctrl_w );
109   DECLARE_READ64_MEMBER( pvr_ctrl_r );
110   DECLARE_WRITE64_MEMBER( pvr_ctrl_w );
11176   DECLARE_READ64_MEMBER( dc_modem_r );
11277   DECLARE_WRITE64_MEMBER( dc_modem_w );
11378   DECLARE_READ64_MEMBER( dc_rtc_r );
r23534r23535
11580
11681   required_device<cpu_device> m_maincpu;
11782   required_device<cpu_device> m_soundcpu;
83   required_device<powervr2_device> m_powervr2;
11884};
11985
12086/*--------- Ch2-DMA Control Registers ----------*/
r23534r23535
276242#define RTC3        ((0x00710008-0x00710000)/4)
277243
278244
279/*----------- defined in video/dc.c -----------*/
280
281extern UINT32 pvrctrl_regs[0x100/4];
282extern UINT64 *dc_texture_ram;
283extern UINT64 *dc_framebuffer_ram;
284
285extern UINT64 *pvr2_texture_ram;
286extern UINT64 *pvr2_framebuffer_ram;
287extern UINT64 *elan_ram;
288
289DECLARE_READ64_HANDLER( pvr_ta_r );
290DECLARE_WRITE64_HANDLER( pvr_ta_w );
291DECLARE_READ64_HANDLER( pvr2_ta_r );
292DECLARE_WRITE64_HANDLER( pvr2_ta_w );
293DECLARE_READ64_HANDLER( pvrs_ta_r );
294DECLARE_WRITE64_HANDLER( pvrs_ta_w );
295DECLARE_READ32_HANDLER( elan_regs_r );
296DECLARE_WRITE32_HANDLER( elan_regs_w );
297DECLARE_WRITE64_HANDLER( ta_fifo_poly_w );
298DECLARE_WRITE64_HANDLER( ta_fifo_yuv_w );
299
300
301
302245/*--------------- CORE registers --------------*/
303246#define PVRID               ((0x005f8000-0x005f8000)/4)
304247#define REVISION            ((0x005f8004-0x005f8000)/4)
trunk/src/mame/includes/naomi.h
r23534r23535
5656   DECLARE_WRITE64_MEMBER( naomi_unknown1_w );
5757   DECLARE_READ64_MEMBER( eeprom_93c46a_r );
5858   DECLARE_WRITE64_MEMBER( eeprom_93c46a_w );
59   DECLARE_WRITE64_MEMBER( ta_texture_directpath0_w );
60   DECLARE_WRITE64_MEMBER( ta_texture_directpath1_w );
6159   DECLARE_READ64_MEMBER( aw_flash_r );
6260   DECLARE_WRITE64_MEMBER( aw_flash_w );
6361   DECLARE_READ64_MEMBER( aw_modem_r );
trunk/src/mame/drivers/naomi.c
r23534r23535
15191519 * Common address map for Naomi 1, Naomi GD-Rom, Naomi 2, Atomiswave ...
15201520 */
15211521
1522// SB_LMMODE0
1523WRITE64_MEMBER(naomi_state::ta_texture_directpath0_w )
1524{
1525   int mode = pvrctrl_regs[SB_LMMODE0]&1;
1526   if (mode&1)
1527   {
1528      printf("ta_texture_directpath0_w 32-bit access!\n");
1529      COMBINE_DATA(&dc_framebuffer_ram[offset]);
1530   }
1531   else
1532   {
1533      COMBINE_DATA(&dc_texture_ram[offset]);
1534   }
1535}
15361522
1537// SB_LMMODE1
1538WRITE64_MEMBER(naomi_state::ta_texture_directpath1_w )
1539{
1540   int mode = pvrctrl_regs[SB_LMMODE1]&1;
1541   if (mode&1)
1542   {
1543      printf("ta_texture_directpath1_w 32-bit access!\n");
1544      COMBINE_DATA(&dc_framebuffer_ram[offset]);
1545   }
1546   else
1547   {
1548      COMBINE_DATA(&dc_texture_ram[offset]);
1549   }
1550}
1551
1552
15531523/*
15541524 * Naomi 1 address map
15551525 */
r23534r23535
15641534   AM_RANGE(0x005f7000, 0x005f70ff) AM_MIRROR(0x02000000) AM_DEVICE16( "rom_board", naomi_board, submap, U64(0x0000ffff0000ffff) )
15651535   AM_RANGE(0x005f7400, 0x005f74ff) AM_MIRROR(0x02000000) AM_DEVICE32( "rom_board", naomi_g1_device, amap, U64(0xffffffffffffffff) )
15661536   AM_RANGE(0x005f7800, 0x005f78ff) AM_MIRROR(0x02000000) AM_READWRITE(dc_g2_ctrl_r, dc_g2_ctrl_w )
1567   AM_RANGE(0x005f7c00, 0x005f7cff) AM_MIRROR(0x02000000) AM_READWRITE(pvr_ctrl_r, pvr_ctrl_w )
1568   AM_RANGE(0x005f8000, 0x005f9fff) AM_MIRROR(0x02000000) AM_READWRITE_LEGACY(pvr_ta_r, pvr_ta_w )
1537   AM_RANGE(0x005f7c00, 0x005f7cff) AM_MIRROR(0x02000000) AM_DEVREADWRITE("powervr2", powervr2_device, pvr_ctrl_r, pvr_ctrl_w)
1538   AM_RANGE(0x005f8000, 0x005f9fff) AM_MIRROR(0x02000000) AM_DEVREADWRITE("powervr2", powervr2_device, pvr_ta_r, pvr_ta_w )
15691539   AM_RANGE(0x00600000, 0x006007ff) AM_MIRROR(0x02000000) AM_READWRITE(dc_modem_r, dc_modem_w )
15701540   AM_RANGE(0x00700000, 0x00707fff) AM_MIRROR(0x02000000) AM_READWRITE(dc_aica_reg_r, dc_aica_reg_w )
15711541   AM_RANGE(0x00710000, 0x0071000f) AM_MIRROR(0x02000000) AM_READWRITE(dc_rtc_r, dc_rtc_w )
r23534r23535
15861556   AM_RANGE(0x0c000000, 0x0dffffff) AM_MIRROR(0xa2000000) AM_RAM AM_SHARE("dc_ram")
15871557
15881558   /* Area 4 */
1589   AM_RANGE(0x10000000, 0x107fffff) AM_MIRROR(0x02000000) AM_WRITE_LEGACY(ta_fifo_poly_w )
1590   AM_RANGE(0x10800000, 0x10ffffff) AM_MIRROR(0x02000000) AM_WRITE_LEGACY(ta_fifo_yuv_w )
1591   AM_RANGE(0x11000000, 0x11ffffff) AM_WRITE(ta_texture_directpath0_w ) // access to texture / framebuffer memory (either 32-bit or 64-bit area depending on SB_LMMODE0 register - cannot be written directly, only through dma / store queue)
1559   AM_RANGE(0x10000000, 0x107fffff) AM_MIRROR(0x02000000) AM_DEVWRITE("powervr2", powervr2_device, ta_fifo_poly_w)
1560   AM_RANGE(0x10800000, 0x10ffffff) AM_MIRROR(0x02000000) AM_DEVWRITE("powervr2", powervr2_device, ta_fifo_yuv_w)
1561   AM_RANGE(0x11000000, 0x11ffffff) AM_DEVWRITE("powervr2", powervr2_device, ta_texture_directpath0_w) // access to texture / framebuffer memory (either 32-bit or 64-bit area depending on SB_LMMODE0 register - cannot be written directly, only through dma / store queue)
15921562   /*       0x12000000 -0x13ffffff Mirror area of  0x10000000 -0x11ffffff */
1593   AM_RANGE(0x13000000, 0x13ffffff) AM_WRITE(ta_texture_directpath1_w ) // access to texture / framebuffer memory (either 32-bit or 64-bit area depending on SB_LMMODE1 register - cannot be written directly, only through dma / store queue)
1563   AM_RANGE(0x13000000, 0x13ffffff) AM_DEVWRITE("powervr2", powervr2_device, ta_texture_directpath1_w) // access to texture / framebuffer memory (either 32-bit or 64-bit area depending on SB_LMMODE1 register - cannot be written directly, only through dma / store queue)
15941564
15951565   /* Area 5 */
15961566   //AM_RANGE(0x14000000, 0x17ffffff) AM_NOP // MPX Ext.
r23534r23535
16161586   AM_RANGE(0x005f7000, 0x005f70ff) AM_MIRROR(0x02000000) AM_DEVICE16( "rom_board", naomi_board, submap, U64(0x0000ffff0000ffff) )
16171587   AM_RANGE(0x005f7400, 0x005f74ff) AM_MIRROR(0x02000000) AM_DEVICE32( "rom_board", naomi_g1_device, amap, U64(0xffffffffffffffff) )
16181588   AM_RANGE(0x005f7800, 0x005f78ff) AM_MIRROR(0x02000000) AM_READWRITE(dc_g2_ctrl_r, dc_g2_ctrl_w )
1619   AM_RANGE(0x005f7c00, 0x005f7cff) AM_READWRITE(pvr_ctrl_r, pvr_ctrl_w )
1620   AM_RANGE(0x005f8000, 0x005f9fff) AM_READWRITE_LEGACY(pvr_ta_r, pvr_ta_w )
1589   AM_RANGE(0x005f7c00, 0x005f7cff) AM_DEVREADWRITE("powervr2", powervr2_device, pvr_ctrl_r, pvr_ctrl_w)
1590   AM_RANGE(0x005f8000, 0x005f9fff) AM_DEVREADWRITE("powervr2", powervr2_device, pvr_ta_r, pvr_ta_w )
16211591   AM_RANGE(0x00600000, 0x006007ff) AM_MIRROR(0x02000000) AM_READWRITE(dc_modem_r, dc_modem_w )
16221592   AM_RANGE(0x00700000, 0x00707fff) AM_MIRROR(0x02000000) AM_READWRITE(dc_aica_reg_r, dc_aica_reg_w )
16231593   AM_RANGE(0x00710000, 0x0071000f) AM_MIRROR(0x02000000) AM_READWRITE(dc_rtc_r, dc_rtc_w )
r23534r23535
16281598   AM_RANGE(0x0103ff00, 0x0103ffff) AM_MIRROR(0x02000000) AM_READWRITE(naomi_unknown1_r, naomi_unknown1_w ) // bios uses it, actual start and end addresses not known
16291599
16301600//  AM_RANGE(0x025f6800, 0x025f69ff) AM_READWRITE_LEGACY(dc_sysctrl_r, dc_sysctrl_w ) // second PVR DMA!
1631//  AM_RANGE(0x025f7c00, 0x025f7cff) AM_READWRITE(pvr_ctrl_r, pvr_ctrl_w )
1632   AM_RANGE(0x025f8000, 0x025f9fff) AM_READWRITE_LEGACY(pvr2_ta_r, pvr2_ta_w )
1601//  AM_RANGE(0x025f7c00, 0x025f7cff) AM_DEVREADWRITE("powervr2", powervr2_device, pvr_ctrl_r, pvr_ctrl_w)
1602   AM_RANGE(0x025f8000, 0x025f9fff) AM_DEVREADWRITE("powervr2", powervr2_device, pvr2_ta_r, pvr2_ta_w )
16331603
16341604   /* Area 1 */
16351605   AM_RANGE(0x04000000, 0x04ffffff) AM_RAM AM_SHARE("dc_texture_ram")      // texture memory 64 bit access
r23534r23535
16391609
16401610   /* Area 2*/
16411611   AM_RANGE(0x085f6800, 0x085f69ff) AM_WRITE(dc_sysctrl_w ) // writes to BOTH PVRs
1642   AM_RANGE(0x085f8000, 0x085f9fff) AM_WRITE_LEGACY(pvrs_ta_w ) // writes to BOTH PVRs
1643   AM_RANGE(0x08800000, 0x088000ff) AM_READWRITE32_LEGACY(elan_regs_r, elan_regs_w, U64(0xffffffffffffffff) ) // T&L chip registers
1612   AM_RANGE(0x085f8000, 0x085f9fff) AM_DEVWRITE("powervr2", powervr2_device, pvrs_ta_w ) // writes to BOTH PVRs
1613   AM_RANGE(0x08800000, 0x088000ff) AM_DEVREADWRITE32("powervr2", powervr2_device, elan_regs_r, elan_regs_w, U64(0xffffffffffffffff) ) // T&L chip registers
16441614//  AM_RANGE(0x09000000, 0x09??????) T&L command processing
16451615   AM_RANGE(0x0a000000, 0x0bffffff) AM_RAM AM_SHARE("elan_ram") // T&L chip RAM
16461616
r23534r23535
16481618   AM_RANGE(0x0c000000, 0x0dffffff) AM_MIRROR(0xa2000000) AM_RAM AM_SHARE("dc_ram")
16491619
16501620   /* Area 4 */
1651   AM_RANGE(0x10000000, 0x107fffff) AM_WRITE_LEGACY(ta_fifo_poly_w )
1652   AM_RANGE(0x10800000, 0x10ffffff) AM_WRITE_LEGACY(ta_fifo_yuv_w )
1653   AM_RANGE(0x11000000, 0x11ffffff) AM_WRITE(ta_texture_directpath0_w ) // access to texture / framebuffer memory (either 32-bit or 64-bit area depending on SB_LMMODE0 register - cannot be written directly, only through dma / store queue)
1621   AM_RANGE(0x10000000, 0x107fffff) AM_DEVWRITE("powervr2", powervr2_device, ta_fifo_poly_w)
1622   AM_RANGE(0x10800000, 0x10ffffff) AM_DEVWRITE("powervr2", powervr2_device, ta_fifo_yuv_w)
1623   AM_RANGE(0x11000000, 0x11ffffff) AM_DEVWRITE("powervr2", powervr2_device, ta_texture_directpath0_w) // access to texture / framebuffer memory (either 32-bit or 64-bit area depending on SB_LMMODE0 register - cannot be written directly, only through dma / store queue)
16541624   /*       0x12000000 -0x13ffffff Mirror area of  0x10000000 -0x11ffffff */
1655   AM_RANGE(0x13000000, 0x13ffffff) AM_WRITE(ta_texture_directpath1_w ) // access to texture / framebuffer memory (either 32-bit or 64-bit area depending on SB_LMMODE1 register - cannot be written directly, only through dma / store queue)
1625   AM_RANGE(0x13000000, 0x13ffffff) AM_DEVWRITE("powervr2", powervr2_device, ta_texture_directpath1_w) // access to texture / framebuffer memory (either 32-bit or 64-bit area depending on SB_LMMODE1 register - cannot be written directly, only through dma / store queue)
16561626
16571627   /* Area 5 */
16581628   //AM_RANGE(0x14000000, 0x17ffffff) AM_NOP // MPX Ext.
r23534r23535
17691739   AM_RANGE(0x005f7000, 0x005f70ff) AM_MIRROR(0x02000000) AM_DEVICE16( "rom_board", aw_rom_board, submap, U64(0x0000ffff0000ffff) )
17701740   AM_RANGE(0x005f7400, 0x005f74ff) AM_MIRROR(0x02000000) AM_DEVICE32( "rom_board", naomi_g1_device, amap, U64(0xffffffffffffffff) )
17711741   AM_RANGE(0x005f7800, 0x005f78ff) AM_READWRITE(dc_g2_ctrl_r, dc_g2_ctrl_w )
1772   AM_RANGE(0x005f7c00, 0x005f7cff) AM_READWRITE(pvr_ctrl_r, pvr_ctrl_w )
1773   AM_RANGE(0x005f8000, 0x005f9fff) AM_READWRITE_LEGACY(pvr_ta_r, pvr_ta_w )
1742   AM_RANGE(0x005f7c00, 0x005f7cff) AM_DEVREADWRITE("powervr2", powervr2_device, pvr_ctrl_r, pvr_ctrl_w)
1743   AM_RANGE(0x005f8000, 0x005f9fff) AM_DEVREADWRITE("powervr2", powervr2_device, pvr_ta_r, pvr_ta_w )
17741744   AM_RANGE(0x00600000, 0x006007ff) AM_READWRITE(aw_modem_r, aw_modem_w )
17751745   AM_RANGE(0x00700000, 0x00707fff) AM_READWRITE(dc_aica_reg_r, dc_aica_reg_w )
17761746   AM_RANGE(0x00710000, 0x0071000f) AM_READWRITE(dc_rtc_r, dc_rtc_w )
r23534r23535
17961766   AM_RANGE(0x8d000000, 0x8dffffff) AM_RAM AM_SHARE("dc_ram") // RAM access through cache
17971767
17981768   /* Area 4 - half the texture memory, like dreamcast, not naomi */
1799   AM_RANGE(0x10000000, 0x107fffff) AM_MIRROR(0x02000000) AM_WRITE_LEGACY(ta_fifo_poly_w )
1800   AM_RANGE(0x10800000, 0x10ffffff) AM_MIRROR(0x02000000) AM_WRITE_LEGACY(ta_fifo_yuv_w )
1801   AM_RANGE(0x11000000, 0x117fffff) AM_WRITE(ta_texture_directpath0_w ) AM_MIRROR(0x00800000)  // access to texture / framebuffer memory (either 32-bit or 64-bit area depending on SB_LMMODE0 register - cannot be written directly, only through dma / store queue
1769   AM_RANGE(0x10000000, 0x107fffff) AM_MIRROR(0x02000000) AM_DEVWRITE("powervr2", powervr2_device, ta_fifo_poly_w)
1770   AM_RANGE(0x10800000, 0x10ffffff) AM_MIRROR(0x02000000) AM_DEVWRITE("powervr2", powervr2_device, ta_fifo_yuv_w)
1771   AM_RANGE(0x11000000, 0x117fffff) AM_DEVWRITE("powervr2", powervr2_device, ta_texture_directpath0_w) AM_MIRROR(0x00800000)  // access to texture / framebuffer memory (either 32-bit or 64-bit area depending on SB_LMMODE0 register - cannot be written directly, only through dma / store queue
18021772   /*       0x12000000 -0x13ffffff Mirror area of  0x10000000 -0x11ffffff */
1803   AM_RANGE(0x13000000, 0x137fffff) AM_WRITE(ta_texture_directpath1_w ) AM_MIRROR(0x00800000) // access to texture / framebuffer memory (either 32-bit or 64-bit area depending on SB_LMMODE1 register - cannot be written directly, only through dma / store queue
1773   AM_RANGE(0x13000000, 0x137fffff) AM_DEVWRITE("powervr2", powervr2_device, ta_texture_directpath1_w) AM_MIRROR(0x00800000) // access to texture / framebuffer memory (either 32-bit or 64-bit area depending on SB_LMMODE1 register - cannot be written directly, only through dma / store queue
18041774
18051775
18061776   /* Area 5 */
r23534r23535
25262496   MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(2500) /* not accurate */)
25272497   MCFG_SCREEN_SIZE(640, 480)
25282498   MCFG_SCREEN_VISIBLE_AREA(0, 640-1, 0, 480-1)
2529   MCFG_SCREEN_UPDATE_DRIVER(naomi_state, screen_update_dc)
2530
2499   MCFG_SCREEN_UPDATE_DEVICE("powervr2", powervr2_device, screen_update)
25312500   MCFG_PALETTE_LENGTH(0x1000)
2501   MCFG_POWERVR2_ADD("powervr2")
25322502
25332503
25342504   MCFG_SPEAKER_STANDARD_STEREO("lspeaker", "rspeaker")
trunk/src/mame/machine/dc.c
r23534r23535
1717
1818#define DEBUG_SYSCTRL   (0)
1919#define DEBUG_AICA_DMA (0)
20#define DEBUG_PVRCTRL   (0)
2120
2221#if DEBUG_SYSCTRL
2322static const char *const sysctrl_names[] =
r23534r23535
8281   dc_update_interrupt_status();
8382}
8483
85TIMER_CALLBACK_MEMBER(dc_state::pvr_dma_irq)
86{
87   m_pvr_dma.start = pvrctrl_regs[SB_PDST] = 0;
88   dc_sysctrl_regs[SB_ISTNRM] |= IST_DMA_PVR;
89   dc_update_interrupt_status();
90}
91
9284void naomi_g1_irq(running_machine &machine)
9385{
9486   dc_state *state = machine.driver_data<dc_state>();
r23534r23535
158150   machine().scheduler().timer_set(attotime::from_usec(300), timer_expired_delegate(FUNC(dc_state::aica_dma_irq),this));
159151}
160152
161void dc_state::pvr_dma_execute(address_space &space)
162{
163   UINT32 src,dst,size;
164   dst = m_pvr_dma.pvr_addr;
165   src = m_pvr_dma.sys_addr;
166   size = 0;
167
168   /* used so far by usagui and sprtjam*/
169   //printf("PVR-DMA start\n");
170   //printf("%08x %08x %08x\n",m_pvr_dma.pvr_addr,m_pvr_dma.sys_addr,m_pvr_dma.size);
171   //printf("src %s dst %08x\n",m_pvr_dma.dir ? "->" : "<-",m_pvr_dma.sel);
172
173   /* 0 rounding size = 16 Mbytes */
174   if(m_pvr_dma.size == 0) { m_pvr_dma.size = 0x100000; }
175
176   if(m_pvr_dma.dir == 0)
177   {
178      for(;size<m_pvr_dma.size;size+=4)
179      {
180         space.write_dword(dst,space.read_dword(src));
181         src+=4;
182         dst+=4;
183      }
184   }
185   else
186   {
187      for(;size<m_pvr_dma.size;size+=4)
188      {
189         space.write_dword(src,space.read_dword(dst));
190         src+=4;
191         dst+=4;
192      }
193   }
194   /* Note: do not update the params, since this DMA type doesn't support it. */
195   /* TODO: timing of this */
196   machine().scheduler().timer_set(attotime::from_usec(250), timer_expired_delegate(FUNC(dc_state::pvr_dma_irq),this));
197}
198
199153// register decode helpers
200154
201155// this accepts only 32-bit accesses
r23534r23535
314268   }
315269
316270   /* PVR-DMA HW trigger */
317   if(m_pvr_dma.flag && ((m_pvr_dma.sel & 1) == 1))
271   if(m_powervr2->m_pvr_dma.flag && ((m_powervr2->m_pvr_dma.sel & 1) == 1))
318272   {
319273      if((dc_sysctrl_regs[SB_PDTNRM] & dc_sysctrl_regs[SB_ISTNRM]) || (dc_sysctrl_regs[SB_PDTEXT] & dc_sysctrl_regs[SB_ISTEXT]))
320274      {
321275         address_space &space = m_maincpu->space(AS_PROGRAM);
322276
323277         printf("PVR-DMA HW trigger\n");
324         pvr_dma_execute(space);
278         m_powervr2->pvr_dma_execute(space);
325279      }
326280   }
327281}
r23534r23535
582536   return reg;
583537}
584538
585READ64_MEMBER(dc_state::pvr_ctrl_r )
586{
587   int reg;
588   UINT64 shift;
589
590   reg = decode_reg_64(offset, mem_mask, &shift);
591
592   #if DEBUG_PVRCTRL
593   mame_printf_verbose("PVRCTRL: [%08x] read %x @ %x (reg %x), mask %" I64FMT "x (PC=%x)\n", 0x5f7c00+reg*4, pvrctrl_regs[reg], offset, reg, mem_mask, space.device().safe_pc());
594   #endif
595
596   return (UINT64)pvrctrl_regs[reg] << shift;
597}
598
599WRITE64_MEMBER(dc_state::pvr_ctrl_w )
600{
601   int reg;
602   UINT64 shift;
603   UINT32 dat;
604   UINT8 old;
605
606   reg = decode_reg_64(offset, mem_mask, &shift);
607   dat = (UINT32)(data >> shift);
608
609   switch (reg)
610   {
611      case SB_PDSTAP: m_pvr_dma.pvr_addr = dat; break;
612      case SB_PDSTAR: m_pvr_dma.sys_addr = dat; break;
613      case SB_PDLEN: m_pvr_dma.size = dat; break;
614      case SB_PDDIR: m_pvr_dma.dir = dat & 1; break;
615      case SB_PDTSEL:
616         m_pvr_dma.sel = dat & 1;
617         //if(m_pvr_dma.sel & 1)
618         //  printf("Warning: Unsupported irq mode trigger PVR-DMA\n");
619         break;
620      case SB_PDEN: m_pvr_dma.flag = dat & 1; break;
621      case SB_PDST:
622         old = m_pvr_dma.start & 1;
623         m_pvr_dma.start = dat & 1;
624
625         if(((old & 1) == 0) && m_pvr_dma.flag && m_pvr_dma.start && ((m_pvr_dma.sel & 1) == 0)) // 0 -> 1
626            pvr_dma_execute(space);
627         break;
628   }
629
630   #if DEBUG_PVRCTRL
631   mame_printf_verbose("PVRCTRL: [%08x=%x] write %" I64FMT "x to %x (reg %x), mask %" I64FMT "x\n", 0x5f7c00+reg*4, dat, data>>shift, offset, reg, mem_mask);
632   #endif
633
634//  pvrctrl_regs[reg] |= dat;
635   pvrctrl_regs[reg] = dat;
636
637}
638
639539READ64_MEMBER(dc_state::dc_modem_r )
640540{
641541   int reg;
r23534r23535
770670   save_item(NAME(m_wave_dma.indirect));
771671   save_item(NAME(m_wave_dma.start));
772672   save_item(NAME(m_wave_dma.sel));
773   save_item(NAME(m_pvr_dma.pvr_addr));
774   save_item(NAME(m_pvr_dma.sys_addr));
775   save_item(NAME(m_pvr_dma.size));
776   save_item(NAME(m_pvr_dma.sel));
777   save_item(NAME(m_pvr_dma.dir));
778   save_item(NAME(m_pvr_dma.flag));
779   save_item(NAME(m_pvr_dma.start));
780   save_pointer(NAME(pvrta_regs),0x2000/4);
781   save_pointer(NAME(pvrctrl_regs),0x100/4);
782   save_item(NAME(debug_dip_status));
783   save_pointer(NAME(tafifo_buff),32);
784   save_item(NAME(scanline));
785   save_item(NAME(next_y));
786673   save_pointer(NAME(dc_sound_ram.target()),dc_sound_ram.bytes());
787674}
788675
trunk/src/emu/delegate.h
r23534r23535
566566   static delegate_generic_class *late_bind_helper(delegate_late_bind &object)
567567   {
568568      _FunctionClass *result = dynamic_cast<_FunctionClass *>(&object);
569      if (result == NULL)
569      if (result == NULL) {
570        abort();
570571         throw binding_type_exception(typeid(_FunctionClass), typeid(object));
572      }
571573      return reinterpret_cast<delegate_generic_class *>(result);
572574   }
573575
trunk/src/emu/devcb2.c
r23534r23535
232232   }
233233   catch (binding_type_exception &binderr)
234234   {
235      abort();
235236      throw emu_fatalerror("Error performing a late bind of type %s to %s\n", binderr.m_actual_type.name(), binderr.m_target_type.name());
236237   }
237238}
r23534r23535
449450   }
450451   catch (binding_type_exception &binderr)
451452   {
453      abort();
452454      throw emu_fatalerror("Error performing a late bind of type %s to %s\n", binderr.m_actual_type.name(), binderr.m_target_type.name());
453455   }
454456}
trunk/src/mess/drivers/dccons.c
r23534r23535
110110   COMBINE_DATA((UINT64 *)dc_sound_ram.target() + offset);
111111}
112112
113
114   // SB_LMMODE0
115WRITE64_MEMBER(dc_cons_state::ta_texture_directpath0_w )
116   {
117   int mode = pvrctrl_regs[SB_LMMODE0]&1;
118   if (mode&1)
119   {
120      printf("ta_texture_directpath0_w 32-bit access!\n");
121      COMBINE_DATA(&dc_framebuffer_ram[offset]);
122   }
123   else
124   {
125      COMBINE_DATA(&dc_texture_ram[offset]);
126   }
127   }
128
129   // SB_LMMODE1
130WRITE64_MEMBER(dc_cons_state::ta_texture_directpath1_w )
131   {
132   int mode = pvrctrl_regs[SB_LMMODE1]&1;
133   if (mode&1)
134   {
135      printf("ta_texture_directpath1_w 32-bit access!\n");
136      COMBINE_DATA(&dc_framebuffer_ram[offset]);
137   }
138   else
139   {
140      COMBINE_DATA(&dc_texture_ram[offset]);
141   }
142   }
143
144113static ADDRESS_MAP_START( dc_map, AS_PROGRAM, 64, dc_cons_state )
145114   AM_RANGE(0x00000000, 0x001fffff) AM_ROM AM_WRITENOP             // BIOS
146115   AM_RANGE(0x00200000, 0x0021ffff) AM_ROM AM_REGION("maincpu", 0x200000)  // flash
r23534r23535
149118   AM_RANGE(0x005f7000, 0x005f70ff) AM_READWRITE(dc_mess_gdrom_r, dc_mess_gdrom_w )
150119   AM_RANGE(0x005f7400, 0x005f74ff) AM_READWRITE(dc_mess_g1_ctrl_r, dc_mess_g1_ctrl_w )
151120   AM_RANGE(0x005f7800, 0x005f78ff) AM_READWRITE(dc_g2_ctrl_r, dc_g2_ctrl_w )
152   AM_RANGE(0x005f7c00, 0x005f7cff) AM_READWRITE(pvr_ctrl_r, pvr_ctrl_w )
153   AM_RANGE(0x005f8000, 0x005f9fff) AM_READWRITE_LEGACY(pvr_ta_r, pvr_ta_w )
121   AM_RANGE(0x005f7c00, 0x005f7cff) AM_DEVREADWRITE("powervr2", powervr2_device, pvr_ctrl_r, pvr_ctrl_w)
122   AM_RANGE(0x005f8000, 0x005f9fff) AM_DEVREADWRITE("powervr2", powervr2_device, pvr_ta_r, pvr_ta_w )
154123   AM_RANGE(0x00600000, 0x006007ff) AM_READWRITE(dc_modem_r, dc_modem_w )
155124   AM_RANGE(0x00700000, 0x00707fff) AM_READWRITE(dc_aica_reg_r, dc_aica_reg_w )
156125   AM_RANGE(0x00710000, 0x0071000f) AM_READWRITE(dc_rtc_r, dc_rtc_w )
r23534r23535
167136   AM_RANGE(0x0f000000, 0x0fffffff) AM_RAM AM_SHARE("dc_ram")// mirror
168137
169138   /* Area 4 */
170   AM_RANGE(0x10000000, 0x107fffff) AM_WRITE_LEGACY(ta_fifo_poly_w )
171   AM_RANGE(0x10800000, 0x10ffffff) AM_WRITE_LEGACY(ta_fifo_yuv_w )
172   AM_RANGE(0x11000000, 0x117fffff) AM_WRITE(ta_texture_directpath0_w ) AM_MIRROR(0x00800000)  // access to texture / fraembfufer memory (either 32-bit or 64-bit area depending on SB_LMMODE0 register - cannot be written directly, only through dma / store queue
139   AM_RANGE(0x10000000, 0x107fffff) AM_DEVWRITE("powervr2", powervr2_device, ta_fifo_poly_w)
140   AM_RANGE(0x10800000, 0x10ffffff) AM_DEVWRITE("powervr2", powervr2_device, ta_fifo_yuv_w)
141   AM_RANGE(0x11000000, 0x117fffff) AM_DEVWRITE("powervr2", powervr2_device, ta_texture_directpath0_w) AM_MIRROR(0x00800000)  // access to texture / framebuffer memory (either 32-bit or 64-bit area depending on SB_LMMODE0 register - cannot be written directly, only through dma / store queue
173142
174   AM_RANGE(0x12000000, 0x127fffff) AM_WRITE_LEGACY(ta_fifo_poly_w )
175   AM_RANGE(0x12800000, 0x12ffffff) AM_WRITE_LEGACY(ta_fifo_yuv_w )
176   AM_RANGE(0x13000000, 0x137fffff) AM_WRITE(ta_texture_directpath1_w ) AM_MIRROR(0x00800000) // access to texture / fraembfufer memory (either 32-bit or 64-bit area depending on SB_LMMODE1 register - cannot be written directly, only through dma / store queue
143   AM_RANGE(0x12000000, 0x127fffff) AM_DEVWRITE("powervr2", powervr2_device, ta_fifo_poly_w)
144   AM_RANGE(0x12800000, 0x12ffffff) AM_DEVWRITE("powervr2", powervr2_device, ta_fifo_yuv_w)
145   AM_RANGE(0x13000000, 0x137fffff) AM_DEVWRITE("powervr2", powervr2_device, ta_texture_directpath1_w) AM_MIRROR(0x00800000) // access to texture / framebuffer memory (either 32-bit or 64-bit area depending on SB_LMMODE1 register - cannot be written directly, only through dma / store queue
177146
178147   AM_RANGE(0x8c000000, 0x8cffffff) AM_RAM AM_SHARE("dc_ram")  // another RAM mirror
179148
r23534r23535
235204   MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(2500) /* not accurate */)
236205   MCFG_SCREEN_SIZE(640, 480)
237206   MCFG_SCREEN_VISIBLE_AREA(0, 640-1, 0, 480-1)
238   MCFG_SCREEN_UPDATE_DRIVER(dc_cons_state, screen_update_dc)
239
207   MCFG_SCREEN_UPDATE_DEVICE("powervr2", powervr2_device, screen_update)
240208   MCFG_PALETTE_LENGTH(0x1000)
209   MCFG_POWERVR2_ADD("powervr2")
241210
242
243211   MCFG_SPEAKER_STANDARD_STEREO("lspeaker", "rspeaker")
244212   MCFG_SOUND_ADD("aica", AICA, 0)
245213   MCFG_SOUND_CONFIG(dc_aica_interface)
trunk/src/mess/mess.mak
r23534r23535
683683   $(MAME_DRIVERS)/megatech.o  \
684684   $(MAME_MACHINE)/dc.o        \
685685   $(MAME_DRIVERS)/naomi.o     \
686   $(MAME_MACHINE)/dc.o        \
687   $(MAME_VIDEO)/dc.o          \
686   $(MAME_VIDEO)/powervr2.o    \
688687   $(MAME_MACHINE)/naomi.o     \
689688   $(MAME_MACHINE)/naomig1.o   \
690689   $(MAME_MACHINE)/naomibd.o   \
r23534r23535
699698   $(MAME_MACHINE)/mapledev.o  \
700699   $(MAME_MACHINE)/dc-ctrl.o   \
701700   $(MAME_MACHINE)/jvs13551.o  \
702   $(MAME_VIDEO)/dc.o          \
703701   $(MAME_VIDEO)/neogeo.o      \
704702   $(MAME_MACHINE)/neoprot.o   \
705703   $(MAME_MACHINE)/neocrypt.o  \
trunk/src/mess/includes/dccons.h
r23534r23535
2020   DECLARE_WRITE64_MEMBER(dc_pdtra_w);
2121   DECLARE_READ64_MEMBER(dc_arm_r);
2222   DECLARE_WRITE64_MEMBER(dc_arm_w);
23   DECLARE_WRITE64_MEMBER(ta_texture_directpath0_w);
24   DECLARE_WRITE64_MEMBER(ta_texture_directpath1_w);
2523   DECLARE_WRITE_LINE_MEMBER(aica_irq);
2624   void gdrom_raise_irq();
2725   TIMER_CALLBACK_MEMBER( atapi_xfer_end );

Previous 199869 Revisions Next


© 1997-2024 The MAME Team