1 // license:BSD-3-Clause
2 // copyright-holders:smf
3 /*
4  * PlayStation Motion Decoder emulator
5  *
6  * Copyright 2003-2011 smf
7  *
8  * Thanks to Oliver Galibert for help figuring out IDCT
9  *
10  */
11 
12 #include "emu.h"
13 #include "mdec.h"
14 #include "dma.h"
15 
16 #define VERBOSE_LEVEL ( 0 )
17 
verboselog(device_t & device,int n_level,const char * s_fmt,...)18 static inline void ATTR_PRINTF(3,4) verboselog( device_t& device, int n_level, const char *s_fmt, ... )
19 {
20 	if( VERBOSE_LEVEL >= n_level )
21 	{
22 		va_list v;
23 		char buf[ 32768 ];
24 		va_start( v, s_fmt );
25 		vsprintf( buf, s_fmt, v );
26 		va_end( v );
27 		device.logerror( "%s: %s", device.machine().describe_context(), buf );
28 	}
29 }
30 
31 DEFINE_DEVICE_TYPE(PSX_MDEC, psxmdec_device, "psxmdec", "Sony PSX MDEC")
32 
psxmdec_device(const machine_config & mconfig,const char * tag,device_t * owner,uint32_t clock)33 psxmdec_device::psxmdec_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
34 	: device_t(mconfig, PSX_MDEC, tag, owner, clock), n_decoded(0), n_offset(0), n_0_command(0), n_0_address(0), n_0_size(0), n_1_command(0), n_1_status(0)
35 {
36 }
37 
device_reset()38 void psxmdec_device::device_reset()
39 {
40 	n_0_command = 0;
41 	n_0_address = 0;
42 	n_0_size = 0;
43 	n_1_command = 0;
44 	n_1_status = 0;
45 	n_offset = 0;
46 	n_decoded = 0;
47 }
48 
device_post_load()49 void psxmdec_device::device_post_load()
50 {
51 	mdec_cos_precalc();
52 }
53 
device_start()54 void psxmdec_device::device_start()
55 {
56 	for( int n = 0; n < 256; n++ )
57 	{
58 		p_n_clamp8[ n ] = 0;
59 		p_n_clamp8[ n + 256 ] = n;
60 		p_n_clamp8[ n + 512 ] = 255;
61 
62 		p_n_r5[ n ] = 0;
63 		p_n_r5[ n + 256 ] = ( n >> 3 );
64 		p_n_r5[ n + 512 ] = ( 255 >> 3 );
65 
66 		p_n_g5[ n ] = 0;
67 		p_n_g5[ n + 256 ] = ( n >> 3 ) << 5;
68 		p_n_g5[ n + 512 ] = ( 255 >> 3 ) << 5;
69 
70 		p_n_b5[ n ] = 0;
71 		p_n_b5[ n + 256 ] = ( n >> 3 ) << 10;
72 		p_n_b5[ n + 512 ] = ( 255 >> 3 ) << 10;
73 	}
74 
75 	save_item( NAME( n_0_command ) );
76 	save_item( NAME( n_0_address ) );
77 	save_item( NAME( n_0_size ) );
78 	save_item( NAME( n_1_command ) );
79 	save_item( NAME( n_1_status ) );
80 	save_item( NAME( p_n_quantize_y ) );
81 	save_item( NAME( p_n_quantize_uv ) );
82 	save_item( NAME( p_n_cos ) );
83 }
84 
85 #ifdef UNUSED_FUNCTION
psxwriteword(uint32_t * p_n_psxram,uint32_t n_address,uint16_t n_data)86 static inline void psxwriteword( uint32_t *p_n_psxram, uint32_t n_address, uint16_t n_data )
87 {
88 	*( (uint16_t *)( (uint8_t *)p_n_psxram + WORD_XOR_LE( n_address ) ) ) = n_data;
89 }
90 #endif
91 
psxreadword(uint32_t * p_n_psxram,uint32_t n_address)92 static inline uint16_t psxreadword( uint32_t *p_n_psxram, uint32_t n_address )
93 {
94 	return *( (uint16_t *)( (uint8_t *)p_n_psxram + WORD_XOR_LE( n_address ) ) );
95 }
96 
97 const uint32_t psxmdec_device::m_p_n_mdec_zigzag[ DCTSIZE2 ] =
98 {
99 		0,  1,  8, 16,  9,  2,  3, 10,
100 	17, 24, 32, 25, 18, 11,  4,  5,
101 	12, 19, 26, 33, 40, 48, 41, 34,
102 	27, 20, 13,  6,  7, 14, 21, 28,
103 	35, 42, 49, 56, 57, 50, 43, 36,
104 	29, 22, 15, 23, 30, 37, 44, 51,
105 	58, 59, 52, 45, 38, 31, 39, 46,
106 	53, 60, 61, 54, 47, 55, 62, 63
107 };
108 
mdec_cos_precalc()109 void psxmdec_device::mdec_cos_precalc()
110 {
111 	uint32_t n_x;
112 	uint32_t n_y;
113 	uint32_t n_u;
114 	uint32_t n_v;
115 	int32_t *p_n_precalc = p_n_cos_precalc;
116 
117 	for( n_y = 0; n_y < 8; n_y++ )
118 	{
119 		for( n_x = 0; n_x < 8; n_x++ )
120 		{
121 			for( n_v = 0; n_v < 8; n_v++ )
122 			{
123 				for( n_u = 0; n_u < 8; n_u++ )
124 				{
125 					*( p_n_precalc++ ) =
126 						( ( p_n_cos[ ( n_u * 8 ) + n_x ] *
127 						p_n_cos[ ( n_v * 8 ) + n_y ] ) >> ( 30 - MDEC_COS_PRECALC_BITS ) );
128 				}
129 			}
130 		}
131 	}
132 }
133 
mdec_idct(int32_t * p_n_src,int32_t * p_n_dst)134 void psxmdec_device::mdec_idct( int32_t *p_n_src, int32_t *p_n_dst )
135 {
136 	int32_t *p_n_precalc = p_n_cos_precalc;
137 
138 	for( uint32_t n_yx = 0; n_yx < DCTSIZE2; n_yx++ )
139 	{
140 		int32_t p_n_z[ 8 ];
141 		int32_t *p_n_data = p_n_src;
142 
143 		memset( p_n_z, 0, sizeof( p_n_z ) );
144 
145 		for( uint32_t n_vu = 0; n_vu < DCTSIZE2 / 8; n_vu++ )
146 		{
147 			p_n_z[ 0 ] += p_n_data[ 0 ] * p_n_precalc[ 0 ];
148 			p_n_z[ 1 ] += p_n_data[ 1 ] * p_n_precalc[ 1 ];
149 			p_n_z[ 2 ] += p_n_data[ 2 ] * p_n_precalc[ 2 ];
150 			p_n_z[ 3 ] += p_n_data[ 3 ] * p_n_precalc[ 3 ];
151 			p_n_z[ 4 ] += p_n_data[ 4 ] * p_n_precalc[ 4 ];
152 			p_n_z[ 5 ] += p_n_data[ 5 ] * p_n_precalc[ 5 ];
153 			p_n_z[ 6 ] += p_n_data[ 6 ] * p_n_precalc[ 6 ];
154 			p_n_z[ 7 ] += p_n_data[ 7 ] * p_n_precalc[ 7 ];
155 			p_n_data += 8;
156 			p_n_precalc += 8;
157 		}
158 
159 		*( p_n_dst++ ) = ( p_n_z[ 0 ] + p_n_z[ 1 ] + p_n_z[ 2 ] + p_n_z[ 3 ] +
160 			p_n_z[ 4 ] + p_n_z[ 5 ] + p_n_z[ 6 ] + p_n_z[ 7 ] ) >> ( MDEC_COS_PRECALC_BITS + 2 );
161 	}
162 }
163 
mdec_unpack_run(uint16_t n_packed)164 static inline uint16_t mdec_unpack_run( uint16_t n_packed )
165 {
166 	return n_packed >> 10;
167 }
168 
mdec_unpack_val(uint16_t n_packed)169 static inline int32_t mdec_unpack_val( uint16_t n_packed )
170 {
171 	return ( ( (int32_t)n_packed ) << 22 ) >> 22;
172 }
173 
mdec_unpack(uint32_t * p_n_psxram,uint32_t n_address)174 uint32_t psxmdec_device::mdec_unpack( uint32_t *p_n_psxram, uint32_t n_address )
175 {
176 	uint8_t n_z;
177 	int32_t n_qscale;
178 	uint16_t n_packed;
179 	int32_t *p_n_block;
180 	int32_t p_n_unpacked[ 64 ];
181 	int32_t *p_n_q;
182 
183 	p_n_q = p_n_quantize_uv;
184 	p_n_block = m_p_n_unpacked;
185 
186 	for( uint32_t n_block = 0; n_block < 6; n_block++ )
187 	{
188 		memset( p_n_unpacked, 0, sizeof( p_n_unpacked ) );
189 
190 		if( n_block == 2 )
191 		{
192 			p_n_q = p_n_quantize_y;
193 		}
194 		n_packed = psxreadword( p_n_psxram, n_address );
195 		n_address += 2;
196 		if( n_packed == 0xfe00 )
197 		{
198 			break;
199 		}
200 
201 		n_qscale = mdec_unpack_run( n_packed );
202 		p_n_unpacked[ 0 ] = mdec_unpack_val( n_packed ) * p_n_q[ 0 ];
203 
204 		n_z = 0;
205 		for( ;; )
206 		{
207 			n_packed = psxreadword( p_n_psxram, n_address );
208 			n_address += 2;
209 
210 			if( n_packed == 0xfe00 )
211 			{
212 				break;
213 			}
214 			n_z += mdec_unpack_run( n_packed ) + 1;
215 			if( n_z > 63 )
216 			{
217 				break;
218 			}
219 			p_n_unpacked[ m_p_n_mdec_zigzag[ n_z ] ] = ( mdec_unpack_val( n_packed ) * p_n_q[ n_z ] * n_qscale ) / 8;
220 		}
221 		mdec_idct( p_n_unpacked, p_n_block );
222 		p_n_block += DCTSIZE2;
223 	}
224 	return n_address;
225 }
226 
mdec_cr_to_r(int32_t n_cr)227 static inline int32_t mdec_cr_to_r( int32_t n_cr )
228 {
229 	return ( 1435 * n_cr ) >> 10;
230 }
231 
mdec_cr_to_g(int32_t n_cr)232 static inline int32_t mdec_cr_to_g( int32_t n_cr )
233 {
234 	return ( -731 * n_cr ) >> 10;
235 }
236 
mdec_cb_to_g(int32_t n_cb)237 static inline int32_t mdec_cb_to_g( int32_t n_cb )
238 {
239 	return ( -351 * n_cb ) >> 10;
240 }
241 
mdec_cb_to_b(int32_t n_cb)242 static inline int32_t mdec_cb_to_b( int32_t n_cb )
243 {
244 	return ( 1814 * n_cb ) >> 10;
245 }
246 
mdec_clamp_r5(int32_t n_r) const247 uint16_t psxmdec_device::mdec_clamp_r5( int32_t n_r ) const
248 {
249 	return p_n_r5[ n_r + 128 + 256 ];
250 }
251 
mdec_clamp_g5(int32_t n_g) const252 uint16_t psxmdec_device::mdec_clamp_g5( int32_t n_g ) const
253 {
254 	return p_n_g5[ n_g + 128 + 256 ];
255 }
256 
mdec_clamp_b5(int32_t n_b) const257 uint16_t psxmdec_device::mdec_clamp_b5( int32_t n_b ) const
258 {
259 	return p_n_b5[ n_b + 128 + 256 ];
260 }
261 
mdec_makergb15(uint32_t n_address,int32_t n_r,int32_t n_g,int32_t n_b,int32_t * p_n_y,uint16_t n_stp)262 void psxmdec_device::mdec_makergb15( uint32_t n_address, int32_t n_r, int32_t n_g, int32_t n_b, int32_t *p_n_y, uint16_t n_stp )
263 {
264 	p_n_output[ WORD_XOR_LE( n_address + 0 ) / 2 ] = n_stp |
265 		mdec_clamp_r5( p_n_y[ 0 ] + n_r ) |
266 		mdec_clamp_g5( p_n_y[ 0 ] + n_g ) |
267 		mdec_clamp_b5( p_n_y[ 0 ] + n_b );
268 
269 	p_n_output[ WORD_XOR_LE( n_address + 2 ) / 2 ] = n_stp |
270 		mdec_clamp_r5( p_n_y[ 1 ] + n_r ) |
271 		mdec_clamp_g5( p_n_y[ 1 ] + n_g ) |
272 		mdec_clamp_b5( p_n_y[ 1 ] + n_b );
273 }
274 
mdec_yuv2_to_rgb15(void)275 void psxmdec_device::mdec_yuv2_to_rgb15( void )
276 {
277 	int32_t n_r;
278 	int32_t n_g;
279 	int32_t n_b;
280 	int32_t n_cb;
281 	int32_t n_cr;
282 	int32_t *p_n_cb;
283 	int32_t *p_n_cr;
284 	int32_t *p_n_y;
285 	uint32_t n_x;
286 	uint32_t n_y;
287 	uint32_t n_z;
288 	uint16_t n_stp;
289 	int n_address = 0;
290 
291 	if( ( n_0_command & ( 1L << 25 ) ) != 0 )
292 	{
293 		n_stp = 0x8000;
294 	}
295 	else
296 	{
297 		n_stp = 0x0000;
298 	}
299 
300 	p_n_cr = &m_p_n_unpacked[ 0 ];
301 	p_n_cb = &m_p_n_unpacked[ DCTSIZE2 ];
302 	p_n_y = &m_p_n_unpacked[ DCTSIZE2 * 2 ];
303 
304 	for( n_z = 0; n_z < 2; n_z++ )
305 	{
306 		for( n_y = 0; n_y < 4; n_y++ )
307 		{
308 			for( n_x = 0; n_x < 4; n_x++ )
309 			{
310 				n_cr = *( p_n_cr );
311 				n_cb = *( p_n_cb );
312 				n_r = mdec_cr_to_r( n_cr );
313 				n_g = mdec_cr_to_g( n_cr ) + mdec_cb_to_g( n_cb );
314 				n_b = mdec_cb_to_b( n_cb );
315 
316 				mdec_makergb15( ( n_address +  0 ), n_r, n_g, n_b, p_n_y, n_stp );
317 				mdec_makergb15( ( n_address + 32 ), n_r, n_g, n_b, p_n_y + 8, n_stp );
318 
319 				n_cr = *( p_n_cr + 4 );
320 				n_cb = *( p_n_cb + 4 );
321 				n_r = mdec_cr_to_r( n_cr );
322 				n_g = mdec_cr_to_g( n_cr ) + mdec_cb_to_g( n_cb );
323 				n_b = mdec_cb_to_b( n_cb );
324 
325 				mdec_makergb15( ( n_address + 16 ), n_r, n_g, n_b, p_n_y + DCTSIZE2, n_stp );
326 				mdec_makergb15( ( n_address + 48 ), n_r, n_g, n_b, p_n_y + DCTSIZE2 + 8, n_stp );
327 
328 				p_n_cr++;
329 				p_n_cb++;
330 				p_n_y += 2;
331 				n_address += 4;
332 			}
333 			p_n_cr += 4;
334 			p_n_cb += 4;
335 			p_n_y += 8;
336 			n_address += 48;
337 		}
338 		p_n_y += DCTSIZE2;
339 	}
340 	n_decoded = ( 16 * 16 ) / 2;
341 }
342 
mdec_clamp8(int32_t n_r) const343 uint16_t psxmdec_device::mdec_clamp8( int32_t n_r ) const
344 {
345 	return p_n_clamp8[ n_r + 128 + 256 ];
346 }
347 
mdec_makergb24(uint32_t n_address,int32_t n_r,int32_t n_g,int32_t n_b,int32_t * p_n_y,uint32_t n_stp)348 void psxmdec_device::mdec_makergb24( uint32_t n_address, int32_t n_r, int32_t n_g, int32_t n_b, int32_t *p_n_y, uint32_t n_stp )
349 {
350 	p_n_output[ WORD_XOR_LE( n_address + 0 ) / 2 ] = ( mdec_clamp8( p_n_y[ 0 ] + n_g ) << 8 ) | mdec_clamp8( p_n_y[ 0 ] + n_r );
351 	p_n_output[ WORD_XOR_LE( n_address + 2 ) / 2 ] = ( mdec_clamp8( p_n_y[ 1 ] + n_r ) << 8 ) | mdec_clamp8( p_n_y[ 0 ] + n_b );
352 	p_n_output[ WORD_XOR_LE( n_address + 4 ) / 2 ] = ( mdec_clamp8( p_n_y[ 1 ] + n_b ) << 8 ) | mdec_clamp8( p_n_y[ 1 ] + n_g );
353 }
354 
mdec_yuv2_to_rgb24(void)355 void psxmdec_device::mdec_yuv2_to_rgb24( void )
356 {
357 	int32_t n_r;
358 	int32_t n_g;
359 	int32_t n_b;
360 	int32_t n_cb;
361 	int32_t n_cr;
362 	int32_t *p_n_cb;
363 	int32_t *p_n_cr;
364 	int32_t *p_n_y;
365 	uint32_t n_x;
366 	uint32_t n_y;
367 	uint32_t n_z;
368 	uint32_t n_stp;
369 	int n_address = 0;
370 
371 	if( ( n_0_command & ( 1L << 25 ) ) != 0 )
372 	{
373 		n_stp = 0x80008000;
374 	}
375 	else
376 	{
377 		n_stp = 0x00000000;
378 	}
379 
380 	p_n_cr = &m_p_n_unpacked[ 0 ];
381 	p_n_cb = &m_p_n_unpacked[ DCTSIZE2 ];
382 	p_n_y = &m_p_n_unpacked[ DCTSIZE2 * 2 ];
383 
384 	for( n_z = 0; n_z < 2; n_z++ )
385 	{
386 		for( n_y = 0; n_y < 4; n_y++ )
387 		{
388 			for( n_x = 0; n_x < 4; n_x++ )
389 			{
390 				n_cr = *( p_n_cr );
391 				n_cb = *( p_n_cb );
392 				n_r = mdec_cr_to_r( n_cr );
393 				n_g = mdec_cr_to_g( n_cr ) + mdec_cb_to_g( n_cb );
394 				n_b = mdec_cb_to_b( n_cb );
395 
396 				mdec_makergb24( ( n_address +  0 ), n_r, n_g, n_b, p_n_y, n_stp );
397 				mdec_makergb24( ( n_address + 48 ), n_r, n_g, n_b, p_n_y + 8, n_stp );
398 
399 				n_cr = *( p_n_cr + 4 );
400 				n_cb = *( p_n_cb + 4 );
401 				n_r = mdec_cr_to_r( n_cr );
402 				n_g = mdec_cr_to_g( n_cr ) + mdec_cb_to_g( n_cb );
403 				n_b = mdec_cb_to_b( n_cb );
404 
405 				mdec_makergb24( ( n_address + 24 ), n_r, n_g, n_b, p_n_y + DCTSIZE2, n_stp );
406 				mdec_makergb24( ( n_address + 72 ), n_r, n_g, n_b, p_n_y + DCTSIZE2 + 8, n_stp );
407 
408 				p_n_cr++;
409 				p_n_cb++;
410 				p_n_y += 2;
411 				n_address += 6;
412 			}
413 			p_n_cr += 4;
414 			p_n_cb += 4;
415 			p_n_y += 8;
416 			n_address += 72;
417 		}
418 		p_n_y += DCTSIZE2;
419 	}
420 	n_decoded = ( 24 * 16 ) / 2;
421 }
422 
dma_write(uint32_t * p_n_psxram,uint32_t n_address,int32_t n_size)423 void psxmdec_device::dma_write( uint32_t *p_n_psxram, uint32_t n_address, int32_t n_size )
424 {
425 	int n_index;
426 
427 	verboselog( *this, 2, "mdec0_write( %08x, %08x )\n", n_address, n_size );
428 
429 	switch( n_0_command >> 28 )
430 	{
431 	case 0x3:
432 		verboselog( *this, 1, "mdec decode %08x %08x %08x\n", n_0_command, n_address, n_size );
433 		n_0_address = n_address;
434 		n_0_size = n_size * 4;
435 		n_1_status |= ( 1L << 29 );
436 		break;
437 	case 0x4:
438 		verboselog( *this, 1, "mdec quantize table %08x %08x %08x\n", n_0_command, n_address, n_size );
439 		n_index = 0;
440 		while( n_size > 0 )
441 		{
442 			if( n_index < DCTSIZE2 )
443 			{
444 				p_n_quantize_y[ n_index + 0 ] = ( p_n_psxram[ n_address / 4 ] >> 0 ) & 0xff;
445 				p_n_quantize_y[ n_index + 1 ] = ( p_n_psxram[ n_address / 4 ] >> 8 ) & 0xff;
446 				p_n_quantize_y[ n_index + 2 ] = ( p_n_psxram[ n_address / 4 ] >> 16 ) & 0xff;
447 				p_n_quantize_y[ n_index + 3 ] = ( p_n_psxram[ n_address / 4 ] >> 24 ) & 0xff;
448 			}
449 			else if( n_index < DCTSIZE2 * 2 )
450 			{
451 				p_n_quantize_uv[ n_index + 0 - DCTSIZE2 ] = ( p_n_psxram[ n_address / 4 ] >> 0 ) & 0xff;
452 				p_n_quantize_uv[ n_index + 1 - DCTSIZE2 ] = ( p_n_psxram[ n_address / 4 ] >> 8 ) & 0xff;
453 				p_n_quantize_uv[ n_index + 2 - DCTSIZE2 ] = ( p_n_psxram[ n_address / 4 ] >> 16 ) & 0xff;
454 				p_n_quantize_uv[ n_index + 3 - DCTSIZE2 ] = ( p_n_psxram[ n_address / 4 ] >> 24 ) & 0xff;
455 			}
456 			n_index += 4;
457 			n_address += 4;
458 			n_size--;
459 		}
460 		break;
461 	case 0x6:
462 		verboselog( *this, 1, "mdec cosine table %08x %08x %08x\n", n_0_command, n_address, n_size );
463 		n_index = 0;
464 		while( n_size > 0 )
465 		{
466 			p_n_cos[ n_index + 0 ] = (int16_t)( ( p_n_psxram[ n_address / 4 ] >> 0 ) & 0xffff );
467 			p_n_cos[ n_index + 1 ] = (int16_t)( ( p_n_psxram[ n_address / 4 ] >> 16 ) & 0xffff );
468 			n_index += 2;
469 			n_address += 4;
470 			n_size--;
471 		}
472 		mdec_cos_precalc();
473 		break;
474 	default:
475 		verboselog( *this, 0, "mdec unknown command %08x %08x %08x\n", n_0_command, n_address, n_size );
476 		break;
477 	}
478 }
479 
dma_read(uint32_t * p_n_psxram,uint32_t n_address,int32_t n_size)480 void psxmdec_device::dma_read( uint32_t *p_n_psxram, uint32_t n_address, int32_t n_size )
481 {
482 	uint32_t n_this;
483 	uint32_t n_nextaddress;
484 
485 	verboselog( *this, 2, "mdec1_read( %08x, %08x )\n", n_address, n_size );
486 	if( ( n_0_command & ( 1L << 29 ) ) != 0 && n_0_size != 0 )
487 	{
488 		while( n_size > 0 )
489 		{
490 			if( n_decoded == 0 )
491 			{
492 				if( (int)n_0_size <= 0 )
493 				{
494 					osd_printf_debug( "ran out of data %08x\n", n_size );
495 					n_0_size = 0;
496 					break;
497 				}
498 
499 				n_nextaddress = mdec_unpack( p_n_psxram, n_0_address );
500 				n_0_size -= n_nextaddress - n_0_address;
501 				n_0_address = n_nextaddress;
502 
503 				if( ( n_0_command & ( 1L << 27 ) ) != 0 )
504 				{
505 					mdec_yuv2_to_rgb15();
506 				}
507 				else
508 				{
509 					mdec_yuv2_to_rgb24();
510 				}
511 				n_offset = 0;
512 				while((psxreadword( p_n_psxram, n_0_address ) == 0xfe00) && n_0_size)
513 				{
514 					n_0_address += 2;  // eat up 0xfe00
515 					n_0_size -= 2;
516 				}
517 			}
518 
519 			n_this = n_decoded;
520 			if( n_this > n_size )
521 			{
522 				n_this = n_size;
523 			}
524 			n_decoded -= n_this;
525 
526 			memcpy( (uint8_t *)p_n_psxram + n_address, (uint8_t *)p_n_output + n_offset, n_this * 4 );
527 			n_offset += n_this * 4;
528 			n_address += n_this * 4;
529 			n_size -= n_this;
530 		}
531 
532 		if( (int)n_0_size < 0 )
533 		{
534 			osd_printf_debug( "ran out of data %d\n", n_0_size );
535 		}
536 	}
537 	else
538 	{
539 		osd_printf_debug( "mdec1_read no conversion :%08x:%08x:\n", n_0_command, n_0_size );
540 	}
541 	if((int)n_0_size <= 0)
542 		n_1_status &= ~( 1L << 29 );
543 }
544 
write(offs_t offset,uint32_t data)545 void psxmdec_device::write(offs_t offset, uint32_t data)
546 {
547 	switch( offset )
548 	{
549 	case 0:
550 		verboselog( *this, 2, "mdec 0 command %08x\n", data );
551 		n_0_command = data;
552 		break;
553 	case 1:
554 		verboselog( *this, 2, "mdec 1 command %08x\n", data );
555 		n_1_command = data;
556 		break;
557 	}
558 }
559 
read(offs_t offset)560 uint32_t psxmdec_device::read(offs_t offset)
561 {
562 	switch( offset )
563 	{
564 	case 0:
565 		verboselog( *this, 2, "mdec 0 status %08x\n", 0 );
566 		return 0;
567 	case 1:
568 		verboselog( *this, 2, "mdec 1 status %08x\n", n_1_status );
569 		return n_1_status;
570 	}
571 	return 0;
572 }
573