MercuryUnit.java
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13: package xeij;
14:
15: import java.util.*;
16:
17: public class MercuryUnit {
18:
19: public static final boolean MU4_ON = true;
20: public static boolean mu4OnRequest;
21: public static boolean mu4On;
22: public static boolean mu4OnPositive;
23: public static boolean mu4OnNegative;
24: public static boolean mu4OutputEnable;
25:
26: public static final boolean MU4_DEBUG = false;
27:
28:
29:
30: public static void mu4Init () {
31:
32: mu4OnRequest = Settings.sgsGetOnOff ("mercury");
33: mu4OutputEnable = Settings.sgsGetOnOff ("mercuryoe");
34:
35: mu4Hermite640 = new Hermite (640, 2500);
36: mu4Hermite882 = new Hermite (882, 2500);
37: mu4Hermite960 = new Hermite (960, 2500);
38: mu4Hermite1280 = new Hermite (1280, 2500);
39: mu4Hermite1764 = new Hermite (1764, 2500);
40: mu4Hermite1920 = new Hermite (1920, 2500);
41:
42: for (int i = 0; i <= MU4_ATTACK_FRAMES; i++) {
43: mu4AttackArray[i] =
44: (float) ((1.0 + Math.sin (Math.PI *
45: (double) (i - MU4_ATTACK_FRAMES / 2) /
46: (double) MU4_ATTACK_FRAMES)) / 2.0);
47: }
48: if (MU4_DEBUG) {
49: for (int i = 0; i <= MU4_ATTACK_FRAMES; i++) {
50: System.out.printf ("mu4AttackArray[%d]=%.6f\n", i, mu4AttackArray[i]);
51: }
52: }
53: }
54:
55:
56:
57: public static void mu4Tini () {
58:
59: Settings.sgsPutOnOff ("mercury", mu4OnRequest);
60: Settings.sgsPutOnOff ("mercuryoe", mu4OutputEnable);
61: }
62:
63:
64:
65: public static void mu4Reset () {
66: mu4On = mu4OnRequest;
67: mu4OnPositive = mu4On && !XEiJ.specifiedModel.isShodai ();
68: mu4OnNegative = mu4On && XEiJ.specifiedModel.isShodai ();
69:
70:
71: mu4PortUpper = (MU4_U_RESERVED |
72: MU4_U12_TERR |
73:
74:
75: MU4_U6_INSEL);
76: mu4PortCommand = 0;
77: mu4PortStatus = (MU4_S3_N32K |
78: MU4_S2_N44K |
79: MU4_S1_N48K);
80:
81: mu4EnablePclReq = true;
82: mu4RiseExpcl ();
83: mu4RiseExreq ();
84: mu4EnablePclReq = false;
85: mu4SequenceArray = null;
86: Arrays.fill (mu4Buffer, 0);
87: TickerQueue.tkqRemove (mu4SequenceTicker);
88: mu4PortCommand = -1;
89: mu4SetCommand (MU4_U_RESERVED |
90: MU4_U12_TERR |
91: MU4_U11_EXPCL |
92: MU4_U10_EXREQ |
93: MU4_U6_INSEL);
94: }
95:
96:
97:
98: public static int mu4ReadByte (int a) {
99: int a70 = a & 0x70;
100: int d = 0;
101: if (a70 == 0x10) {
102: d = (a & 1) == 0 ? mu4PortUpper >> 8 : (mu4PortUpper | mu4PortCommand) & 0xff;
103: } else if (a70 == 0x20) {
104: d = (a & 1) == 0 ? mu4PortUpper >> 8 : (mu4PortUpper | mu4PortStatus) & 0xff;
105: }
106: if (MU4_DEBUG) {
107: System.out.printf ("%08x mu4ReadByte(0x%08x)=0x%02x\n", XEiJ.regPC0, a, d);
108: }
109: return d;
110: }
111:
112:
113:
114: public static int mu4ReadWord (int a) {
115: int a70 = a & 0x70;
116: int d = 0;
117: if (a70 == 0x10) {
118: d = mu4PortUpper | mu4PortCommand;
119: } else if (a70 == 0x20) {
120: d = mu4PortUpper | mu4PortStatus;
121: }
122: if (MU4_DEBUG) {
123: System.out.printf ("%08x mu4ReadWord(0x%08x)=0x%04x\n", XEiJ.regPC0, a, d);
124: }
125: return d;
126: }
127:
128:
129:
130: public static void mu4WriteByte (int a, int d) {
131: d &= 0xff;
132: if (MU4_DEBUG) {
133: System.out.printf ("%08x mu4WriteByte(0x%08x,0x%02x)\n", XEiJ.regPC0, a, d);
134: }
135: int a70 = a & 0x70;
136: if (a70 == 0x10) {
137: int t = mu4PortUpper | mu4PortCommand;
138: if ((a & 1) == 0) {
139: mu4SetCommand ((d << 8) | (t & 0xff));
140: } else {
141: mu4SetCommand ((t & 0xff00) | d);
142: }
143: }
144: }
145:
146:
147:
148: public static void mu4WriteWord (int a, int d) {
149: d &= 0xffff;
150: if (MU4_DEBUG) {
151: System.out.printf ("%08x mu4WriteWord(0x%08x,0x%04x)\n", XEiJ.regPC0, a, d);
152: }
153: int a70 = a & 0x70;
154: if (a70 == 0x00 &&
155: mu4Mode == MU4_MODE_OUT &&
156: mu4OutputEnable &&
157: 0 <= mu4WritePointer) {
158: if ((mu4DataChannels == 1 ||
159: (mu4WritePointer & 1) == 0) &&
160: (mu4PortCommand & MU4_C2_LG) != 0) {
161: mu4NaiKamoLeft = false;
162: if (mu4NaiDesuLeft) {
163: mu4NaiDesuLeft = false;
164: mu4AttackIndexLeft = 1;
165: }
166: mu4DataArray[mu4WritePointer] = Math.round (mu4AttackArray[mu4AttackIndexLeft] * (short) d);
167: mu4AttackIndexLeft = Math.min (MU4_ATTACK_FRAMES, mu4AttackIndexLeft + 1);
168: }
169: if ((mu4DataChannels == 1 ||
170: (mu4WritePointer & 1) != 0) &&
171: (mu4PortCommand & MU4_C3_RG) != 0) {
172: mu4NaiKamoRight = false;
173: if (mu4NaiDesuRight) {
174: mu4NaiDesuRight = false;
175: mu4AttackIndexRight = 1;
176: }
177: mu4DataArray[mu4WritePointer + (2 - mu4DataChannels)] = Math.round (mu4AttackArray[mu4AttackIndexRight] * (short) d);
178: mu4AttackIndexRight = Math.min (MU4_ATTACK_FRAMES, mu4AttackIndexRight + 1);
179: }
180: if (false) {
181: mu4WritePointer = -1;
182: }
183: mu4DataWritten = true;
184: } else if (a70 == 0x10) {
185: mu4SetCommand (d);
186: }
187: }
188:
189:
190:
191:
192:
193:
194: public static void mu4HsyncStart (long hsyncTime) {
195: if (mu4Mode != MU4_MODE_M256) {
196: return;
197: }
198: mu4SequenceArray = (mu4DataChannels == 1 ?
199: mu4DataRate < 32000 ? MU4_M256_LOW_MONO : MU4_M256_HIGH_MONO
200: :
201: mu4DataRate < 32000 ? MU4_M256_LOW_STEREO : MU4_M256_HIGH_STEREO);
202: if (mu4SequenceArray == MU4_M256_LOW_STEREO &&
203: (mu4PortUpper & MU4_U54_CLKSEL) == MU4_U54_32K) {
204: mu4SequenceArray = MU4_M256_LOW_MONO;
205: }
206:
207:
208:
209: mu4BlockTime = hsyncTime;
210:
211: mu4FrameNumber = 0;
212:
213: mu4SequenceIndex = 0;
214:
215: TickerQueue.tkqAdd (
216: mu4SequenceTicker,
217: mu4SequenceTime = mu4BlockTime +
218: mu4SequenceArray[mu4SequenceIndex++] *
219: XEiJ.TMR_FREQ / mu4DataFrequency);
220: }
221:
222:
223:
224:
225:
226: public static void mu4ExackStart () {
227: if ((mu4PortUpper & MU4_U8_ACKIG) != 0) {
228: mu4RiseExreq ();
229: }
230: }
231:
232:
233:
234:
235: public static final int[] mu4Buffer = new int[2 * 2500];
236:
237:
238:
239: public static void mu4FillBuffer () {
240: if (mu4Mode != MU4_MODE_OUT) {
241: return;
242: }
243: if (MU4_DEBUG) {
244: System.out.printf ("%08x mu4FillBuffer()\n", XEiJ.regPC0);
245: }
246:
247: mu4FrameNumber -= mu4DataFrames;
248:
249: mu4BlockTime += MU4_BLOCK_TIME;
250:
251: TickerQueue.tkqAdd (
252: mu4SequenceTicker,
253: mu4SequenceTime = mu4BlockTime +
254: (mu4DataCycles * mu4FrameNumber + mu4SequenceArray[mu4SequenceIndex - 1]) *
255: XEiJ.TMR_FREQ / mu4DataFrequency);
256:
257: if (!mu4DataWritten) {
258: Arrays.fill (mu4Buffer, 0);
259: return;
260: }
261: mu4DataWritten = false;
262:
263: switch (mu4DataFrames) {
264: case 640:
265: mu4Hermite640.convert ();
266: break;
267: case 882:
268: mu4Hermite882.convert ();
269: break;
270: case 960:
271: mu4Hermite960.convert ();
272: break;
273: case 1280:
274: mu4Hermite1280.convert ();
275: break;
276: case 1764:
277: mu4Hermite1764.convert ();
278: break;
279: case 1920:
280: mu4Hermite1920.convert ();
281: break;
282: }
283:
284: for (int i = 0; i < 2 * 4; i++) {
285: mu4DataArray[i] = mu4DataArray[2 * mu4DataFrames + i];
286: mu4DataWritten = mu4DataWritten || mu4DataArray[i] != 0;
287: }
288: Arrays.fill (mu4DataArray, 2 * 4, 2 * (mu4DataFrames + 4), 0);
289: }
290:
291:
292:
293:
294:
295: static final int MU4_U_RESERVED = 7 << 13;
296: static final int MU4_U12_TERR = 1 << 12;
297: static final int MU4_U11_EXPCL = 1 << 11;
298: static final int MU4_U10_EXREQ = 1 << 10;
299: static final int MU4_U9_M256 = 1 << 9;
300: static final int MU4_U8_ACKIG = 1 << 8;
301: static final int MU4_U7_CLKRATE = 1 << 7;
302: static final int MU4_U6_INSEL = 1 << 6;
303: static final int MU4_U54_CLKSEL = 3 << 4;
304: static final int MU4_U54_32K = 1 << 4;
305: static final int MU4_U54_48K = 3 << 4;
306:
307: static final int MU4_C3_RG = 1 << 3;
308: static final int MU4_C2_LG = 1 << 2;
309: static final int MU4_C1_STEREO = 1 << 1;
310: static final int MU4_C0_OUT = 1 << 0;
311:
312: static final int MU4_S3_N32K = 1 << 3;
313: static final int MU4_S2_N44K = 1 << 2;
314: static final int MU4_S1_N48K = 1 << 1;
315: static final int MU4_S0_ERR = 1 << 0;
316:
317: static int mu4PortUpper;
318: static int mu4PortCommand;
319: static int mu4PortStatus;
320:
321:
322: static final int MU4_MODE_M256 = 0;
323: static final int MU4_MODE_OUT = 1;
324: static final int MU4_MODE_IN = 2;
325: static int mu4Mode;
326:
327:
328: static boolean mu4EnablePclReq;
329:
330:
331: static int mu4DataFrequency;
332:
333:
334: static int mu4DataCycles;
335:
336:
337:
338: static int mu4DataRate;
339:
340:
341: static int mu4DataChannels;
342:
343:
344:
345: static final int MU4_BLOCK_RATE = 25;
346:
347:
348:
349: static int mu4DataFrames;
350:
351:
352:
353: static final int MU4_LINE_RATE = 62500;
354:
355:
356:
357: static final int MU4_LINE_CHANNELS = 2;
358:
359:
360:
361: static final int MU4_LINE_FRAMES = MU4_LINE_RATE / MU4_BLOCK_RATE;
362:
363:
364:
365: static final int MU4_LINE_ELEMENTS = MU4_LINE_CHANNELS * MU4_LINE_FRAMES;
366:
367:
368:
369:
370:
371:
372: static final int MU4_FALL_EXPCL = 0;
373: static final int MU4_RISE_EXPCL = 1;
374: static final int MU4_FALL_EXREQ = 2;
375: static final int MU4_RISE_EXREQ = 3;
376:
377:
378:
379:
380: static final int[] MU4_M256_LOW_MONO = {
381: 2, MU4_FALL_EXPCL,
382: 20, MU4_FALL_EXREQ,
383: 283, MU4_RISE_EXREQ,
384: 385, MU4_RISE_EXPCL,
385: };
386:
387:
388: static final int[] MU4_M256_LOW_STEREO = {
389: 2, MU4_FALL_EXPCL,
390: 283, MU4_RISE_EXREQ,
391: 385, MU4_RISE_EXPCL,
392: 404, MU4_FALL_EXREQ,
393: };
394:
395:
396:
397: static final int[] MU4_M256_HIGH_MONO = {
398: 2, MU4_FALL_EXPCL,
399: 10, MU4_FALL_EXREQ,
400: 142, MU4_RISE_EXREQ,
401: 193, MU4_RISE_EXPCL,
402: };
403:
404:
405:
406: static final int[] MU4_M256_HIGH_STEREO = {
407: 2, MU4_FALL_EXPCL,
408: 10, MU4_FALL_EXREQ,
409: 142, MU4_RISE_EXREQ,
410: 193, MU4_RISE_EXPCL,
411: 202, MU4_FALL_EXREQ,
412: 334, MU4_RISE_EXREQ,
413: };
414:
415:
416:
417: static final int[] MU4_OUT_LOW_MONO = {
418: 0, MU4_FALL_EXPCL,
419: 379, MU4_FALL_EXREQ,
420: 384, MU4_RISE_EXPCL,
421: 667, MU4_RISE_EXREQ,
422: };
423:
424:
425:
426: static final int[] MU4_OUT_LOW_STEREO = {
427: 0, MU4_FALL_EXPCL,
428: 283, MU4_RISE_EXREQ,
429: 379, MU4_FALL_EXREQ,
430: 384, MU4_RISE_EXPCL,
431: 667, MU4_RISE_EXREQ,
432: 763, MU4_FALL_EXREQ,
433: };
434:
435:
436:
437: static final int[] MU4_OUT_HIGH_MONO = {
438: 0, MU4_FALL_EXPCL,
439: 190, MU4_FALL_EXREQ,
440: 192, MU4_RISE_EXPCL,
441: 334, MU4_RISE_EXREQ,
442: };
443:
444:
445:
446: static final int[] MU4_OUT_HIGH_STEREO = {
447: 0, MU4_FALL_EXPCL,
448: 142, MU4_RISE_EXREQ,
449: 190, MU4_FALL_EXREQ,
450: 192, MU4_RISE_EXPCL,
451: 334, MU4_RISE_EXREQ,
452: 382, MU4_FALL_EXREQ,
453: };
454:
455:
456: static int[] mu4SequenceArray;
457:
458:
459:
460: static final long MU4_BLOCK_TIME = XEiJ.TMR_FREQ / MU4_BLOCK_RATE;
461:
462:
463:
464:
465: static long mu4BlockTime;
466:
467:
468:
469:
470: static int mu4FrameNumber;
471:
472:
473: static int mu4SequenceIndex;
474:
475:
476:
477:
478: static int mu4LRCounter;
479:
480:
481:
482:
483: static int mu4WritePointer;
484:
485:
486:
487:
488: static final int[] mu4DataArray = new int[2 * (1920 + 4)];
489:
490:
491: static boolean mu4DataWritten;
492:
493:
494: static long mu4SequenceTime;
495:
496:
497:
498: static void mu4DumpVars () {
499: System.out.printf ("mu4Mode=%d\n", mu4Mode);
500: System.out.printf ("mu4EnablePclReq=%b\n", mu4EnablePclReq);
501: System.out.printf ("mu4DataFrequency=%d\n", mu4DataFrequency);
502: System.out.printf ("mu4DataCycles=%d\n", mu4DataCycles);
503: System.out.printf ("mu4DataRate=%d\n", mu4DataRate);
504: System.out.printf ("mu4DataChannels=%d\n", mu4DataChannels);
505: System.out.printf ("mu4DataFrames=%d\n", mu4DataFrames);
506: System.out.printf ("mu4BlockTime=%d\n", mu4BlockTime);
507: System.out.printf ("mu4FrameNumber=%d\n", mu4FrameNumber);
508: System.out.printf ("mu4SequenceIndex=%d\n", mu4SequenceIndex);
509: System.out.printf ("mu4LRCounter=%d\n", mu4LRCounter);
510: System.out.printf ("mu4WritePointer=%d\n", mu4WritePointer);
511: System.out.printf ("mu4DataWritten=%b\n", mu4DataWritten);
512: }
513:
514:
515:
516: static void mu4SetCommand (int d) {
517: if (MU4_DEBUG) {
518: System.out.printf ("%08x mu4SetCommand(0x%04x)\n", XEiJ.regPC0, d);
519: }
520: int prevMode = mu4Mode;
521: int prevDataRate = mu4DataRate;
522: int prevDataChannels = mu4DataChannels;
523: int prevUpper = mu4PortUpper;
524: int prevCommand = mu4PortCommand;
525: mu4PortUpper = ((mu4PortUpper & (MU4_U_RESERVED |
526: MU4_U12_TERR |
527: MU4_U11_EXPCL |
528: MU4_U10_EXREQ)) |
529: (d & (MU4_U9_M256 |
530: MU4_U8_ACKIG |
531: MU4_U7_CLKRATE |
532: MU4_U6_INSEL |
533: MU4_U54_CLKSEL)));
534: mu4PortCommand = d & (MU4_C3_RG |
535: MU4_C2_LG |
536: MU4_C1_STEREO |
537: MU4_C0_OUT);
538:
539:
540: mu4EnablePclReq = (mu4PortUpper & (MU4_U9_M256 | MU4_U8_ACKIG)) != 0;
541:
542: if ((((mu4PortUpper | mu4PortCommand) ^ (prevUpper | prevCommand)) & 0xff) == 0) {
543: return;
544: }
545:
546: mu4Mode = ((mu4PortUpper & MU4_U9_M256) == 0 ? MU4_MODE_M256 :
547: (mu4PortCommand & MU4_C0_OUT) != 0 ? MU4_MODE_OUT :
548: MU4_MODE_IN);
549:
550: mu4DataFrequency = ((mu4PortUpper & MU4_U54_CLKSEL) == MU4_U54_32K ? 12288000 :
551: (mu4PortUpper & MU4_U54_CLKSEL) != MU4_U54_48K ? 16934400 :
552: 18432000);
553:
554: mu4DataCycles = (mu4PortUpper & MU4_U7_CLKRATE) == 0 ? 768 : 384;
555:
556: mu4DataRate = mu4DataFrequency / mu4DataCycles;
557:
558: mu4DataChannels = (mu4PortCommand & MU4_C1_STEREO) == 0 ? 1 : 2;
559:
560: if (mu4Mode != prevMode ||
561: mu4DataRate != prevDataRate ||
562: mu4DataChannels != prevDataChannels) {
563: if (mu4Mode == MU4_MODE_M256) {
564:
565: mu4SequenceArray = null;
566: } else if (mu4Mode == MU4_MODE_OUT) {
567:
568: mu4DataFrames = mu4DataRate / MU4_BLOCK_RATE;
569:
570: mu4SequenceArray = (mu4DataChannels == 1 ?
571: mu4DataRate < 32000 ? MU4_OUT_LOW_MONO : MU4_OUT_HIGH_MONO
572: :
573: mu4DataRate < 32000 ? MU4_OUT_LOW_STEREO : MU4_OUT_HIGH_STEREO);
574:
575: mu4BlockTime = SoundSource.sndBlockClock - MU4_BLOCK_TIME;
576:
577:
578: mu4FrameNumber =
579: Math.max (0,
580: Math.min (mu4DataFrames,
581: (int) (((XEiJ.mpuClockTime - mu4BlockTime) * mu4DataFrames +
582: (MU4_BLOCK_TIME - 1)) / MU4_BLOCK_TIME)));
583:
584: mu4SequenceIndex = 0;
585:
586: mu4LRCounter = 0;
587:
588: mu4WritePointer = -1;
589: if (mu4DataRate != prevDataRate ||
590: mu4DataChannels != prevDataChannels) {
591:
592: Arrays.fill (mu4DataArray, 0, 2 * (mu4DataFrames + 4), 0);
593: }
594:
595: mu4DataWritten = false;
596: if (MU4_DEBUG) {
597: mu4DumpVars ();
598: }
599:
600: mu4AttackIndexLeft = 1;
601: mu4AttackIndexRight = 1;
602: mu4NaiKamoLeft = true;
603: mu4NaiKamoRight = true;
604: mu4NaiDesuLeft = true;
605: mu4NaiDesuRight = true;
606:
607: TickerQueue.tkqAdd (
608: mu4SequenceTicker,
609: mu4SequenceTime = mu4BlockTime +
610: (mu4DataCycles * mu4FrameNumber + mu4SequenceArray[mu4SequenceIndex++]) *
611: XEiJ.TMR_FREQ / mu4DataFrequency);
612: } else {
613:
614: mu4SequenceArray = null;
615: }
616: }
617: }
618:
619:
620:
621: static final TickerQueue.Ticker mu4SequenceTicker = new TickerQueue.Ticker () {
622: @Override protected void tick () {
623: if (mu4SequenceArray == null) {
624: return;
625: }
626: switch (mu4SequenceArray[mu4SequenceIndex++]) {
627: case MU4_FALL_EXPCL:
628: mu4FallExpcl ();
629: break;
630: case MU4_RISE_EXPCL:
631: mu4RiseExpcl ();
632: break;
633: case MU4_FALL_EXREQ:
634: if (mu4Mode == MU4_MODE_OUT) {
635:
636: mu4WritePointer = 2 * (mu4FrameNumber + 3) + mu4LRCounter;
637:
638: mu4LRCounter ^= 1;
639:
640: mu4DataArray[mu4WritePointer] = (int) (mu4DataArray[mu4WritePointer - 2] * MU4_DECAY_RATIO);
641: if (mu4DataChannels == 1 ||
642: (mu4WritePointer & 1) == 0) {
643: mu4NaiDesuLeft = mu4NaiDesuLeft || mu4NaiKamoLeft;
644: mu4NaiKamoLeft = true;
645: }
646: if (mu4DataChannels == 1 ||
647: (mu4WritePointer & 1) != 0) {
648: mu4NaiDesuRight = mu4NaiDesuRight || mu4NaiKamoRight;
649: mu4NaiKamoRight = true;
650: }
651: }
652: mu4FallExreq (mu4SequenceTime);
653: break;
654: case MU4_RISE_EXREQ:
655: mu4RiseExreq ();
656: break;
657: }
658: if (mu4SequenceArray.length <= mu4SequenceIndex) {
659: if (mu4Mode == MU4_MODE_M256) {
660: mu4SequenceArray = null;
661: return;
662: }
663:
664: mu4FrameNumber++;
665: mu4SequenceIndex = 0;
666: mu4LRCounter = 0;
667: }
668:
669: TickerQueue.tkqAdd (
670: mu4SequenceTicker,
671: mu4SequenceTime = mu4BlockTime +
672: (mu4DataCycles * mu4FrameNumber + mu4SequenceArray[mu4SequenceIndex++]) *
673: XEiJ.TMR_FREQ / mu4DataFrequency);
674: }
675: };
676:
677:
678:
679: static void mu4FallExpcl () {
680: if ((mu4PortUpper & MU4_U11_EXPCL) != 0) {
681: mu4PortUpper &= ~MU4_U11_EXPCL;
682: if (mu4EnablePclReq) {
683: HD63450.dmaFallPCL (2);
684: }
685: }
686: }
687:
688:
689:
690: static void mu4RiseExpcl () {
691: if ((mu4PortUpper & MU4_U11_EXPCL) == 0) {
692: mu4PortUpper |= MU4_U11_EXPCL;
693: if (mu4EnablePclReq) {
694: HD63450.dmaRisePCL (2);
695: }
696: }
697: }
698:
699:
700:
701: static void mu4FallExreq (long time) {
702: if ((mu4PortUpper & MU4_U10_EXREQ) != 0) {
703: mu4PortUpper &= ~MU4_U10_EXREQ;
704: if (mu4EnablePclReq) {
705: HD63450.dmaFallREQ (2, time);
706: }
707: }
708: }
709:
710:
711:
712: static void mu4RiseExreq () {
713: if ((mu4PortUpper & MU4_U10_EXREQ) == 0) {
714: mu4PortUpper |= MU4_U10_EXREQ;
715: if (mu4EnablePclReq) {
716: HD63450.dmaRiseREQ (2);
717: }
718: }
719: }
720:
721:
722:
723:
724: static Hermite mu4Hermite640;
725: static Hermite mu4Hermite882;
726: static Hermite mu4Hermite960;
727: static Hermite mu4Hermite1280;
728: static Hermite mu4Hermite1764;
729: static Hermite mu4Hermite1920;
730:
731:
732:
733: static class Hermite {
734: int inputFrames, outputFrames;
735: int inputFactor, outputFactor;
736: float[] coeffArray;
737: int[] indexArray;
738: Hermite (int inputFrames, int outputFrames) {
739: this.inputFrames = inputFrames;
740: this.outputFrames = outputFrames;
741: int g = gcd (inputFrames, outputFrames);
742: inputFactor = inputFrames / g;
743: outputFactor = outputFrames / g;
744: coeffArray = new float[4 * outputFactor];
745: indexArray = new int[outputFactor];
746: int inputIndex1 = 0;
747: int ratio1 = 0;
748: for (int outputIndex = 0; outputIndex < outputFactor; outputIndex++) {
749: int inputIndex0 = inputIndex1;
750: int ratio0 = ratio1;
751: ratio1 += inputFactor;
752: while (outputFactor <= ratio1) {
753: ratio1 -= outputFactor;
754: inputIndex1++;
755: }
756:
757:
758:
759:
760:
761:
762:
763:
764:
765:
766:
767:
768:
769:
770:
771:
772:
773:
774:
775:
776:
777:
778:
779:
780:
781:
782:
783:
784:
785:
786:
787:
788:
789: double x = (double) ratio0 / (double) outputFactor;
790: coeffArray[4 * outputIndex] = (float) (((-0.5 * x + 1.0) * x - 0.5) * x);
791: coeffArray[4 * outputIndex + 1] = (float) ((1.5 * x - 2.5) * x * x + 1.0);
792: coeffArray[4 * outputIndex + 2] = (float) (((-1.5 * x + 2.0) * x + 0.5) * x);
793: coeffArray[4 * outputIndex + 3] = (float) ((0.5 * x - 0.5) * x * x);
794: indexArray[outputIndex] = inputIndex0;
795: }
796: }
797: void convert () {
798: for (int inputIndex = 0, outputIndex = 0;
799: inputIndex < inputFrames;
800: inputIndex += inputFactor, outputIndex += outputFactor) {
801: for (int od = 0; od < outputFactor; od++) {
802: int ii = inputIndex + indexArray[od];
803: int oi = outputIndex + od;
804: float cm = coeffArray[4 * od];
805: float c0 = coeffArray[4 * od + 1];
806: float c1 = coeffArray[4 * od + 2];
807: float c2 = coeffArray[4 * od + 3];
808: mu4Buffer[2 * oi + 0] = Math.round (cm * mu4DataArray[2 * ii + 0] +
809: c0 * mu4DataArray[2 * ii + 2] +
810: c1 * mu4DataArray[2 * ii + 4] +
811: c2 * mu4DataArray[2 * ii + 6]);
812: mu4Buffer[2 * oi + 1] = Math.round (cm * mu4DataArray[2 * ii + 1] +
813: c0 * mu4DataArray[2 * ii + 3] +
814: c1 * mu4DataArray[2 * ii + 5] +
815: c2 * mu4DataArray[2 * ii + 7]);
816: }
817: }
818: }
819: int gcd (int x, int y) {
820: while (y != 0) {
821: int t = x % y;
822: x = y;
823: y = t;
824: }
825: return x;
826: }
827: }
828:
829:
830:
831:
832:
833:
834:
835:
836: static final float MU4_DECAY_RATIO = 0.97F;
837: static final int MU4_ATTACK_FRAMES = 300;
838: static final float mu4AttackArray[] = new float[MU4_ATTACK_FRAMES + 1];
839: static int mu4AttackIndexLeft;
840: static int mu4AttackIndexRight;
841: static boolean mu4NaiKamoLeft;
842: static boolean mu4NaiKamoRight;
843: static boolean mu4NaiDesuLeft;
844: static boolean mu4NaiDesuRight;
845:
846:
847:
848: }