DOSBox-X
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines
src/hardware/snd_pc98/sound/fmtimer.c
00001 #include    "np2glue.h"
00002 //#include      "compiler.h"
00003 //#include      "cpucore.h"
00004 //#include      "pccore.h"
00005 //#include      "iocore.h"
00006 #include        "sound.h"
00007 #include        "fmboard.h"
00008 
00009 
00010 /* DOSBox-X replacement for nevents here */
00011 static unsigned char nevent_is_set[2] = {0,0};
00012 
00013 enum {
00014     NEVENT_FMTIMERA=0,
00015     NEVENT_FMTIMERB
00016 };
00017 
00018 /* meaningless now */
00019 #define NEVENT_ABSOLUTE 0
00020 
00021 void pc98_fm_dosbox_fmtimer_setevent(unsigned int n,double dt);
00022 void pc98_fm_dosbox_fmtimer_clearevent(unsigned int n);
00023 
00024 static void nevent_set(unsigned int n,double dt) {
00025     pc98_fm_dosbox_fmtimer_setevent(n,dt);
00026     nevent_is_set[n] = 1;
00027 }
00028 
00029 static void nevent_reset(unsigned int n) {
00030     pc98_fm_dosbox_fmtimer_clearevent(n);
00031     nevent_is_set[n] = 0;
00032 }
00033 
00034 static void nevent_ack_event(unsigned int n) {
00035     nevent_is_set[n] = 0;
00036 }
00037 
00038 static unsigned int nevent_iswork(unsigned int n) {
00039     return nevent_is_set[n];
00040 }
00041 
00042 
00043 static const UINT8 irqtable[4] = {0x03, 0x0d, 0x0a, 0x0c};
00044 
00045 /* added for DOSBox-X */
00046 UINT8 fmtimer_index2irq(const UINT8 index) {
00047     return irqtable[index & 3];
00048 }
00049 
00050 UINT8 fmtimer_irq2index(const UINT8 irq) {
00051     unsigned int i;
00052 
00053     for (i=0;i < 4;i++) {
00054         if (irqtable[i] == irq)
00055             return i;
00056     }
00057 
00058     return 0x00;
00059 }
00060 /* end */
00061 
00062 static void set_fmtimeraevent(BOOL absolute) {
00063     (void)absolute;//UNUSED
00064 
00065         SINT32  l;
00066 
00067     nevent_ack_event(NEVENT_FMTIMERA);
00068 
00069         l = 18 * (1024 - fmtimer.timera);
00070 #if 0
00071         if (pccore.cpumode & CPUMODE_8MHZ) {            // 4MHz
00072                 l = (l * 1248 / 625) * pccore.multiple;
00073         }
00074         else {                                                                          // 5MHz
00075                 l = (l * 1536 / 625) * pccore.multiple;
00076         }
00077 //      TRACEOUT(("FMTIMER-A: %08x-%d", l, absolute));
00078         nevent_set(NEVENT_FMTIMERA, l, fmport_a, absolute);
00079 #else
00080     /* if you do the math here, it becomes:
00081      * l_us = l * core_clock_speed * multiple
00082      * which can be expressed in seconds like this:
00083      * dt = l / 1000000 */
00084     double dt_ms = (double)l / 1000;
00085     nevent_set(NEVENT_FMTIMERA,dt_ms);
00086 #endif
00087 }
00088 
00089 static void set_fmtimerbevent(BOOL absolute) {
00090     (void)absolute;//UNUSED
00091 
00092         SINT32  l;
00093 
00094     nevent_ack_event(NEVENT_FMTIMERB);
00095 
00096         l = 288 * (256 - fmtimer.timerb);
00097 #if 0
00098         if (pccore.cpumode & CPUMODE_8MHZ) {            // 4MHz
00099                 l = (l * 1248 / 625) * pccore.multiple;
00100         }
00101         else {                                                                          // 5MHz
00102                 l = (l * 1536 / 625) * pccore.multiple;
00103         }
00104 //      TRACEOUT(("FMTIMER-B: %08x-%d", l, absolute));
00105         nevent_set(NEVENT_FMTIMERB, l, fmport_b, absolute);
00106 #else
00107     double dt_ms = (double)l / 1000;
00108     nevent_set(NEVENT_FMTIMERB,dt_ms);
00109 #endif
00110 }
00111 
00112 
00113 void fmport_a(NEVENTITEM item) {
00114     (void)item;//UNUSED
00115 
00116         BOOL    intreq = FALSE;
00117 
00118 //      if (item->flag & NEVENT_SETEVENT) {
00119                 intreq = pcm86gen_intrq();
00120                 if (fmtimer.reg & 0x04) {
00121                         fmtimer.status |= 0x01;
00122                         intreq = TRUE;
00123                 }
00124                 if (intreq) {
00125                         pic_setirq(fmtimer.irq);
00126 //                      TRACEOUT(("fm int-A"));
00127                 }
00128 
00129                 set_fmtimeraevent(FALSE);
00130 //      }
00131 }
00132 
00133 void fmport_b(NEVENTITEM item) {
00134     (void)item;//UNUSED
00135         BOOL    intreq = FALSE;
00136 
00137 //      if (item->flag & NEVENT_SETEVENT) {
00138                 intreq = pcm86gen_intrq();
00139                 if (fmtimer.reg & 0x08) {
00140                         fmtimer.status |= 0x02;
00141                         intreq = TRUE;
00142                 }
00143                 if (intreq) {
00144                         pic_setirq(fmtimer.irq);
00145 //                      TRACEOUT(("fm int-B"));
00146                 }
00147 
00148                 set_fmtimerbevent(FALSE);
00149 //      }
00150 }
00151 
00152 void fmtimer_reset(UINT irq) {
00153 
00154         ZeroMemory(&fmtimer, sizeof(fmtimer));
00155         fmtimer.intr = irq & 0xc0;
00156         fmtimer.intdisabel = irq & 0x10;
00157         fmtimer.irq = irqtable[irq >> 6];
00158 //      pic_registext(fmtimer.irq);
00159 }
00160 
00161 void fmtimer_setreg(UINT reg, REG8 value) {
00162 
00163 //      TRACEOUT(("fm %x %x [%.4x:%.4x]", reg, value, CPU_CS, CPU_IP));
00164 
00165         switch(reg) {
00166                 case 0x24:
00167                         fmtimer.timera = (value << 2) + (fmtimer.timera & 3);
00168                         break;
00169 
00170                 case 0x25:
00171                         fmtimer.timera = (fmtimer.timera & 0x3fc) + (value & 3);
00172                         break;
00173 
00174                 case 0x26:
00175                         fmtimer.timerb = value;
00176                         break;
00177 
00178                 case 0x27:
00179                         fmtimer.reg = value;
00180                         fmtimer.status &= ~((value & 0x30) >> 4);
00181                         if (value & 0x01) {
00182                                 if (!nevent_iswork(NEVENT_FMTIMERA)) {
00183                                         set_fmtimeraevent(NEVENT_ABSOLUTE);
00184                                 }
00185                         }
00186                         else {
00187                                 nevent_reset(NEVENT_FMTIMERA);
00188                         }
00189 
00190                         if (value & 0x02) {
00191                                 if (!nevent_iswork(NEVENT_FMTIMERB)) {
00192                                         set_fmtimerbevent(NEVENT_ABSOLUTE);
00193                                 }
00194                         }
00195                         else {
00196                                 nevent_reset(NEVENT_FMTIMERB);
00197                         }
00198 
00199                         if (!(value & 0x03)) {
00200                                 pic_resetirq(fmtimer.irq);
00201                         }
00202                         break;
00203         }
00204 }
00205