static void gpsm_init(struct sndbrdData *brdData) { int mixing_levels[4] = {25,25,25,25}; int i; int s = 0; memset(&gps_locals, 0x00, sizeof(gps_locals)); gps_locals.brdData = *brdData; for (i = 0;i < 32000;i++) { s = (s ? 0 : 1); if (s) { sineWaveext[i] = rand(); } else sineWaveext[i] = 0-rand(); } pia_config(GPS_PIA0, PIA_STANDARD_ORDERING, &gps_pia[0]); pia_config(GPS_PIA1, PIA_STANDARD_ORDERING, &gps_pia[1]); gps_locals.channel = mixer_allocate_channels(4, mixing_levels); mixer_set_name (gps_locals.channel, "MC6840 #Q1"); // 6840 Output timer 1 (q1) is easy wave mixer_set_volume(gps_locals.channel,0); mixer_set_name (gps_locals.channel+1,"MC6840 #Q2"); // 6840 Output timer 2 (q2) is easy wave mixer_set_volume(gps_locals.channel+1,0); mixer_set_name (gps_locals.channel+2,"MC6840 #Q3"); // 6840 Output timer 3 (q3) is easy wave mixer_set_volume(gps_locals.channel+2,0); mixer_set_name (gps_locals.channel+3,"Noise"); // Noise generator mixer_set_volume(gps_locals.channel+3,0); mixer_play_sample_16(gps_locals.channel+3,sineWaveext, sizeof(sineWaveext), 625000 , 1); gps_locals.stateca1 = 0; timer_set(TIME_IN_NSEC(814000000),0,oneshoot); // fire ca1 only once // // this time should run to emulate the 6840 correctly, but it is not needed for gampelan games i think // because the sound rum never reads back the decreased values from the m6840 // // timer_pulse(TIME_IN_HZ(MSU1_INTCLOCK),0x02,m6840_pulse); // start internal clock 6840 // }
INLINE void timer_list_insert(mame_timer *timer) { double expire = timer->enabled ? timer->expire : TIME_NEVER; mame_timer *t, *lt = NULL; /* sanity checks for the debug build */ #ifdef MAME_DEBUG { int tnum = 0; /* loop over the timer list */ for (t = timer_head; t; t = t->next, tnum++) { if (t == timer) printf("This timer is already inserted in the list!\n"); if (tnum == MAX_TIMERS-1) printf("Timer list is full!\n"); } } #endif /* loop over the timer list */ for (t = timer_head; t; lt = t, t = t->next) { /* if the current list entry expires after us, we should be inserted before it */ /* note that due to floating point rounding, we need to allow a bit of slop here */ /* because two equal entries -- within rounding precision -- need to sort in */ /* the order they were inserted into the list */ if ((t->expire - expire) > TIME_IN_NSEC(1)) { /* link the new guy in before the current list entry */ timer->prev = t->prev; timer->next = t; if (t->prev) t->prev->next = timer; else timer_head = timer; t->prev = timer; return; } } /* need to insert after the last one */ if (lt) lt->next = timer; else timer_head = timer; timer->prev = lt; timer->next = NULL; }
static double cpu_computerate(int value) { /* values equal to zero are zero */ if (value <= 0) return 0.0; /* values above between 0 and 50000 are in Hz */ if (value < 50000) return TIME_IN_HZ(value); /* values greater than 50000 are in nanoseconds */ else return TIME_IN_NSEC(value); }
double cpu_getscanlinetime(int scanline) { double scantime = timer_starttime(refresh_timer) + (double)scanline * scanline_period; double abstime = timer_get_time(); double result; /* if we're already past the computed time, count it for the next frame */ if (abstime >= scantime) scantime += TIME_IN_HZ(Machine->drv->frames_per_second); /* compute how long from now until that time */ result = scantime - abstime; /* if it's small, just count a whole frame */ if (result < TIME_IN_NSEC(1)) result += TIME_IN_HZ(Machine->drv->frames_per_second); return result; }
void timer_adjust_global_time(double delta) { mame_timer *timer; /* add the delta to the global offset */ global_offset += delta; /* scan the list and adjust the times */ for (timer = timer_head; timer != NULL; timer = timer->next) { timer->start -= delta; timer->expire -= delta; } LOG(("timer_adjust_global_time: delta=%.9f head->expire=%.9f\n", delta, timer_head->expire)); /* now process any timers that are overdue */ while (timer_head->expire < TIME_IN_NSEC(1)) { int was_enabled = timer_head->enabled; /* if this is a one-shot timer, disable it now */ timer = timer_head; if (timer->period == 0) timer->enabled = 0; /* set the global state of which callback we're in */ callback_timer_modified = 0; callback_timer = timer; callback_timer_expire_time = timer->expire; /* call the callback */ if (was_enabled && timer->callback) { LOG(("Timer %08X fired (expire=%.9f)\n", (UINT32)timer, timer->expire)); profiler_mark(PROFILER_TIMER_CALLBACK); (*timer->callback)(timer->callback_param); profiler_mark(PROFILER_END); } /* clear the callback timer global */ callback_timer = NULL; /* reset or remove the timer, but only if it wasn't modified during the callback */ if (!callback_timer_modified) { /* if the timer is temporary, remove it now */ if (timer->temporary) timer_remove(timer); /* otherwise, reschedule it */ else { timer->start = timer->expire; timer->expire += timer->period; timer_list_remove(timer); timer_list_insert(timer); } } } }
else { // transparent disable nbmj8891_videoram1[(dy2 * Machine->screen[0].width) + dx1] = color1; update_pixel1(dx1, dy2); nbmj8891_videoram1[(dy2 * Machine->screen[0].width) + dx2] = color2; update_pixel1(dx2, dy2); } } nb1413m3_busyctr++; } } nb1413m3_busyflag = 0; timer_set((double)nb1413m3_busyctr * TIME_IN_NSEC(2500), 0, blitter_timer_callback); } /****************************************************************************** ******************************************************************************/ VIDEO_START( nbmj8891_1layer ) { unsigned char *CLUT = memory_region(REGION_USER1); int i; nbmj8891_tmpbitmap0 = auto_bitmap_alloc(Machine->screen[0].width, Machine->screen[0].height); nbmj8891_videoram0 = auto_malloc(Machine->screen[0].width * Machine->screen[0].height * sizeof(char)); nbmj8891_palette = auto_malloc(0x200 * sizeof(char)); nbmj8891_clut = auto_malloc(0x800 * sizeof(char));
static void cchasm_refresh (void) { int pc = 0; int done = 0; int opcode, data; int currentx = 0, currenty = 0; int scalex = 0, scaley = 0; int color = 0; int total_length = 1; /* length of all lines drawn in a frame */ int move = 0; vector_clear_list(); while (!done) { data = cchasm_ram[pc]; opcode = data >> 12; data &= 0xfff; if ((opcode > COLOR) && (data & 0x800)) data |= 0xfffff000; pc++; switch (opcode) { case HALT: done=1; break; case JUMP: pc = data - 0xb00; logerror("JUMP to %x\n", data); break; case COLOR: color = VECTOR_COLOR444(data ^ 0xfff); break; case SCALEY: scaley = data << 5; break; case POSY: move = 1; currenty = ycenter + (data << 16); break; case SCALEX: scalex = data << 5; break; case POSX: move = 1; currentx = xcenter - (data << 16); break; case LENGTH: if (move) { vector_add_point (currentx, currenty, 0, 0); move = 0; } currentx -= data * scalex; currenty += data * scaley; total_length += abs(data); if (color) vector_add_point (currentx, currenty, color, 0xff); else move = 1; break; default: logerror("Unknown refresh proc opcode %x with data %x at pc = %x\n", opcode, data, pc-2); done = 1; break; } } /* Refresh processor runs with 6 MHz */ timer_set (TIME_IN_NSEC(166) * total_length, 0, cchasm_refresh_end); }
static void timer_callback(int ref) { cpu_set_irq_line(0, 0, ASSERT_LINE); timer_set(TIME_IN_NSEC(300), 0, irq_off); }
/* basic machine hardware */ MDRV_CPU_ADD(Z80, 4000000) /* 4 MHz */ MDRV_CPU_PROGRAM_MAP(readmem,writemem) MDRV_CPU_IO_MAP(readport,writeport) MDRV_CPU_VBLANK_INT(irq0_line_hold,1) MDRV_CPU_ADD(Z80, 3000000) /* 3 MHz */ /* audio CPU */ MDRV_CPU_PROGRAM_MAP(sound_readmem,sound_writemem) /* interrupts (from Jungle King hardware, might be wrong): */ /* - no interrupts synced with vblank */ /* - NMI triggered by the main CPU */ /* - periodic IRQ, with frequency 6000000/(4*16*16*10*16) = 36.621 Hz, */ /* that is a period of 27306666.6666 ns */ MDRV_CPU_PERIODIC_INT(irq0_line_hold,TIME_IN_NSEC(27306667)) MDRV_FRAMES_PER_SECOND(60) MDRV_VBLANK_DURATION(DEFAULT_60HZ_VBLANK_DURATION) /* video hardware */ MDRV_VIDEO_ATTRIBUTES(VIDEO_TYPE_RASTER) MDRV_SCREEN_SIZE(32*8, 32*8) MDRV_VISIBLE_AREA(0*8, 32*8-1, 2*8, 30*8-1) MDRV_GFXDECODE(gfxdecodeinfo) MDRV_PALETTE_LENGTH(512) MDRV_COLORTABLE_LENGTH(4*8+4*4+4*2+4*2) MDRV_PALETTE_INIT(bking2) MDRV_VIDEO_START(bking2) MDRV_VIDEO_UPDATE(bking2)
void cchasm_6840_w(int offset, int data) { /* From datasheet: 0 0 - write control reg 1/3 (reg 1 if lsb of Reg 2 is 1, else 3) 2 1 - write control reg 2 4 2 - write msb buffer reg 6 3 - write timer 1 latch 8 4 - msb buffer register a 5 - write timer 2 latch c 6 - msb buffer reg e 7 - write timer 3 latch So: Write ff0100 to 6840 02 = } Write ff0000 to 6840 00 = } Write 0 to control reg 1 Write ff0000 to 6840 02 Write ff0000 to 6840 0c Write ff3500 to 6840 0e = } Write 0035 to timer 3 latch? Write ff0a00 to 6840 00 = } Write 0a to control reg 3 */ data &= 0xff; switch (offset) { case 0x0: /* CR1/3 */ m6840_cr[m6840_cr_select] = data; if (m6840_cr_select==0) { if ((data&0x1)) { int i; if (errorlog) fprintf(errorlog,"MC6840: Internal reset\n"); for (i=0; i<3; i++) { m6840_timerLSB[i]=255; m6840_timerMSB[i]=255; } } else if (errorlog) fprintf(errorlog,"MC6840: Timers go!\n"); } else if (m6840_cr_select==2) { if (data&0x1) { if (errorlog) fprintf(errorlog,"MC6840: Divide by 8 prescaler selected\n"); } } /* Following bits apply to both registers */ if (data&0x2) { if (errorlog) fprintf(errorlog,"MC6840: Internal clock selected on CR %d\n",m6840_cr_select); else if (errorlog) fprintf(errorlog,"MC6840: External clock selected on CR %d\n",m6840_cr_select); } if (data&0x4) { if (errorlog) fprintf(errorlog,"MC6840: Dual 8 bit count mode selected on CR %d\n",m6840_cr_select); else if (errorlog) fprintf(errorlog,"MC6840: 16 bit count mode selected on CR %d\n",m6840_cr_select); } if (errorlog) fprintf(errorlog," Write %02x to control register 1/3\n",data); break; case 0x2: m6840_cr[1] = data; if (data&0x1) { m6840_cr_select=0; if (errorlog) fprintf(errorlog,"MC6840: Control register 1 selected\n"); } else { m6840_cr_select=2; if (errorlog) fprintf(errorlog,"MC6840: Control register 3 selected\n"); } if (data&0x80) if (errorlog) fprintf(errorlog,"MC6840: Cr2 Timer output enabled\n"); if (data&0x40) if (errorlog) fprintf(errorlog,"MC6840: Cr2 interrupt output enabled\n"); if (errorlog) fprintf(errorlog," Write %02x to control register 2\n",data); break; case 0x4: m6840_timerMSB[0]=data; m6840_status &= ~0x01; if (errorlog) fprintf(errorlog," Write %02x to MSB of Timer 1\n",data); break; case 0x6: m6840_status &= ~0x01; m6840_timerLSB[0]=data; if (errorlog) fprintf(errorlog," Write %02x to LSB of Timer 1\n",data); break; case 0x8: m6840_status &= ~0x02; cchasm_6840_irq(CLEAR_LINE); m6840_timerMSB[1]=data; if ((m6840_cr[1] & 0x38) == 0) timer_set (TIME_IN_NSEC(M6840_CYCLE) * ((m6840_timerMSB[1]<<8) | m6840_timerLSB[1]), 0, timer_2_timeout); if (errorlog) fprintf(errorlog," Write %02x to MSB of Timer 2\n",data); break; case 0xa: m6840_status &= ~0x02; cchasm_6840_irq(CLEAR_LINE); m6840_timerLSB[1]=data; if (errorlog) fprintf(errorlog," Write %02x to LSB of Timer 2\n",data); break; case 0xc: m6840_status &= ~0x04; m6840_timerMSB[2]=data; if (errorlog) fprintf(errorlog," Write %02x to MSB of Timer 3\n",data); break; case 0xe: m6840_status &= ~0x04; m6840_timerLSB[2]=data; if (errorlog) fprintf(errorlog," Write %02x to LSB of Timer 3\n",data); break; } /* if (errorlog) fprintf(errorlog,"Write %04x to 6840 %02x\n",data,offset); */ }