Rewrote timer code.

The new code is based on timestamps, rather than delays. This eliminates the
need to update every timer in timer_process(), which cost a non-trivial amount
of CPU time on low-end machines.

This involved changes to every user of the timer code, so this change almost
certainly introduces bugs.
This commit is contained in:
SarahW 2018-08-02 22:06:10 +01:00
commit a7d006b637
79 changed files with 1050 additions and 1033 deletions

View file

@ -222,12 +222,11 @@ void exec386(int cycs)
// output=3;
while (cycles>0)
{
int cycle_period = (timer_count >> TIMER_SHIFT) + 1;
int cycle_period = (timer_target - (uint32_t)tsc) + 1;
x86_was_reset = 0;
cycdiff=0;
oldcyc=cycles;
timer_start_period(cycles << TIMER_SHIFT);
// pclog("%i %02X\n", ins, ram[8]);
while (cycdiff < cycle_period)
{
@ -257,7 +256,7 @@ dontprint=0;
if (output == 3)
{
pclog("%04X(%06X):%04X : %08X %08X %08X %08X %04X %04X %04X(%08X) %04X %04X %04X(%08X) %08X %08X %08X SP=%04X:%08X %02X %04X %i %08X %08X %i %i %02X %02X %02X %02X %02X %f %02X%02X %02X%02X %02X%02X %02X\n",CS,cs,cpu_state.pc,EAX,EBX,ECX,EDX,CS,DS,ES,es,FS,GS,SS,ss,EDI,ESI,EBP,SS,ESP,opcode,flags,ins,0, ldt.base, CPL, stack32, pic.pend, pic.mask, pic.mask2, pic2.pend, pic2.mask, pit.c[0], ram[0xB270+0x3F5], ram[0xB270+0x3F4], ram[0xB270+0x3F7], ram[0xB270+0x3F6], ram[0xB270+0x3F9], ram[0xB270+0x3F8], ram[0x4430+0x0D49]);
pclog("%04X(%06X):%04X : %08X %08X %08X %08X %04X %04X %04X(%08X) %04X %04X %04X(%08X) %08X %08X %08X SP=%04X:%08X %02X %04X %i %08X %08X %i %i %02X %02X %02X %02X %02X\n",CS,cs,cpu_state.pc,EAX,EBX,ECX,EDX,CS,DS,ES,es,FS,GS,SS,ss,EDI,ESI,EBP,SS,ESP,opcode,flags,ins,0, ldt.base, CPL, stack32, pic.pend, pic.mask, pic.mask2, pic2.pend, pic2.mask);
}
cpu_state.pc++;
x86_opcodes[(opcode | cpu_state.op32) & 0x3ff](fetchdat);
@ -381,7 +380,7 @@ dontprint=0;
}
tsc += cycdiff;
timer_end_period(cycles << TIMER_SHIFT);
if (TIMER_VAL_LESS_THAN_VAL(timer_target, (uint32_t)tsc))
timer_process();
}
}

View file

@ -528,7 +528,6 @@ void exec386_dynarec(int cycs)
cycles += cyc_period;
cycles_start = cycles;
timer_start_period(cycles << TIMER_SHIFT);
// output=3;
while (cycles>0)
{
@ -945,7 +944,8 @@ inrecomp=0;
}
}
}
timer_end_period(cycles << TIMER_SHIFT);
if (TIMER_VAL_LESS_THAN_VAL(timer_target, (uint32_t)tsc))
timer_process();
cycles_main -= (cycles_start - cycles);
}
}

View file

@ -25,7 +25,7 @@
#include "x87.h"
#include "paths.h"
int xt_cpu_multi;
uint64_t xt_cpu_multi;
int nmi = 0;
int nmi_auto_clear = 0;
@ -821,13 +821,24 @@ static void setsbc16(uint16_t a, uint16_t b)
}
int current_diff = 0;
/*XT systems use the XT master oscillator (14.318 MHz) rather than the CPU clock
at the base timer frequency. Because there isn't an integer relationship
between the two frequencies, use fixed point arithmetic when updating TSC.*/
static uint64_t tsc_frac = 0;
void clockhardware()
{
int diff = cycdiff - cycles - current_diff;
current_diff += diff;
timer_end_period(cycles*xt_cpu_multi);
tsc_frac += (uint64_t)diff * xt_cpu_multi;
tsc += (tsc_frac >> 32);
tsc_frac &= 0xffffffff;
if (TIMER_VAL_LESS_THAN_VAL(timer_target, (uint32_t)tsc))
timer_process();
}
static int takeint = 0;
@ -1104,7 +1115,6 @@ void execx86(int cycs)
// if (pc==0x96B && cs==0x9E040) { printf("Hit it\n"); output=1; timetolive=150; }
// if (pc<0x8000) printf("%04X : %04X %04X %04X %04X %04X %04X %04X %04X %04X %04X %04X %04X %02X %04X %i\n",pc,AX,BX,CX,DX,cs>>4,ds>>4,es>>4,ss>>4,DI,SI,BP,SP,opcode,flags,disctime);
cycdiff=cycles;
timer_start_period(cycles*xt_cpu_multi);
current_diff = 0;
cycles-=nextcyc;
// if (instime) pclog("Cycles %i %i\n",cycles,cycdiff);

View file

@ -140,7 +140,7 @@ void cpu_WRMSR();
extern int cpu_use_dynarec;
extern int xt_cpu_multi;
extern uint64_t xt_cpu_multi;
extern int isa_cycles;
#define ISA_CYCLES(x) (x * isa_cycles)

View file

@ -9,7 +9,7 @@
#include "timer.h"
int disc_drivesel = 0;
int disc_poll_time = 16;
pc_timer_t disc_poll_timer;
int disc_track[2];
int writeprot[2], fwriteprot[2];
@ -22,9 +22,6 @@ int curdrive = 0;
//char discfns[2][260] = {"", ""};
int defaultwriteprot = 0;
int fdc_time;
int disc_time;
int fdc_ready;
int drive_empty[2] = {1, 1};
@ -137,7 +134,7 @@ int disc_hole(int drive)
void disc_poll()
{
disc_poll_time += disc_period * TIMER_USEC;
timer_advance_u64(&disc_poll_timer, disc_period * TIMER_USEC);
if (disc_drivesel < 2 && drives[disc_drivesel].poll)
drives[disc_drivesel].poll();
@ -209,7 +206,7 @@ void disc_reset()
curdrive = 0;
disc_period = 32;
timer_add(disc_poll, &disc_poll_time, &motoron, NULL);
timer_add(&disc_poll_timer, disc_poll, NULL, 0);
for (drive = 0; drive < 2; drive++)
{
@ -295,3 +292,12 @@ void disc_set_drivesel(int drive)
disc_drivesel = drive;
}
void disc_set_motor_enable(int motor_enable)
{
if (motor_enable && !motoron)
timer_set_delay_u64(&disc_poll_timer, disc_period * TIMER_USEC);
else if (!motor_enable)
timer_disable(&disc_poll_timer);
motoron = motor_enable;
}

View file

@ -30,8 +30,7 @@ void disc_stop(int drive);
int disc_empty(int drive);
void disc_set_rate(int drive, int drvden, int rate);
void disc_set_drivesel(int drive);
extern int disc_time;
extern int disc_poll_time;
void disc_set_motor_enable(int motor_enable);
extern int disc_drivesel;
void fdc_callback();
@ -45,8 +44,7 @@ void fdc_writeprotect();
int fdc_getdata(int last);
void fdc_sectorid(uint8_t track, uint8_t side, uint8_t sector, uint8_t size, uint8_t crc1, uint8_t crc2);
void fdc_indexpulse();
/*extern int fdc_time;
extern int fdc_ready;
/*extern int fdc_ready;
extern int fdc_indexcount;*/
extern int motorspin;

View file

@ -74,7 +74,7 @@ typedef struct esdi_t
uint16_t buffer[256];
int irqstat;
int callback;
pc_timer_t callback_timer;
esdi_drive_t drives[2];
@ -224,18 +224,14 @@ void esdi_write(uint16_t port, uint8_t val, void *p)
// pclog("Restore\n");
esdi->command &= ~0x0f; /*Mask off step rate*/
esdi->status = STAT_BUSY;
timer_clock();
esdi->callback = 200*IDE_TIME;
timer_update_outstanding();
timer_set_delay_u64(&esdi->callback_timer, 200*IDE_TIME);
break;
case CMD_SEEK:
// pclog("Seek to cylinder %i\n", esdi->cylinder);
esdi->command &= ~0x0f; /*Mask off step rate*/
esdi->status = STAT_BUSY;
timer_clock();
esdi->callback = 200*IDE_TIME;
timer_update_outstanding();
timer_set_delay_u64(&esdi->callback_timer, 200*IDE_TIME);
break;
default:
@ -243,9 +239,7 @@ void esdi_write(uint16_t port, uint8_t val, void *p)
{
case CMD_NOP:
esdi->status = STAT_BUSY;
timer_clock();
esdi->callback = 200*IDE_TIME;
timer_update_outstanding();
timer_set_delay_u64(&esdi->callback_timer, 200*IDE_TIME);
break;
case CMD_READ: case CMD_READ+1:
@ -256,9 +250,7 @@ void esdi_write(uint16_t port, uint8_t val, void *p)
fatal("Read with ECC\n");
case 0xa0:
esdi->status = STAT_BUSY;
timer_clock();
esdi->callback = 200*IDE_TIME;
timer_update_outstanding();
timer_set_delay_u64(&esdi->callback_timer, 200*IDE_TIME);
break;
case CMD_WRITE: case CMD_WRITE+1:
@ -275,9 +267,7 @@ void esdi_write(uint16_t port, uint8_t val, void *p)
// pclog("Read verify %i sectors from sector %i cylinder %i head %i\n",esdi->secount,esdi->sector,esdi->cylinder,esdi->head);
esdi->command &= ~1;
esdi->status = STAT_BUSY;
timer_clock();
esdi->callback = 200 * IDE_TIME;
timer_update_outstanding();
timer_set_delay_u64(&esdi->callback_timer, 200 * IDE_TIME);
break;
case CMD_FORMAT:
@ -288,33 +278,25 @@ void esdi_write(uint16_t port, uint8_t val, void *p)
case CMD_SET_PARAMETERS: /* Initialize Drive Parameters */
esdi->status = STAT_BUSY;
timer_clock();
esdi->callback = 30*IDE_TIME;
timer_update_outstanding();
timer_set_delay_u64(&esdi->callback_timer, 30*IDE_TIME);
break;
case CMD_DIAGNOSE: /* Execute Drive Diagnostics */
esdi->status = STAT_BUSY;
timer_clock();
esdi->callback = 200*IDE_TIME;
timer_update_outstanding();
timer_set_delay_u64(&esdi->callback_timer, 200*IDE_TIME);
break;
case 0xe0: /*???*/
case CMD_READ_PARAMETERS:
esdi->status = STAT_BUSY;
timer_clock();
esdi->callback = 200*IDE_TIME;
timer_update_outstanding();
timer_set_delay_u64(&esdi->callback_timer, 200*IDE_TIME);
break;
default:
pclog("Bad esdi command %02X\n", val);
case 0xe8: /*???*/
esdi->status = STAT_BUSY;
timer_clock();
esdi->callback = 200*IDE_TIME;
timer_update_outstanding();
timer_set_delay_u64(&esdi->callback_timer, 200*IDE_TIME);
break;
}
}
@ -323,9 +305,7 @@ void esdi_write(uint16_t port, uint8_t val, void *p)
case 0x3F6: /* Device control */
if ((esdi->fdisk & 4) && !(val & 4))
{
timer_clock();
esdi->callback = 500*IDE_TIME;
timer_update_outstanding();
timer_set_delay_u64(&esdi->callback_timer, 500*IDE_TIME);
esdi->reset = 1;
esdi->status = STAT_BUSY;
// pclog("esdi Reset\n");
@ -333,9 +313,7 @@ void esdi_write(uint16_t port, uint8_t val, void *p)
if (val & 4)
{
/*Drive held in reset*/
timer_clock();
esdi->callback = 0;
timer_update_outstanding();
timer_disable(&esdi->callback_timer);
esdi->status = STAT_BUSY;
}
esdi->fdisk = val;
@ -357,9 +335,7 @@ void esdi_writew(uint16_t port, uint16_t val, void *p)
{
esdi->pos = 0;
esdi->status = STAT_BUSY;
timer_clock();
esdi->callback = 6*IDE_TIME;
timer_update_outstanding();
timer_set_delay_u64(&esdi->callback_timer, 6*IDE_TIME);
}
}
@ -428,9 +404,7 @@ uint16_t esdi_readw(uint16_t port, void *p)
{
esdi_next_sector(esdi);
esdi->status = STAT_BUSY;
timer_clock();
esdi->callback = 6*IDE_TIME;
timer_update_outstanding();
timer_set_delay_u64(&esdi->callback_timer, 6*IDE_TIME);
}
}
}
@ -446,7 +420,7 @@ void esdi_callback(void *p)
off64_t addr;
// pclog("esdi_callback: command=%02x reset=%i\n", esdi->command, esdi->reset);
esdi->callback = 0;
if (esdi->reset)
{
esdi->status = STAT_READY | STAT_DSC;
@ -586,7 +560,7 @@ void esdi_callback(void *p)
esdi_next_sector(esdi);
esdi->secount = (esdi->secount - 1) & 0xff;
if (esdi->secount)
esdi->callback = 6*IDE_TIME;
timer_set_delay_u64(&esdi->callback_timer, 6*IDE_TIME);
else
{
esdi->pos = 0;
@ -804,7 +778,7 @@ void *wd1007vse1_init()
io_sethandler(0x01f1, 0x0007, esdi_read, NULL, NULL, esdi_write, NULL, NULL, esdi);
io_sethandler(0x03f6, 0x0001, NULL, NULL, NULL, esdi_write, NULL, NULL, esdi);
timer_add(esdi_callback, &esdi->callback, &esdi->callback, esdi);
timer_add(&esdi->callback_timer, esdi_callback, esdi, 0);
return esdi;
}

123
src/fdc.c
View file

@ -10,8 +10,6 @@
#include "pic.h"
#include "timer.h"
extern int motoron;
static int fdc_reset_stat = 0;
/*FDC*/
typedef struct FDC
@ -39,7 +37,7 @@ typedef struct FDC
int pcjr, ps1;
int watchdog_timer;
pc_timer_t watchdog_timer;
int watchdog_count;
int data_ready;
@ -65,6 +63,8 @@ typedef struct FDC
uint8_t fifobuf[16];
int int_pending;
pc_timer_t timer;
} FDC;
static FDC fdc;
@ -151,12 +151,11 @@ static void fdc_watchdog_poll(void *p)
fdc->watchdog_count--;
if (fdc->watchdog_count)
fdc->watchdog_timer += 1000 * TIMER_USEC;
timer_advance_u64(&fdc->watchdog_timer, 1000 * TIMER_USEC);
else
{
// pclog("Watchdog timed out\n");
fdc->watchdog_timer = 0;
if (fdc->dor & 0x20)
picint(1 << 6);
}
@ -332,25 +331,19 @@ void fdc_write(uint16_t addr, uint8_t val, void *priv)
{
if ((fdc.dor & 0x40) && !(val & 0x40))
{
fdc.watchdog_timer = 1000 * TIMER_USEC;
timer_set_delay_u64(&fdc.watchdog_timer, 1000 * TIMER_USEC);
fdc.watchdog_count = 1000;
picintc(1 << 6);
// pclog("watchdog set %i %i\n", fdc.watchdog_timer, TIMER_USEC);
}
if ((val & 0x80) && !(fdc.dor & 0x80))
{
timer_process();
disctime = 128 * (1 << TIMER_SHIFT);
timer_update_outstanding();
timer_set_delay_u64(&fdc.timer, 8 * TIMER_USEC);
discint=-1;
fdc_reset();
}
motoron = val & 0x01;
disc_set_motor_enable(val & 0x01);
fdc.drive = 0;
/* if (motoron)
output = 3;
else
output = 0;*/
}
else
{
@ -361,15 +354,11 @@ void fdc_write(uint16_t addr, uint8_t val, void *priv)
}
if ((val&4) && !(fdc.dor&4))
{
timer_process();
disctime = 128 * (1 << TIMER_SHIFT);
timer_update_outstanding();
timer_set_delay_u64(&fdc.timer, 8 * TIMER_USEC);
discint=-1;
fdc_reset();
}
timer_process();
motoron = (val & 0xf0) ? 1 : 0;
timer_update_outstanding();
disc_set_motor_enable((val & 0xf0) ? 1 : 0);
fdc.drive = val & 3;
}
fdc.dor=val;
@ -386,9 +375,7 @@ void fdc_write(uint16_t addr, uint8_t val, void *priv)
case 4:
if (val & 0x80)
{
timer_process();
disctime = 128 * (1 << TIMER_SHIFT);
timer_update_outstanding();
timer_set_delay_u64(&fdc.timer, 8 * TIMER_USEC);
discint=-1;
fdc_reset();
}
@ -471,7 +458,6 @@ void fdc_write(uint16_t addr, uint8_t val, void *priv)
// printf("Sense interrupt status %i\n",curdrive);
fdc.lastdrive = fdc.drive;
// fdc.stat = 0x10 | (fdc.stat & 0xf);
// fdc_time=1024;
discint = 8;
fdc.pos = 0;
fdc_callback();
@ -480,9 +466,7 @@ void fdc_write(uint16_t addr, uint8_t val, void *priv)
{
fdc.stat=0x10;
discint=0xfc;
timer_process();
disctime = 200 * (1 << TIMER_SHIFT);
timer_update_outstanding();
timer_set_delay_u64(&fdc.timer, 100 * TIMER_USEC);
}
break;
case 10: /*Read sector ID*/
@ -553,9 +537,7 @@ bad_command:
// exit(-1);
fdc.stat=0x10;
discint=0xfc;
timer_process();
disctime = 200 * (1 << TIMER_SHIFT);
timer_update_outstanding();
timer_set_delay_u64(&fdc.timer, 100 * TIMER_USEC);
break;
}
}
@ -564,12 +546,12 @@ bad_command:
fdc.params[fdc.pnum++]=val;
if (fdc.pnum==fdc.ptot)
{
uint64_t time;
// pclog("Got all params %02X\n", fdc.command);
fdc.stat=0x30;
discint=fdc.command&0x1F;
timer_process();
disctime = 1024 * (1 << TIMER_SHIFT);
timer_update_outstanding();
timer_set_delay_u64(&fdc.timer, 1024 * TIMER_USEC);
// fdc.drive = fdc.params[0] & 3;
disc_drivesel = fdc.drive & 1;
fdc_reset_stat = 0;
@ -587,7 +569,7 @@ bad_command:
fdc.track[fdc.drive]=fdc.params[1];
// pclog("Read a track track=%i head=%i sector=%i eot=%i\n", fdc.track[fdc.drive], fdc.head, fdc.sector, fdc.eot[fdc.drive]);
disc_readsector(fdc.drive, SECTOR_FIRST, fdc.track[fdc.drive], fdc.head, fdc.rate, fdc.params[4]);
disctime = 0;
timer_disable(&fdc.timer);
readflash_set(READFLASH_FDC, fdc.drive);
fdc.inread = 1;
break;
@ -597,7 +579,7 @@ bad_command:
fdc.specify[0] = fdc.params[0];
fdc.specify[1] = fdc.params[1];
fdc.dma = (fdc.specify[1] & 1) ^ 1;
disctime = 0;
timer_disable(&fdc.timer);
break;
case 5: /*Write data*/
@ -612,7 +594,7 @@ bad_command:
fdc.rw_track = fdc.params[1];
disc_writesector(fdc.drive, fdc.sector, fdc.track[fdc.drive], fdc.head, fdc.rate, fdc.params[4]);
disctime = 0;
timer_disable(&fdc.timer);
fdc.written = 0;
readflash_set(READFLASH_FDC, fdc.drive);
fdc.pos = 0;
@ -633,15 +615,17 @@ bad_command:
fdc.rw_track = fdc.params[1];
disc_readsector(fdc.drive, fdc.sector, fdc.track[fdc.drive], fdc.head, fdc.rate, fdc.params[4]);
disctime = 0;
timer_disable(&fdc.timer);
readflash_set(READFLASH_FDC, fdc.drive);
fdc.inread = 1;
break;
case 7: /*Recalibrate*/
fdc.stat = 1 << fdc.drive;
disctime = 0;
fdd_seek(fdc.drive, SEEK_RECALIBRATE);
timer_disable(&fdc.timer);
time = fdd_seek(fdc.drive, SEEK_RECALIBRATE);
if (time)
timer_set_delay_u64(&fdc.timer, time);
break;
case 0x0d: /*Format*/
@ -655,14 +639,16 @@ bad_command:
case 0xf: /*Seek*/
fdc.stat = 1 << fdc.drive;
fdc.head = (fdc.params[0] & 4) ? 1 : 0;
disctime = 0;
fdd_seek(fdc.drive, fdc.params[1] - fdc.track[fdc.drive]);
timer_disable(&fdc.timer);
time = fdd_seek(fdc.drive, fdc.params[1] - fdc.track[fdc.drive]);
if (time)
timer_set_delay_u64(&fdc.timer, time);
// pclog("Seek to %i\n", fdc.params[1]);
break;
case 10: /*Read sector ID*/
fdc_rate(fdc.drive);
disctime = 0;
timer_disable(&fdc.timer);
fdc.head = (fdc.params[0] & 4) ? 1 : 0;
// pclog("Read sector ID %i %i\n", fdc.rate, fdc.drive);
disc_readaddress(fdc.drive, fdc.track[fdc.drive], fdc.head, fdc.rate);
@ -771,9 +757,7 @@ uint8_t fdc_read(uint16_t addr, void *priv)
}
if (discint==0xA)
{
timer_process();
disctime = 1024 * (1 << TIMER_SHIFT);
timer_update_outstanding();
timer_set_delay_u64(&fdc.timer, 1024 * TIMER_USEC);
}
fdc.stat &= 0xf0;
break;
@ -805,8 +789,7 @@ void fdc_callback()
int doseek = 0;
int drive;
disctime = 0;
// pclog("fdc_callback %i %i\n", discint, disctime);
// pclog("fdc_callback %i\n", discint);
// if (fdc.inread)
// rpclog("c82c711_fdc_callback : while inread! %08X %i %02X %i\n", discint, fdc.drive, fdc.st0, ins);
switch (discint)
@ -870,7 +853,6 @@ void fdc_callback()
fdc.stat = (fdc.stat & 0xf) | 0xd0;
paramstogo = 1;
discint = 0;
disctime = 0;
return;
case 5: /*Write data*/
if (!fdc.in_seek_mt)
@ -983,9 +965,7 @@ void fdc_callback()
fdc.st0 = 0x68 | (fdc.params[0] & 3) | (fdc.head?4:0);
fdc.int_pending = 1;
discint=-3;
timer_process();
disctime = 2048 * (1 << TIMER_SHIFT);
timer_update_outstanding();
timer_set_delay_u64(&fdc.timer, 2048 * TIMER_USEC);
// printf("Recalibrate complete!\n");
fdc.stat = 0x80 | (1 << fdc.drive);
return;
@ -1006,7 +986,6 @@ void fdc_callback()
paramstogo = 2;
discint = 0;
disctime = 0;
return;
case 0x0d: /*Format track*/
@ -1015,26 +994,20 @@ void fdc_callback()
{
// ioc_fiq(IOC_FIQ_DISC_DATA);
fdc.format_state = 2;
timer_process();
disctime = 128 * (1 << TIMER_SHIFT);
timer_update_outstanding();
timer_set_delay_u64(&fdc.timer, 8 * TIMER_USEC);
}
else if (fdc.format_state == 2)
{
temp = fdc_getdata(fdc.pos == ((fdc.params[2] * 4) - 1));
if (temp == -1)
{
timer_process();
disctime = 128 * (1 << TIMER_SHIFT);
timer_update_outstanding();
timer_set_delay_u64(&fdc.timer, 8 * TIMER_USEC);
return;
}
fdc.format_dat[fdc.pos++] = temp;
if (fdc.pos == (fdc.params[2] * 4))
fdc.format_state = 3;
timer_process();
disctime = 128 * (1 << TIMER_SHIFT);
timer_update_outstanding();
timer_set_delay_u64(&fdc.timer, 8 * TIMER_USEC);
}
else if (fdc.format_state == 3)
{
@ -1070,9 +1043,7 @@ void fdc_callback()
fdc.st0 = 0x68 | (fdc.params[0] & 3) | (fdc.head?4:0);
fdc.int_pending = 1;
discint=-3;
timer_process();
disctime = 2048 * (1 << TIMER_SHIFT);
timer_update_outstanding();
timer_set_delay_u64(&fdc.timer, 1024 * TIMER_USEC);
fdc.stat = 0x80 | (1 << fdc.drive);
// pclog("Stat %02X ST0 %02X\n", fdc.stat, fdc.st0);
return;
@ -1088,7 +1059,6 @@ void fdc_callback()
fdc.res[10] = (fdc.perp & 0x7f) | ((fdc.lock) ? 0x80 : 0);
paramstogo=10;
discint=0;
disctime = 0;
return;
case 0x10: /*Version*/
@ -1096,13 +1066,11 @@ void fdc_callback()
fdc.res[10] = 0x90;
paramstogo=1;
discint=0;
disctime = 0;
return;
case 0x12:
fdc.perp = fdc.params[0];
fdc.stat = 0x80;
disctime = 0;
// picint(0x40);
return;
case 0x13: /*Configure*/
@ -1112,7 +1080,6 @@ void fdc_callback()
fdc.tfifo = (fdc.params[1] & 0xF) + 1;
pclog("FIFO is now %02X, threshold is %02X\n", fdc.fifo, fdc.tfifo);
fdc.stat = 0x80;
disctime = 0;
// picint(0x40);
return;
case 0x14: /*Unlock*/
@ -1121,7 +1088,6 @@ void fdc_callback()
fdc.res[10] = 0;
paramstogo=1;
discint=0;
disctime = 0;
return;
case 0x94: /*Lock*/
fdc.lock = 1;
@ -1129,7 +1095,6 @@ void fdc_callback()
fdc.res[10] = 0x10;
paramstogo=1;
discint=0;
disctime = 0;
return;
case 0x18: /*NSC*/
@ -1137,7 +1102,6 @@ void fdc_callback()
fdc.res[10] = 0x73;
paramstogo=1;
discint=0;
disctime = 0;
return;
case 0xfc: /*Invalid*/
@ -1149,7 +1113,6 @@ void fdc_callback()
fdc.res[10] = fdc.st0;
paramstogo=1;
discint=0;
disctime = 0;
return;
}
// printf("Bad FDC disc int %i\n",discint);
@ -1160,7 +1123,7 @@ void fdc_callback()
void fdc_overrun()
{
disc_sector_stop();
disctime = 0;
timer_disable(&fdc.timer);
fdc_int();
fdc.stat=0xD0;
@ -1234,13 +1197,13 @@ int fdc_data(uint8_t data)
void fdc_finishread()
{
fdc.inread = 0;
disctime = 200 * TIMER_USEC;
timer_set_delay_u64(&fdc.timer, 200 * TIMER_USEC);
// rpclog("fdc_finishread\n");
}
void fdc_notfound()
{
disctime = 0;
timer_disable(&fdc.timer);
fdc_int();
fdc.stat=0xD0;
@ -1257,7 +1220,7 @@ void fdc_notfound()
void fdc_datacrcerror()
{
disctime = 0;
timer_disable(&fdc.timer);
fdc_int();
fdc.stat=0xD0;
@ -1274,7 +1237,7 @@ void fdc_datacrcerror()
void fdc_headercrcerror()
{
disctime = 0;
timer_disable(&fdc.timer);
fdc_int();
fdc.stat=0xD0;
@ -1291,7 +1254,7 @@ void fdc_headercrcerror()
void fdc_writeprotect()
{
disctime = 0;
timer_disable(&fdc.timer);
fdc_int();
fdc.stat=0xD0;
@ -1380,7 +1343,7 @@ void fdc_indexpulse()
void fdc_init()
{
timer_add(fdc_callback, &disctime, &disctime, NULL);
timer_add(&fdc.timer, fdc_callback, NULL, 0);
fdc.dskchg_activelow = 0;
fdc.enable_3f1 = 1;
@ -1404,7 +1367,7 @@ void fdc_add()
void fdc_add_pcjr()
{
io_sethandler(0x00f0, 0x0006, fdc_read, NULL, NULL, fdc_write, NULL, NULL, NULL);
timer_add(fdc_watchdog_poll, &fdc.watchdog_timer, &fdc.watchdog_timer, &fdc);
timer_add(&fdc.watchdog_timer, fdc_watchdog_poll, &fdc, 0);
fdc.pcjr = 1;
fdc.ps1 = 0;
}

View file

@ -76,15 +76,12 @@ static struct
int fdd_swap = 0;
void fdd_seek(int drive, int track_diff)
uint64_t fdd_seek(int drive, int track_diff)
{
drive ^= fdd_swap;
if (drive >= 2)
{
disctime = 5000;
return;
}
return 1000 * TIMER_USEC;
fdd[drive].track += track_diff;
@ -99,7 +96,7 @@ void fdd_seek(int drive, int track_diff)
fdc_discchange_clear(drive);
disc_seek(drive, fdd[drive].track);
disctime = 5000;
return 1000 * TIMER_USEC;
}
void fdd_disc_changed(int drive)

View file

@ -1,5 +1,5 @@
#define SEEK_RECALIBRATE -999
void fdd_seek(int drive, int track_diff);
uint64_t fdd_seek(int drive, int track_diff);
int fdd_track0(int drive);
int fdd_getrpm(int drive);
void fdd_set_densel(int densel);

View file

@ -69,7 +69,7 @@ char *joystick_get_pov_name(int joystick, int id)
typedef struct gameport_axis_t
{
int count;
pc_timer_t timer;
int axis_nr;
struct gameport_t *gameport;
} gameport_axis_t;
@ -86,7 +86,7 @@ typedef struct gameport_t
static gameport_t *gameport_global = NULL;
static int gameport_time(int axis)
static uint64_t gameport_time(int axis)
{
if (axis == AXIS_NOT_PRESENT)
return 0;
@ -101,14 +101,13 @@ void gameport_write(uint16_t addr, uint8_t val, void *p)
{
gameport_t *gameport = (gameport_t *)p;
timer_clock();
gameport->state |= 0x0f;
// pclog("gameport_write : joysticks_present=%i\n", joysticks_present);
gameport->axis[0].count = gameport_time(gameport->joystick->read_axis(gameport->joystick_dat, 0));
gameport->axis[1].count = gameport_time(gameport->joystick->read_axis(gameport->joystick_dat, 1));
gameport->axis[2].count = gameport_time(gameport->joystick->read_axis(gameport->joystick_dat, 2));
gameport->axis[3].count = gameport_time(gameport->joystick->read_axis(gameport->joystick_dat, 3));
timer_set_delay_u64(&gameport->axis[0].timer, gameport_time(gameport->joystick->read_axis(gameport->joystick_dat, 0)));
timer_set_delay_u64(&gameport->axis[1].timer, gameport_time(gameport->joystick->read_axis(gameport->joystick_dat, 1)));
timer_set_delay_u64(&gameport->axis[2].timer, gameport_time(gameport->joystick->read_axis(gameport->joystick_dat, 2)));
timer_set_delay_u64(&gameport->axis[3].timer, gameport_time(gameport->joystick->read_axis(gameport->joystick_dat, 3)));
gameport->joystick->write(gameport->joystick_dat);
@ -120,7 +119,6 @@ uint8_t gameport_read(uint16_t addr, void *p)
gameport_t *gameport = (gameport_t *)p;
uint8_t ret;
timer_clock();
// if (joysticks_present)
ret = gameport->state | gameport->joystick->read(gameport->joystick_dat);//0xf0;
// else
@ -139,7 +137,6 @@ void gameport_timer_over(void *p)
gameport_t *gameport = axis->gameport;
gameport->state &= ~(1 << axis->axis_nr);
axis->count = 0;
if (axis == &gameport->axis[0])
gameport->joystick->a0_over(gameport->joystick_dat);
@ -161,10 +158,10 @@ void *gameport_init_common()
gameport->axis[2].axis_nr = 2;
gameport->axis[3].axis_nr = 3;
timer_add(gameport_timer_over, &gameport->axis[0].count, &gameport->axis[0].count, &gameport->axis[0]);
timer_add(gameport_timer_over, &gameport->axis[1].count, &gameport->axis[1].count, &gameport->axis[1]);
timer_add(gameport_timer_over, &gameport->axis[2].count, &gameport->axis[2].count, &gameport->axis[2]);
timer_add(gameport_timer_over, &gameport->axis[3].count, &gameport->axis[3].count, &gameport->axis[3]);
timer_add(&gameport->axis[0].timer, gameport_timer_over, &gameport->axis[0], 0);
timer_add(&gameport->axis[1].timer, gameport_timer_over, &gameport->axis[1], 0);
timer_add(&gameport->axis[2].timer, gameport_timer_over, &gameport->axis[2], 0);
timer_add(&gameport->axis[3].timer, gameport_timer_over, &gameport->axis[3], 0);
gameport->joystick = joystick_list[joystick_type];
gameport->joystick_dat = gameport->joystick->init();

View file

@ -58,7 +58,7 @@ typedef struct esdi_t
int cmd_state;
int in_reset;
int callback;
pc_timer_t callback_timer;
uint32_t rba;
@ -163,7 +163,7 @@ static void esdi_write(uint16_t port, uint8_t val, void *p)
{
// pclog("ESDI reset\n");
esdi->in_reset = 1;
esdi->callback = ESDI_TIME * 50;
timer_set_delay_u64(&esdi->callback_timer, ESDI_TIME * 50);
esdi->status = STATUS_BUSY;
}
esdi->basic_ctrl = val;
@ -195,7 +195,7 @@ static void esdi_write(uint16_t port, uint8_t val, void *p)
case ATTN_RESET:
// pclog("ESDI reset\n");
esdi->in_reset = 1;
esdi->callback = ESDI_TIME * 50;
timer_set_delay_u64(&esdi->callback_timer, ESDI_TIME * 50);
esdi->status = STATUS_BUSY;
break;
@ -311,7 +311,7 @@ static void esdi_writew(uint16_t port, uint16_t val, void *p)
if ((esdi->cmd_data[0] & CMD_DEVICE_SEL) != esdi->cmd_dev)
fatal("Command device mismatch with attn\n");
esdi->command = esdi->cmd_data[0] & CMD_MASK;
esdi->callback = ESDI_TIME;
timer_set_delay_u64(&esdi->callback_timer, ESDI_TIME);
esdi->status = STATUS_BUSY;
esdi->data_pos = 0;
}
@ -421,8 +421,6 @@ static void esdi_callback(void *p)
esdi_t *esdi = (esdi_t *)p;
hdd_file_t *hdd_file;
esdi->callback = 0;
// pclog("esdi_callback: in_reset=%i command=%x\n", esdi->in_reset, esdi->command);
if (esdi->in_reset)
{
@ -464,7 +462,7 @@ static void esdi_callback(void *p)
esdi_set_irq(esdi);
esdi->cmd_state = 1;
esdi->callback = ESDI_TIME;
timer_set_delay_u64(&esdi->callback_timer, ESDI_TIME);
esdi->data_pos = 0;
break;
@ -472,7 +470,7 @@ static void esdi_callback(void *p)
if (!(esdi->basic_ctrl & CTRL_DMA_ENA))
{
// pclog("DMA not enabled\n");
esdi->callback = ESDI_TIME;
timer_set_delay_u64(&esdi->callback_timer, ESDI_TIME);
return;
}
while (esdi->sector_pos < esdi->sector_count)
@ -492,7 +490,7 @@ static void esdi_callback(void *p)
if (val == DMA_NODATA)
{
// pclog("DMA out of data\n");
esdi->callback = ESDI_TIME;
timer_set_delay_u64(&esdi->callback_timer, ESDI_TIME);
return;
}
@ -506,7 +504,7 @@ static void esdi_callback(void *p)
esdi->status = STATUS_CMD_IN_PROGRESS;
esdi->cmd_state = 2;
esdi->callback = ESDI_TIME;
timer_set_delay_u64(&esdi->callback_timer, ESDI_TIME);
break;
case 2:
@ -551,7 +549,7 @@ static void esdi_callback(void *p)
esdi_set_irq(esdi);
esdi->cmd_state = 1;
esdi->callback = ESDI_TIME;
timer_set_delay_u64(&esdi->callback_timer, ESDI_TIME);
esdi->data_pos = 0;
break;
@ -559,7 +557,7 @@ static void esdi_callback(void *p)
if (!(esdi->basic_ctrl & CTRL_DMA_ENA))
{
// pclog("DMA not enabled\n");
esdi->callback = ESDI_TIME;
timer_set_delay_u64(&esdi->callback_timer, ESDI_TIME);
return;
}
while (esdi->sector_pos < esdi->sector_count)
@ -572,7 +570,7 @@ static void esdi_callback(void *p)
if (val == DMA_NODATA)
{
// pclog("DMA out of data\n");
esdi->callback = ESDI_TIME;
timer_set_delay_u64(&esdi->callback_timer, ESDI_TIME);
return;
}
@ -591,7 +589,7 @@ static void esdi_callback(void *p)
esdi->status = STATUS_CMD_IN_PROGRESS;
esdi->cmd_state = 2;
esdi->callback = ESDI_TIME;
timer_set_delay_u64(&esdi->callback_timer, ESDI_TIME);
break;
case 2:
@ -739,7 +737,7 @@ static void esdi_callback(void *p)
esdi_set_irq(esdi);
esdi->cmd_state = 1;
esdi->callback = ESDI_TIME;
timer_set_delay_u64(&esdi->callback_timer, ESDI_TIME);
esdi->data_pos = 0;
break;
@ -747,7 +745,7 @@ static void esdi_callback(void *p)
if (!(esdi->basic_ctrl & CTRL_DMA_ENA))
{
// pclog("DMA not enabled\n");
esdi->callback = ESDI_TIME;
timer_set_delay_u64(&esdi->callback_timer, ESDI_TIME);
return;
}
while (esdi->sector_pos < esdi->sector_count)
@ -762,7 +760,7 @@ static void esdi_callback(void *p)
if (val == DMA_NODATA)
{
// pclog("DMA out of data\n");
esdi->callback = ESDI_TIME;
timer_set_delay_u64(&esdi->callback_timer, ESDI_TIME);
return;
}
@ -774,7 +772,7 @@ static void esdi_callback(void *p)
esdi->status = STATUS_CMD_IN_PROGRESS;
esdi->cmd_state = 2;
esdi->callback = ESDI_TIME;
timer_set_delay_u64(&esdi->callback_timer, ESDI_TIME);
break;
case 2:
@ -803,7 +801,7 @@ static void esdi_callback(void *p)
esdi_set_irq(esdi);
esdi->cmd_state = 1;
esdi->callback = ESDI_TIME;
timer_set_delay_u64(&esdi->callback_timer, ESDI_TIME);
esdi->data_pos = 0;
break;
@ -811,7 +809,7 @@ static void esdi_callback(void *p)
if (!(esdi->basic_ctrl & CTRL_DMA_ENA))
{
// pclog("DMA not enabled\n");
esdi->callback = ESDI_TIME;
timer_set_delay_u64(&esdi->callback_timer, ESDI_TIME);
return;
}
while (esdi->sector_pos < esdi->sector_count)
@ -824,7 +822,7 @@ static void esdi_callback(void *p)
if (val == DMA_NODATA)
{
// pclog("DMA out of data\n");
esdi->callback = ESDI_TIME;
timer_set_delay_u64(&esdi->callback_timer, ESDI_TIME);
return;
}
@ -837,7 +835,7 @@ static void esdi_callback(void *p)
esdi->status = STATUS_CMD_IN_PROGRESS;
esdi->cmd_state = 2;
esdi->callback = ESDI_TIME;
timer_set_delay_u64(&esdi->callback_timer, ESDI_TIME);
break;
case 2:
@ -917,7 +915,7 @@ static void *esdi_init()
hdd_load(&esdi->hdd_file[0], 0, ide_fn[0]);
hdd_load(&esdi->hdd_file[1], 1, ide_fn[1]);
timer_add(esdi_callback, &esdi->callback, &esdi->callback, esdi);
timer_add(&esdi->callback_timer, esdi_callback, esdi, 0);
mca_add(esdi_mca_read, esdi_mca_write, esdi);
@ -925,7 +923,7 @@ static void *esdi_init()
esdi->pos_regs[1] = 0xdd;
esdi->in_reset = 1;
esdi->callback = ESDI_TIME * 50;
timer_set_delay_u64(&esdi->callback_timer, ESDI_TIME * 50);
esdi->status = STATUS_BUSY;
return esdi;

View file

@ -2,6 +2,8 @@
#include <stdint.h>
#include <string.h>
#include "timer.h"
#ifdef ABS
#undef ABS
#endif
@ -296,7 +298,7 @@ typedef struct PIT_nr
typedef struct PIT
{
uint32_t l[3];
int c[3];
pc_timer_t timer[3];
uint8_t m[3];
uint8_t ctrl,ctrls[3];
int wp,rm[3],wm[3];
@ -378,7 +380,6 @@ PIC pic,pic2;
extern int pic_intpending;
int disctime;
char discfns[2][256];
int driveempty[2];
@ -527,10 +528,10 @@ extern int changeframecount;
/*Sound*/
int ppispeakon;
float CGACONST;
float MDACONST;
float VGACONST1,VGACONST2;
float RTCCONST;
extern uint64_t CGACONST;
extern uint64_t MDACONST;
extern uint64_t VGACONST1,VGACONST2;
extern uint64_t RTCCONST;
int gated,speakval,speakon;

View file

@ -1,4 +1,4 @@
#define IDE_TIME (5 * 100 * (1 << TIMER_SHIFT))
#define IDE_TIME (10 * TIMER_USEC)
#define _LARGEFILE_SOURCE
#define _LARGEFILE64_SOURCE
@ -98,7 +98,7 @@ int (*ide_bus_master_read_data)(int channel, uint8_t *data, int size);
int (*ide_bus_master_write_data)(int channel, uint8_t *data, int size);
void (*ide_bus_master_set_irq)(int channel);
int idecallback[2] = {0, 0};
pc_timer_t ide_timer[2];
int cur_ide[2];
@ -268,7 +268,6 @@ void resetide(void)
ide_drives[d].board = (d & 2) ? 1 : 0;
}
idecallback[0]=idecallback[1]=0;
if (hdd_controller_current_is_ide())
{
for (d = 0; d < 4; d++)
@ -324,12 +323,10 @@ void writeidew(int ide_board, uint16_t val)
{
ide->pos=0;
ide->atastat = BUSY_STAT;
timer_process();
if (ide->command == WIN_WRITE_MULTIPLE)
callbackide(ide_board);
else
idecallback[ide_board] = 6 * IDE_TIME;
timer_update_outstanding();
timer_set_delay_u64(&ide_timer[ide_board], 6 * IDE_TIME);
}
}
}
@ -428,8 +425,7 @@ void writeide(int ide_board, uint16_t addr, uint8_t val)
if (IDE_DRIVE_IS_CDROM(ide_other))
ide_other->cylinder=0xEB14;
idecallback[ide_board] = 0;
timer_update_outstanding();
timer_disable(&ide_timer[ide_board]);
return;
}
@ -460,18 +456,14 @@ void writeide(int ide_board, uint16_t addr, uint8_t val)
case WIN_SRST: /* ATAPI Device Reset */
if (IDE_DRIVE_IS_CDROM(ide)) ide->atastat = BUSY_STAT;
else ide->atastat = READY_STAT;
timer_process();
idecallback[ide_board]=100*IDE_TIME;
timer_update_outstanding();
timer_set_delay_u64(&ide_timer[ide_board], 100*IDE_TIME);
return;
case WIN_RESTORE:
case WIN_SEEK:
// pclog("WIN_RESTORE start\n");
ide->atastat = READY_STAT;
timer_process();
idecallback[ide_board]=100*IDE_TIME;
timer_update_outstanding();
timer_set_delay_u64(&ide_timer[ide_board], 100*IDE_TIME);
return;
case WIN_READ_MULTIPLE:
@ -495,9 +487,7 @@ void writeide(int ide_board, uint16_t addr, uint8_t val)
else pclog("Read %i sectors from sector %i cylinder %i head %i %i\n",ide->secount,ide->sector,ide->cylinder,ide->head,ins);
#endif
ide->atastat = BUSY_STAT;
timer_process();
idecallback[ide_board]=200*IDE_TIME;
timer_update_outstanding();
timer_set_delay_u64(&ide_timer[ide_board], 200*IDE_TIME);
ide->do_initial_read = 1;
return;
@ -530,9 +520,7 @@ void writeide(int ide_board, uint16_t addr, uint8_t val)
else pclog("Write %i sectors to sector %i cylinder %i head %i\n",ide->secount,ide->sector,ide->cylinder,ide->head);
#endif
ide->atastat = BUSY_STAT;
timer_process();
idecallback[ide_board]=200*IDE_TIME;
timer_update_outstanding();
timer_set_delay_u64(&ide_timer[ide_board], 200*IDE_TIME);
return;
case WIN_VERIFY:
@ -542,9 +530,7 @@ void writeide(int ide_board, uint16_t addr, uint8_t val)
else pclog("Read verify %i sectors from sector %i cylinder %i head %i\n",ide->secount,ide->sector,ide->cylinder,ide->head);
#endif
ide->atastat = BUSY_STAT;
timer_process();
idecallback[ide_board]=200*IDE_TIME;
timer_update_outstanding();
timer_set_delay_u64(&ide_timer[ide_board], 200*IDE_TIME);
return;
case WIN_FORMAT:
@ -556,18 +542,14 @@ void writeide(int ide_board, uint16_t addr, uint8_t val)
case WIN_SPECIFY: /* Initialize Drive Parameters */
ide->atastat = BUSY_STAT;
timer_process();
idecallback[ide_board]=30*IDE_TIME;
timer_update_outstanding();
timer_set_delay_u64(&ide_timer[ide_board], 30*IDE_TIME);
// pclog("SPECIFY\n");
// output=1;
return;
case WIN_DRIVE_DIAGNOSTICS: /* Execute Drive Diagnostics */
ide->atastat = BUSY_STAT;
timer_process();
idecallback[ide_board]=200*IDE_TIME;
timer_update_outstanding();
timer_set_delay_u64(&ide_timer[ide_board], 200*IDE_TIME);
return;
case WIN_PIDENTIFY: /* Identify Packet Device */
@ -576,10 +558,8 @@ void writeide(int ide_board, uint16_t addr, uint8_t val)
case WIN_SETIDLE1: /* Idle */
case WIN_CHECK_POWER_MODE:
ide->atastat = BUSY_STAT;
timer_process();
callbackide(ide_board);
// idecallback[ide_board]=200*IDE_TIME;
timer_update_outstanding();
return;
case WIN_IDENTIFY: /* Identify Device */
@ -587,9 +567,7 @@ void writeide(int ide_board, uint16_t addr, uint8_t val)
// output=3;
// timetolive=500;
ide->atastat = BUSY_STAT;
timer_process();
idecallback[ide_board]=200*IDE_TIME;
timer_update_outstanding();
timer_set_delay_u64(&ide_timer[ide_board], 200*IDE_TIME);
return;
case WIN_PACKETCMD: /* ATAPI Packet */
@ -597,9 +575,7 @@ void writeide(int ide_board, uint16_t addr, uint8_t val)
atapi_command_start(&ide->atapi, ide->cylprecomp);
ide->atastat = BUSY_STAT;
timer_process();
idecallback[ide_board] = IDE_TIME;
timer_update_outstanding();
timer_set_delay_u64(&ide_timer[ide_board], IDE_TIME);
ide->atapi.bus_state = 0;
return;
@ -618,9 +594,7 @@ void writeide(int ide_board, uint16_t addr, uint8_t val)
case 0x3F6: /* Device control */
if ((ide->fdisk&4) && !(val&4) && (ide->type != IDE_NONE || ide_other->type != IDE_NONE))
{
timer_process();
idecallback[ide_board]=500*IDE_TIME;
timer_update_outstanding();
timer_set_delay_u64(&ide_timer[ide_board], 500*IDE_TIME);
ide->reset = ide_other->reset = 1;
ide->atastat = ide_other->atastat = BUSY_STAT;
// pclog("IDE Reset %i\n", ide_board);
@ -628,9 +602,7 @@ void writeide(int ide_board, uint16_t addr, uint8_t val)
if (val & 4)
{
/*Drive held in reset*/
timer_process();
idecallback[ide_board] = 0;
timer_update_outstanding();
timer_disable(&ide_timer[ide_board]);
ide->atastat = ide_other->atastat = BUSY_STAT;
}
ide->fdisk = ide_other->fdisk = val;
@ -794,12 +766,10 @@ uint16_t readidew(int ide_board)
{
ide_next_sector(ide);
ide->atastat = BUSY_STAT;
timer_process();
if (ide->command == WIN_READ_MULTIPLE)
callbackide(ide_board);
else
idecallback[ide_board] = 6 * IDE_TIME;
timer_update_outstanding();
timer_set_delay_u64(&ide_timer[ide_board], 6 * IDE_TIME);
// pclog("set idecallback\n");
// callbackide(ide_board);
}
@ -936,7 +906,7 @@ void callbackide(int ide_board)
if (ide_bus_master_read_data)
{
if (ide_bus_master_read_data(ide_board, &ide->sector_buffer[ide->sector_pos*512], 512))
idecallback[ide_board]=6*IDE_TIME; /*DMA not performed, try again later*/
timer_set_delay_u64(&ide_timer[ide_board], 6*IDE_TIME); /*DMA not performed, try again later*/
else
{
/*DMA successful*/
@ -948,7 +918,7 @@ void callbackide(int ide_board)
{
ide_next_sector(ide);
ide->atastat = BUSY_STAT;
idecallback[ide_board]=6*IDE_TIME;
timer_set_delay_u64(&ide_timer[ide_board], 6*IDE_TIME);
}
else
{
@ -1014,7 +984,7 @@ void callbackide(int ide_board)
if (ide_bus_master_write_data)
{
if (ide_bus_master_write_data(ide_board, (uint8_t *)ide->buffer, 512))
idecallback[ide_board]=6*IDE_TIME; /*DMA not performed, try again later*/
timer_set_delay_u64(&ide_timer[ide_board], 6*IDE_TIME); /*DMA not performed, try again later*/
else
{
/*DMA successful*/
@ -1027,7 +997,7 @@ void callbackide(int ide_board)
{
ide_next_sector(ide);
ide->atastat = BUSY_STAT;
idecallback[ide_board]=6*IDE_TIME;
timer_set_delay_u64(&ide_timer[ide_board], 6*IDE_TIME);
}
else
{
@ -1201,13 +1171,11 @@ abort_cmd:
void ide_callback_pri()
{
idecallback[0] = 0;
callbackide(0);
}
void ide_callback_sec()
{
idecallback[1] = 0;
callbackide(1);
}
@ -1292,8 +1260,8 @@ static void *ide_init()
ide_pri_enable();
ide_sec_enable();
timer_add(ide_callback_pri, &idecallback[0], &idecallback[0], NULL);
timer_add(ide_callback_sec, &idecallback[1], &idecallback[1], NULL);
timer_add(&ide_timer[0], ide_callback_pri, NULL, 0);
timer_add(&ide_timer[1], ide_callback_sec, NULL, 0);
return (void *)-1;
}

View file

@ -2,6 +2,7 @@
#define __IDE__
#include "device.h"
#include "timer.h"
struct IDE;
@ -26,7 +27,7 @@ extern void (*ide_bus_master_set_irq)(int channel);
extern int ideboard;
extern int idecallback[2];
extern pc_timer_t ide_timer[2];
extern char ide_fn[7][512];

View file

@ -4,7 +4,7 @@
#include "scsi.h"
#include "timer.h"
#define IDE_TIME (5 * 100 * (1 << TIMER_SHIFT))
#define IDE_TIME (100 * TIMER_USEC)
#define ATAPI_STATE_IDLE 0
#define ATAPI_STATE_COMMAND 1
@ -35,7 +35,7 @@ void atapi_data_write(atapi_device_t *atapi_dev, uint16_t val)
if (atapi_dev->command_pos >= 12)
{
atapi_dev->state = ATAPI_STATE_GOT_COMMAND;
idecallback[atapi_dev->board] = 6 * IDE_TIME;
timer_set_delay_u64(&ide_timer[atapi_dev->board], 6 * IDE_TIME);
}
break;
@ -47,7 +47,7 @@ void atapi_data_write(atapi_device_t *atapi_dev, uint16_t val)
{
atapi_dev->bus_state = 0;
atapi_dev->state = ATAPI_STATE_WRITE_DATA;
idecallback[atapi_dev->board] = 6 * IDE_TIME;
timer_set_delay_u64(&ide_timer[atapi_dev->board], 6 * IDE_TIME);
}
break;
}
@ -73,7 +73,7 @@ uint16_t atapi_data_read(atapi_device_t *atapi_dev)
if (atapi_dev->data_read_pos >= atapi_dev->data_write_pos)
{
atapi_dev->state = ATAPI_STATE_NEXT_PHASE;
idecallback[atapi_dev->board] = 6*IDE_TIME;
timer_set_delay_u64(&ide_timer[atapi_dev->board], 6*IDE_TIME);
}
break;
}
@ -199,7 +199,7 @@ void atapi_process_packet(atapi_device_t *atapi_dev)
{
// pclog("SEND_COMMAND timed out %x\n", scsi_bus_read(&atapi_dev->bus));
atapi_dev->state = ATAPI_STATE_NEXT_PHASE;
idecallback[atapi_dev->board] = 6 * IDE_TIME;
timer_set_delay_u64(&ide_timer[atapi_dev->board], 6 * IDE_TIME);
break;
}
@ -209,7 +209,7 @@ void atapi_process_packet(atapi_device_t *atapi_dev)
{
// pclog("SEND_COMMAND - bus state changed %x\n", bus_state);
atapi_dev->state = ATAPI_STATE_NEXT_PHASE;
idecallback[atapi_dev->board] = 6 * IDE_TIME;
timer_set_delay_u64(&ide_timer[atapi_dev->board], 6 * IDE_TIME);
break;
}
@ -261,20 +261,20 @@ void atapi_process_packet(atapi_device_t *atapi_dev)
if (ide_bus_master_write_data(atapi_dev->board, atapi_dev->data, atapi_dev->data_read_pos))
{
atapi_dev->state = ATAPI_STATE_RETRY_WRITE_DMA;
idecallback[atapi_dev->board] = 1*IDE_TIME;
timer_set_delay_u64(&ide_timer[atapi_dev->board], 1*IDE_TIME);
}
else
{
atapi_dev->data_write_pos = atapi_dev->data_read_pos;
atapi_dev->bus_state = 0;
atapi_dev->state = ATAPI_STATE_WRITE_DATA;
idecallback[atapi_dev->board] = 6 * IDE_TIME;
timer_set_delay_u64(&ide_timer[atapi_dev->board], 6 * IDE_TIME);
}
}
else
{
atapi_dev->state = ATAPI_STATE_RETRY_WRITE_DMA;
idecallback[atapi_dev->board] = 1*IDE_TIME;
timer_set_delay_u64(&ide_timer[atapi_dev->board], 1*IDE_TIME);
}
}
else
@ -312,7 +312,7 @@ void atapi_process_packet(atapi_device_t *atapi_dev)
break;
}
}
idecallback[atapi_dev->board] = 6 * IDE_TIME;
timer_set_delay_u64(&ide_timer[atapi_dev->board], 6 * IDE_TIME);
}
break;
@ -344,7 +344,7 @@ void atapi_process_packet(atapi_device_t *atapi_dev)
break;
}
}
idecallback[atapi_dev->board] = 6 * IDE_TIME;
timer_set_delay_u64(&ide_timer[atapi_dev->board], 6 * IDE_TIME);
}
break;
@ -387,7 +387,7 @@ void atapi_process_packet(atapi_device_t *atapi_dev)
break;
}
}
idecallback[atapi_dev->board] = 6 * IDE_TIME;
timer_set_delay_u64(&ide_timer[atapi_dev->board], 6 * IDE_TIME);
}
break;
@ -433,18 +433,18 @@ void atapi_process_packet(atapi_device_t *atapi_dev)
if (ide_bus_master_read_data(atapi_dev->board, atapi_dev->data, atapi_dev->data_write_pos))
{
atapi_dev->state = ATAPI_STATE_RETRY_READ_DMA;
idecallback[atapi_dev->board] = 1*IDE_TIME;
timer_set_delay_u64(&ide_timer[atapi_dev->board], 1*IDE_TIME);
}
else
{
atapi_dev->state = ATAPI_STATE_NEXT_PHASE;
idecallback[atapi_dev->board] = 1*IDE_TIME;
timer_set_delay_u64(&ide_timer[atapi_dev->board], 1*IDE_TIME);
}
}
else
{
atapi_dev->state = ATAPI_STATE_RETRY_READ_DMA;
idecallback[atapi_dev->board] = 1*IDE_TIME;
timer_set_delay_u64(&ide_timer[atapi_dev->board], 1*IDE_TIME);
}
}
else
@ -490,7 +490,7 @@ void atapi_process_packet(atapi_device_t *atapi_dev)
}
atapi_dev->state = ATAPI_STATE_NEXT_PHASE;
idecallback[atapi_dev->board] = 1 * IDE_TIME;
timer_set_delay_u64(&ide_timer[atapi_dev->board], 1 * IDE_TIME);
}
break;
@ -529,7 +529,7 @@ void atapi_process_packet(atapi_device_t *atapi_dev)
ide_irq_raise(atapi_dev->ide);
}
else
idecallback[atapi_dev->board] = 6 * IDE_TIME;
timer_set_delay_u64(&ide_timer[atapi_dev->board], 6 * IDE_TIME);
}
break;
@ -537,12 +537,12 @@ void atapi_process_packet(atapi_device_t *atapi_dev)
{
if (ide_bus_master_read_data(atapi_dev->board, atapi_dev->data, atapi_dev->data_write_pos))
{
idecallback[atapi_dev->board] = 1*IDE_TIME;
timer_set_delay_u64(&ide_timer[atapi_dev->board], 1*IDE_TIME);
}
else
{
atapi_dev->state = ATAPI_STATE_NEXT_PHASE;
idecallback[atapi_dev->board] = 6*IDE_TIME;
timer_set_delay_u64(&ide_timer[atapi_dev->board], 6*IDE_TIME);
}
}
break;
@ -551,13 +551,13 @@ void atapi_process_packet(atapi_device_t *atapi_dev)
{
if (ide_bus_master_write_data(atapi_dev->board, atapi_dev->data, atapi_dev->data_read_pos))
{
idecallback[atapi_dev->board] = 1*IDE_TIME;
timer_set_delay_u64(&ide_timer[atapi_dev->board], 1*IDE_TIME);
}
else
{
atapi_dev->bus_state = 0;
atapi_dev->state = ATAPI_STATE_WRITE_DATA;
idecallback[atapi_dev->board] = 6 * IDE_TIME;
timer_set_delay_u64(&ide_timer[atapi_dev->board], 6 * IDE_TIME);
}
}
break;

View file

@ -45,11 +45,10 @@ void batman_brdconfig_write(uint16_t port, uint8_t val, void *p)
}
static uint16_t batman_timer_latch;
static int batman_timer = 0;
static pc_timer_t batman_timer;
static void batman_timer_over(void *p)
{
batman_timer = 0;
}
static void batman_timer_write(uint16_t addr, uint8_t val, void *p)
@ -58,7 +57,7 @@ static void batman_timer_write(uint16_t addr, uint8_t val, void *p)
batman_timer_latch = (batman_timer_latch & 0xff) | (val << 8);
else
batman_timer_latch = (batman_timer_latch & 0xff00) | val;
batman_timer = batman_timer_latch * TIMER_USEC;
timer_set_delay_u64(&batman_timer, batman_timer_latch * TIMER_USEC);
}
static uint8_t batman_timer_read(uint16_t addr, void *p)
@ -67,12 +66,7 @@ static uint8_t batman_timer_read(uint16_t addr, void *p)
cycles -= (int)PITCONST;
timer_clock();
if (batman_timer < 0)
return 0;
batman_timer_latch = batman_timer / TIMER_USEC;
batman_timer_latch = timer_get_remaining_us(&batman_timer);
if (addr & 1)
return batman_timer_latch >> 8;
@ -87,7 +81,7 @@ void intel_batman_init()
io_sethandler(0x0078, 0x0002, batman_timer_read, NULL, NULL, batman_timer_write, NULL, NULL, NULL);
io_sethandler(0x0092, 0x0001, batman_brdconfig, NULL, NULL, batman_brdconfig_write, NULL, NULL, NULL);
batman_port_92 = 0;
timer_add(batman_timer_over, &batman_timer, &batman_timer, NULL);
timer_add(&batman_timer, batman_timer_over, NULL, 0);
}

View file

@ -30,13 +30,13 @@
typedef struct
{
int poll_time;
pc_timer_t poll_timer;
int poll_left;
int poll_clock;
uint64_t poll_data;
int poll_mode;
int trigger_time;
pc_timer_t trigger_timer;
int data_mode;
} sw_data;
@ -44,33 +44,22 @@ static void sw_timer_over(void *p)
{
sw_data *sw = (sw_data *)p;
while (sw->poll_time <= 0 && sw->poll_left)
{
sw->poll_clock = !sw->poll_clock;
sw->poll_clock = !sw->poll_clock;
if (sw->poll_clock)
{
sw->poll_data >>= (sw->poll_mode ? 3 : 1);
sw->poll_left--;
}
if (sw->poll_left == 1 && !sw->poll_clock)
sw->poll_time += TIMER_USEC * 160;
else if (sw->poll_left)
sw->poll_time += TIMER_USEC * 5;
else
sw->poll_time = 0;
if (sw->poll_clock)
{
sw->poll_data >>= (sw->poll_mode ? 3 : 1);
sw->poll_left--;
}
if (!sw->poll_left)
sw->poll_time = 0;
if (sw->poll_left == 1 && !sw->poll_clock)
timer_advance_u64(&sw->poll_timer, TIMER_USEC * 160);
else if (sw->poll_left)
timer_advance_u64(&sw->poll_timer, TIMER_USEC * 5);
}
static void sw_trigger_timer_over(void *p)
{
sw_data *sw = (sw_data *)p;
sw->trigger_time = 0;
}
static int sw_parity(uint16_t data)
@ -91,8 +80,8 @@ static void *sw_init()
sw_data *sw = (sw_data *)malloc(sizeof(sw_data));
memset(sw, 0, sizeof(sw_data));
timer_add(sw_timer_over, &sw->poll_time, &sw->poll_time, sw);
timer_add(sw_trigger_timer_over, &sw->trigger_time, &sw->trigger_time, sw);
timer_add(&sw->poll_timer, sw_timer_over, sw, 0);
timer_add(&sw->trigger_timer, sw_trigger_timer_over, sw, 0);
return sw;
}
@ -112,7 +101,7 @@ static uint8_t sw_read(void *p)
if (!JOYSTICK_PRESENT(0))
return 0xff;
if (sw->poll_time)
if (timer_is_enabled(&sw->poll_timer))
{
if (sw->poll_clock)
temp |= 0x10;
@ -135,7 +124,7 @@ static uint8_t sw_read(void *p)
static void sw_write(void *p)
{
sw_data *sw = (sw_data *)p;
int time_since_last = sw->trigger_time / TIMER_USEC;
int time_since_last = timer_get_remaining_us(&sw->trigger_timer);
if (!JOYSTICK_PRESENT(0))
return;
@ -145,7 +134,7 @@ static void sw_write(void *p)
if (!sw->poll_left)
{
sw->poll_clock = 1;
sw->poll_time = TIMER_USEC * 50;
timer_set_delay_u64(&sw->poll_timer, TIMER_USEC * 50);
if (time_since_last > 9900 && time_since_last < 9940)
{
@ -214,9 +203,7 @@ static void sw_write(void *p)
}
}
sw->trigger_time = 0;
timer_update_outstanding();
timer_disable(&sw->trigger_timer);
}
static int sw_read_axis(void *p, int axis)
@ -231,7 +218,7 @@ static void sw_a0_over(void *p)
{
sw_data *sw = (sw_data *)p;
sw->trigger_time = TIMER_USEC * 10000;
timer_set_delay_u64(&sw->trigger_timer, TIMER_USEC * 10000);
}
joystick_if_t joystick_sw_pad =

View file

@ -26,6 +26,8 @@ struct
uint8_t key_waiting;
uint8_t pa;
uint8_t pb;
pc_timer_t send_delay_timer;
} keyboard_amstrad;
static uint8_t key_queue[16];
@ -35,7 +37,7 @@ static uint8_t amstrad_systemstat_1, amstrad_systemstat_2;
void keyboard_amstrad_poll()
{
keybsenddelay += (1000 * TIMER_USEC);
timer_advance_u64(&keyboard_amstrad.send_delay_timer, (1000 * TIMER_USEC));
if (keyboard_amstrad.wantirq)
{
keyboard_amstrad.wantirq = 0;
@ -77,7 +79,6 @@ void keyboard_amstrad_write(uint16_t port, uint8_t val, void *priv)
ppi.pb = val;
timer_process();
timer_update_outstanding();
speaker_update();
speaker_gated = val & 1;
@ -174,5 +175,5 @@ void keyboard_amstrad_init()
keyboard_send = keyboard_amstrad_adddata;
keyboard_poll = keyboard_amstrad_poll;
timer_add(keyboard_amstrad_poll, &keybsenddelay, TIMER_ALWAYS_ENABLED, NULL);
timer_add(&keyboard_amstrad.send_delay_timer, keyboard_amstrad_poll, NULL, 1);
}

View file

@ -48,10 +48,12 @@ struct
void (*mouse_write)(uint8_t val, void *p);
void *mouse_p;
int refresh_time;
pc_timer_t refresh_timer;
int refresh;
int is_ps2;
pc_timer_t send_delay_timer;
} keyboard_at;
static uint8_t key_ctrl_queue[16];
@ -65,7 +67,7 @@ int mouse_queue_start = 0, mouse_queue_end = 0;
void keyboard_at_poll()
{
keybsenddelay += (100 * TIMER_USEC);
timer_advance_u64(&keyboard_at.send_delay_timer, (100 * TIMER_USEC));
if (keyboard_at.out_new != -1 && !keyboard_at.last_irq)
{
@ -336,9 +338,6 @@ void keyboard_at_write(uint16_t port, uint8_t val, void *priv)
case 0x61:
ppi.pb = val;
timer_process();
timer_update_outstanding();
speaker_update();
speaker_gated = val & 1;
speaker_enable = val & 2;
@ -626,7 +625,7 @@ void keyboard_at_reset()
static void at_refresh(void *p)
{
keyboard_at.refresh = !keyboard_at.refresh;
keyboard_at.refresh_time += PS2_REFRESH_TIME;
timer_advance_u64(&keyboard_at.refresh_timer, PS2_REFRESH_TIME);
}
void keyboard_at_init()
@ -641,7 +640,7 @@ void keyboard_at_init()
keyboard_at.mouse_p = NULL;
keyboard_at.is_ps2 = 0;
timer_add(keyboard_at_poll, &keybsenddelay, TIMER_ALWAYS_ENABLED, NULL);
timer_add(&keyboard_at.send_delay_timer, keyboard_at_poll, NULL, 1);
}
void keyboard_at_set_mouse(void (*mouse_write)(uint8_t val, void *p), void *p)
@ -652,6 +651,6 @@ void keyboard_at_set_mouse(void (*mouse_write)(uint8_t val, void *p), void *p)
void keyboard_at_init_ps2()
{
timer_add(at_refresh, &keyboard_at.refresh_time, TIMER_ALWAYS_ENABLED, NULL);
timer_add(&keyboard_at.refresh_timer, at_refresh, NULL, 1);
keyboard_at.is_ps2 = 1;
}

View file

@ -34,6 +34,8 @@ struct
uint8_t params[16];
int mouse_mode;
pc_timer_t send_delay_timer;
} keyboard_olim24;
static uint8_t key_queue[16];
@ -43,7 +45,7 @@ static uint8_t mouse_scancodes[7];
void keyboard_olim24_poll()
{
keybsenddelay += (1000 * TIMER_USEC);
timer_advance_u64(&keyboard_olim24.send_delay_timer, (1000 * TIMER_USEC));
//pclog("poll %i\n", keyboard_olim24.wantirq);
if (keyboard_olim24.wantirq)
{
@ -147,7 +149,6 @@ void keyboard_olim24_write(uint16_t port, uint8_t val, void *priv)
ppi.pb = val;
timer_process();
timer_update_outstanding();
speaker_update();
speaker_gated = val & 1;
@ -345,5 +346,5 @@ void keyboard_olim24_init()
keyboard_send = keyboard_olim24_adddata;
keyboard_poll = keyboard_olim24_poll;
timer_add(keyboard_olim24_poll, &keybsenddelay, TIMER_ALWAYS_ENABLED, NULL);
timer_add(&keyboard_olim24.send_delay_timer, keyboard_olim24_poll, NULL, 1);
}

View file

@ -32,6 +32,8 @@ struct
uint8_t pa;
uint8_t pb;
pc_timer_t send_delay_timer;
} keyboard_pcjr;
static uint8_t key_queue[16];
@ -39,8 +41,7 @@ static int key_queue_start = 0, key_queue_end = 0;
void keyboard_pcjr_poll()
{
keybsenddelay += (220 * TIMER_USEC);
timer_advance_u64(&keyboard_pcjr.send_delay_timer, (220 * TIMER_USEC));
if (key_queue_start != key_queue_end && !keyboard_pcjr.serial_pos && !keyboard_pcjr.latched)
{
@ -127,7 +128,6 @@ void keyboard_pcjr_write(uint16_t port, uint8_t val, void *priv)
keyboard_pcjr.pb = val;
timer_process();
timer_update_outstanding();
speaker_update();
speaker_gated = val & 1;
@ -205,5 +205,5 @@ void keyboard_pcjr_init()
keyboard_send = keyboard_pcjr_adddata;
keyboard_poll = keyboard_pcjr_poll;
timer_add(keyboard_pcjr_poll, &keybsenddelay, TIMER_ALWAYS_ENABLED, NULL);
timer_add(&keyboard_pcjr.send_delay_timer, keyboard_pcjr_poll, NULL, 1);
}

View file

@ -36,6 +36,8 @@ struct
int tandy;
int pb2_turbo;
pc_timer_t send_delay_timer;
} keyboard_xt;
static uint8_t key_queue[16];
@ -43,7 +45,7 @@ static int key_queue_start = 0, key_queue_end = 0;
void keyboard_xt_poll()
{
keybsenddelay += (1000 * TIMER_USEC);
timer_advance_u64(&keyboard_xt.send_delay_timer, (1000 * TIMER_USEC));
if (!(keyboard_xt.pb & 0x40) && romset != ROM_TANDY)
return;
if (keyboard_xt.wantirq)
@ -124,7 +126,6 @@ void keyboard_xt_write(uint16_t port, uint8_t val, void *priv)
ppi.pb = val;
timer_process();
timer_update_outstanding();
if (keyboard_xt.pb2_turbo)
cpu_set_turbo((val & 4) ? 0 : 1);
@ -236,7 +237,7 @@ void keyboard_xt_init()
keyboard_xt.tandy = 0;
keyboard_xt.pb2_turbo = (romset == ROM_GENXT || romset == ROM_DTKXT || romset == ROM_AMIXT || romset == ROM_PXXT) ? 1 : 0;
timer_add(keyboard_xt_poll, &keybsenddelay, TIMER_ALWAYS_ENABLED, NULL);
timer_add(&keyboard_xt.send_delay_timer, keyboard_xt_poll, NULL, 1);
}
void keyboard_tandy_init()
@ -248,5 +249,5 @@ void keyboard_tandy_init()
keyboard_poll = keyboard_xt_poll;
keyboard_xt.tandy = (romset != ROM_TANDY) ? 1 : 0;
timer_add(keyboard_xt_poll, &keybsenddelay, TIMER_ALWAYS_ENABLED, NULL);
timer_add(&keyboard_xt.send_delay_timer, keyboard_xt_poll, NULL, 1);
}

View file

@ -30,8 +30,6 @@ static void dac_write_data(uint8_t val, void *p)
{
lpt_dac_t *lpt_dac = (lpt_dac_t *)p;
timer_clock();
if (lpt_dac->is_stereo)
{
if (lpt_dac->channel)

View file

@ -12,7 +12,7 @@ typedef struct dss_t
uint8_t dac_val;
int time;
pc_timer_t timer;
int16_t buffer[MAXSOUNDBUFLEN];
int pos;
@ -29,8 +29,6 @@ static void dss_write_data(uint8_t val, void *p)
{
dss_t *dss = (dss_t *)p;
timer_clock();
if ((dss->write_idx - dss->read_idx) < 16)
{
dss->fifo[dss->write_idx & 15] = val;
@ -82,7 +80,7 @@ static void dss_callback(void *p)
dss->read_idx++;
}
dss->time += (TIMER_USEC * (1000000.0 / 7000.0));
timer_advance_u64(&dss->timer, (TIMER_USEC * (1000000.0 / 7000.0)));
}
static void *dss_init()
@ -91,7 +89,7 @@ static void *dss_init()
memset(dss, 0, sizeof(dss_t));
sound_add_handler(dss_get_buffer, dss);
timer_add(dss_callback, &dss->time, TIMER_ALWAYS_ENABLED, dss);
timer_add(&dss->timer, dss_callback, dss, 1);
return dss;
}

View file

@ -70,7 +70,7 @@ typedef struct mfm_t
uint16_t buffer[256];
int irqstat;
int callback;
pc_timer_t callback_timer;
mfm_drive_t drives[2];
} mfm_t;
@ -215,18 +215,14 @@ void mfm_write(uint16_t port, uint8_t val, void *p)
// pclog("Restore\n");
mfm->command &= ~0x0f; /*Mask off step rate*/
mfm->status = STAT_BUSY;
timer_clock();
mfm->callback = 200*IDE_TIME;
timer_update_outstanding();
timer_set_delay_u64(&mfm->callback_timer, 200*IDE_TIME);
break;
case CMD_SEEK:
// pclog("Seek to cylinder %i\n", mfm->cylinder);
mfm->command &= ~0x0f; /*Mask off step rate*/
mfm->status = STAT_BUSY;
timer_clock();
mfm->callback = 200*IDE_TIME;
timer_update_outstanding();
timer_set_delay_u64(&mfm->callback_timer, 200*IDE_TIME);
break;
default:
@ -239,9 +235,7 @@ void mfm_write(uint16_t port, uint8_t val, void *p)
if (val & 2)
fatal("Read with ECC\n");
mfm->status = STAT_BUSY;
timer_clock();
mfm->callback = 200*IDE_TIME;
timer_update_outstanding();
timer_set_delay_u64(&mfm->callback_timer, 200*IDE_TIME);
break;
case CMD_WRITE: case CMD_WRITE+1:
@ -258,9 +252,7 @@ void mfm_write(uint16_t port, uint8_t val, void *p)
// pclog("Read verify %i sectors from sector %i cylinder %i head %i\n",mfm->secount,mfm->sector,mfm->cylinder,mfm->head);
mfm->command &= ~1;
mfm->status = STAT_BUSY;
timer_clock();
mfm->callback = 200 * IDE_TIME;
timer_update_outstanding();
timer_set_delay_u64(&mfm->callback_timer, 200 * IDE_TIME);
break;
case CMD_FORMAT:
@ -271,24 +263,18 @@ void mfm_write(uint16_t port, uint8_t val, void *p)
case CMD_SET_PARAMETERS: /* Initialize Drive Parameters */
mfm->status = STAT_BUSY;
timer_clock();
mfm->callback = 30*IDE_TIME;
timer_update_outstanding();
timer_set_delay_u64(&mfm->callback_timer, 30*IDE_TIME);
break;
case CMD_DIAGNOSE: /* Execute Drive Diagnostics */
mfm->status = STAT_BUSY;
timer_clock();
mfm->callback = 200*IDE_TIME;
timer_update_outstanding();
timer_set_delay_u64(&mfm->callback_timer, 200*IDE_TIME);
break;
default:
pclog("Bad MFM command %02X\n", val);
mfm->status = STAT_BUSY;
timer_clock();
mfm->callback = 200*IDE_TIME;
timer_update_outstanding();
timer_set_delay_u64(&mfm->callback_timer, 200*IDE_TIME);
break;
}
}
@ -297,9 +283,7 @@ void mfm_write(uint16_t port, uint8_t val, void *p)
case 0x3F6: /* Device control */
if ((mfm->fdisk & 4) && !(val & 4))
{
timer_clock();
mfm->callback = 500*IDE_TIME;
timer_update_outstanding();
timer_set_delay_u64(&mfm->callback_timer, 500*IDE_TIME);
mfm->reset = 1;
mfm->status = STAT_BUSY;
// pclog("MFM Reset\n");
@ -307,9 +291,7 @@ void mfm_write(uint16_t port, uint8_t val, void *p)
if (val & 4)
{
/*Drive held in reset*/
timer_clock();
mfm->callback = 0;
timer_update_outstanding();
timer_disable(&mfm->callback_timer);
mfm->status = STAT_BUSY;
}
mfm->fdisk = val;
@ -331,9 +313,7 @@ void mfm_writew(uint16_t port, uint16_t val, void *p)
{
mfm->pos = 0;
mfm->status = STAT_BUSY;
timer_clock();
mfm->callback = 6*IDE_TIME;
timer_update_outstanding();
timer_set_delay_u64(&mfm->callback_timer, 6*IDE_TIME);
}
}
@ -402,9 +382,7 @@ uint16_t mfm_readw(uint16_t port, void *p)
{
mfm_next_sector(mfm);
mfm->status = STAT_BUSY;
timer_clock();
mfm->callback = 6*IDE_TIME;
timer_update_outstanding();
timer_set_delay_u64(&mfm->callback_timer, 6*IDE_TIME);
}
}
}
@ -430,7 +408,7 @@ void mfm_callback(void *p)
off64_t addr;
// pclog("mfm_callback: command=%02x reset=%i\n", mfm->command, mfm->reset);
mfm->callback = 0;
if (mfm->reset)
{
mfm->status = STAT_READY | STAT_DSC;
@ -562,7 +540,7 @@ void *mfm_init()
io_sethandler(0x01f1, 0x0007, mfm_read, NULL, NULL, mfm_write, NULL, NULL, mfm);
io_sethandler(0x03f6, 0x0001, NULL, NULL, NULL, mfm_write, NULL, NULL, mfm);
timer_add(mfm_callback, &mfm->callback, &mfm->callback, mfm);
timer_add(&mfm->callback_timer, mfm_callback, mfm, 0);
return mfm;
}

View file

@ -51,7 +51,7 @@ typedef struct xebec_t
{
rom_t bios_rom;
int callback;
pc_timer_t callback_timer;
int state;
@ -143,7 +143,7 @@ static uint8_t xebec_read(uint16_t port, void *p)
// pclog("Read all data\n");
xebec->status = STAT_BSY;
xebec->state = STATE_SENT_DATA;
xebec->callback = XEBEC_TIME;
timer_set_delay_u64(&xebec->callback_timer, XEBEC_TIME);
}
break;
@ -190,7 +190,7 @@ static void xebec_write(uint16_t port, uint8_t val, void *p)
{
xebec->status = STAT_BSY;
xebec->state = STATE_START_COMMAND;
xebec->callback = XEBEC_TIME;
timer_set_delay_u64(&xebec->callback_timer, XEBEC_TIME);
// pclog("Command %02x\n", xebec->command[0]);
}
break;
@ -207,7 +207,7 @@ static void xebec_write(uint16_t port, uint8_t val, void *p)
// pclog("Got data\n");
xebec->status = STAT_BSY;
xebec->state = STATE_RECEIVED_DATA;
xebec->callback = XEBEC_TIME;
timer_set_delay_u64(&xebec->callback_timer, XEBEC_TIME);
}
break;
@ -314,8 +314,6 @@ static void xebec_callback(void *p)
xebec_t *xebec = (xebec_t *)p;
mfm_drive_t *drive;
xebec->callback = 0;
xebec->drive_sel = (xebec->command[1] & 0x20) ? 1 : 0;
xebec->completion_byte = xebec->drive_sel & 0x20;
@ -448,7 +446,7 @@ static void xebec_callback(void *p)
readflash_set(READFLASH_HDC, xebec->drive_sel);
}
if (xebec->irq_dma_mask & DMA_ENA)
xebec->callback = XEBEC_TIME;
timer_set_delay_u64(&xebec->callback_timer, XEBEC_TIME);
else
{
xebec->status = STAT_BSY | STAT_IO | STAT_REQ;
@ -468,12 +466,12 @@ static void xebec_callback(void *p)
{
pclog("CMD_READ_SECTORS out of data!\n");
xebec->status = STAT_BSY | STAT_CD | STAT_IO | STAT_REQ;
xebec->callback = XEBEC_TIME;
timer_set_delay_u64(&xebec->callback_timer, XEBEC_TIME);
return;
}
}
xebec->state = STATE_SENT_DATA;
xebec->callback = XEBEC_TIME;
timer_set_delay_u64(&xebec->callback_timer, XEBEC_TIME);
}
else
fatal("Read sectors no DMA! - shouldn't get here\n");
@ -505,7 +503,7 @@ static void xebec_callback(void *p)
xebec->state = STATE_SEND_DATA;
if (xebec->irq_dma_mask & DMA_ENA)
xebec->callback = XEBEC_TIME;
timer_set_delay_u64(&xebec->callback_timer, XEBEC_TIME);
else
{
xebec->status = STAT_BSY | STAT_IO | STAT_REQ;
@ -535,7 +533,7 @@ static void xebec_callback(void *p)
xebec->data_pos = 0;
xebec->data_len = 512;
if (xebec->irq_dma_mask & DMA_ENA)
xebec->callback = XEBEC_TIME;
timer_set_delay_u64(&xebec->callback_timer, XEBEC_TIME);
else
xebec->status = STAT_BSY | STAT_REQ;
break;
@ -552,7 +550,7 @@ static void xebec_callback(void *p)
{
pclog("CMD_WRITE_SECTORS out of data!\n");
xebec->status = STAT_BSY | STAT_CD | STAT_IO | STAT_REQ;
xebec->callback = XEBEC_TIME;
timer_set_delay_u64(&xebec->callback_timer, XEBEC_TIME);
return;
}
@ -560,7 +558,7 @@ static void xebec_callback(void *p)
}
xebec->state = STATE_RECEIVED_DATA;
xebec->callback = XEBEC_TIME;
timer_set_delay_u64(&xebec->callback_timer, XEBEC_TIME);
}
else
fatal("Write sectors no DMA! - should never get here\n");
@ -595,7 +593,7 @@ static void xebec_callback(void *p)
{
xebec->state = STATE_RECEIVE_DATA;
if (xebec->irq_dma_mask & DMA_ENA)
xebec->callback = XEBEC_TIME;
timer_set_delay_u64(&xebec->callback_timer, XEBEC_TIME);
else
xebec->status = STAT_BSY | STAT_REQ;
}
@ -653,7 +651,7 @@ static void xebec_callback(void *p)
xebec->data_pos = 0;
xebec->data_len = 512;
if (xebec->irq_dma_mask & DMA_ENA)
xebec->callback = XEBEC_TIME;
timer_set_delay_u64(&xebec->callback_timer, XEBEC_TIME);
else
xebec->status = STAT_BSY | STAT_REQ;
break;
@ -671,7 +669,7 @@ static void xebec_callback(void *p)
{
pclog("CMD_WRITE_SECTOR_BUFFER out of data!\n");
xebec->status = STAT_BSY | STAT_CD | STAT_IO | STAT_REQ;
xebec->callback = XEBEC_TIME;
timer_set_delay_u64(&xebec->callback_timer, XEBEC_TIME);
return;
}
@ -679,7 +677,7 @@ static void xebec_callback(void *p)
}
xebec->state = STATE_RECEIVED_DATA;
xebec->callback = XEBEC_TIME;
timer_set_delay_u64(&xebec->callback_timer, XEBEC_TIME);
}
else
fatal("CMD_WRITE_SECTOR_BUFFER - should never get here!\n");
@ -829,7 +827,7 @@ static void *xebec_init()
io_sethandler(0x0320, 0x0004, xebec_read, NULL, NULL, xebec_write, NULL, NULL, xebec);
timer_add(xebec_callback, &xebec->callback, &xebec->callback, xebec);
timer_add(&xebec->callback_timer, xebec_callback, xebec, 0);
return xebec;
}
@ -880,7 +878,7 @@ static void *dtc_5150x_init()
io_sethandler(0x0320, 0x0004, xebec_read, NULL, NULL, xebec_write, NULL, NULL, xebec);
timer_add(xebec_callback, &xebec->callback, &xebec->callback, xebec);
timer_add(&xebec->callback_timer, xebec_callback, xebec, 0);
return xebec;
}

View file

@ -7,7 +7,8 @@
typedef struct mouse_serial_t
{
int mousepos, mousedelay;
int mousepos;
pc_timer_t mousedelay_timer;
int oldb;
SERIAL *serial;
} mouse_serial_t;
@ -52,14 +53,13 @@ void mouse_serial_rcr(struct SERIAL *serial, void *p)
mouse_serial_t *mouse = (mouse_serial_t *)p;
mouse->mousepos = -1;
mouse->mousedelay = 5000 * (1 << TIMER_SHIFT);
timer_set_delay_u64(&mouse->mousedelay_timer, TIMER_USEC * 5000);
}
void mousecallback(void *p)
{
mouse_serial_t *mouse = (mouse_serial_t *)p;
mouse->mousedelay = 0;
if (mouse->mousepos == -1)
{
mouse->mousepos = 0;
@ -75,7 +75,7 @@ void *mouse_serial_init()
mouse->serial = &serial1;
serial1.rcr_callback = mouse_serial_rcr;
serial1.rcr_callback_p = mouse;
timer_add(mousecallback, &mouse->mousedelay, &mouse->mousedelay, mouse);
timer_add(&mouse->mousedelay_timer, mousecallback, mouse, 0);
return mouse;
}

View file

@ -91,7 +91,7 @@ static struct
static int vlan_handlers_num;
static int vlan_poller_time = 0;
static pc_timer_t vlan_poller_timer;
void vlan_handler(void (*poller)(void *p), void *p)
//void vlan_handler(int (*can_receive)(void *p), void (*receive)(void *p, const uint8_t *buf, int size), void *p)
@ -106,7 +106,7 @@ void vlan_poller(void *priv)
{
int c;
vlan_poller_time += (int)((double)TIMER_USEC * (1000000.0 / 8.0 / 1500.0));
timer_advance_u64(&vlan_poller_timer, (uint64_t)((double)TIMER_USEC * (1000000.0 / 8.0 / 1500.0)));
for (c = 0; c < vlan_handlers_num; c++)
vlan_handlers[c].poller(vlan_handlers[c].priv);
@ -114,7 +114,7 @@ void vlan_poller(void *priv)
void vlan_reset()
{
timer_add(vlan_poller, &vlan_poller_time, TIMER_ALWAYS_ENABLED, NULL);
timer_add(&vlan_poller_timer, vlan_poller, NULL, 1);
vlan_handlers_num = 0;
}

View file

@ -19,9 +19,10 @@ int nvraddr;
int nvr_dosave = 0;
static int nvr_onesec_time = 0, nvr_onesec_cnt = 0;
static pc_timer_t nvr_onesec_timer;
static int nvr_onesec_cnt = 0;
static int rtctime;
static pc_timer_t rtc_timer;
FILE *nvrfopen(char *fn, char *mode)
{
@ -62,10 +63,9 @@ void getnvrtime()
void nvr_recalc()
{
int c;
int newrtctime;
c = 1 << ((nvrram[RTC_REGA] & RTC_RS) - 1);
newrtctime=(int)(RTCCONST * c * (1 << TIMER_SHIFT));
if (rtctime>newrtctime) rtctime=newrtctime;
timer_set_delay_u64(&rtc_timer, (uint64_t)(RTCCONST * c));
}
void nvr_rtc(void *p)
@ -73,11 +73,11 @@ void nvr_rtc(void *p)
int c;
if (!(nvrram[RTC_REGA] & RTC_RS))
{
rtctime=0x7fffffff;
timer_disable(&rtc_timer);
return;
}
c = 1 << ((nvrram[RTC_REGA] & RTC_RS) - 1);
rtctime += (int)(RTCCONST * c * (1 << TIMER_SHIFT));
timer_advance_u64(&rtc_timer, (uint64_t)(RTCCONST * c));
// pclog("RTCtime now %f\n",rtctime);
nvrram[RTC_REGC] |= RTC_PF;
if (nvrram[RTC_REGB] & RTC_PIE)
@ -98,7 +98,7 @@ int nvr_check_alarm(int nvraddr)
return (nvrram[nvraddr + 1] == nvrram[nvraddr] || (nvrram[nvraddr + 1] & ALARM_DONTCARE) == ALARM_DONTCARE);
}
int nvr_update_end_count = 0;
pc_timer_t nvr_update_end_timer;
void nvr_update_end(void *p)
{
@ -130,8 +130,6 @@ void nvr_update_end(void *p)
}
// pclog("RTC onesec\n");
nvr_update_end_count = 0;
}
void nvr_onesec(void *p)
@ -144,11 +142,11 @@ void nvr_onesec(void *p)
nvr_update_status = RTC_UIP;
rtc_tick();
nvr_update_end_count = (int)((244.0 + 1984.0) * TIMER_USEC);
timer_set_delay_u64(&nvr_update_end_timer, (uint64_t)((244.0 + 1984.0) * TIMER_USEC));
}
nvr_onesec_cnt = 0;
}
nvr_onesec_time += (int)(10000 * TIMER_USEC);
timer_advance_u64(&nvr_onesec_timer, (uint64_t)(10000 * TIMER_USEC));
}
void writenvr(uint16_t addr, uint8_t val, void *priv)
@ -174,10 +172,10 @@ void writenvr(uint16_t addr, uint8_t val, void *priv)
if (val & RTC_RS)
{
c = 1 << ((val & RTC_RS) - 1);
rtctime += (int)(RTCCONST * c * (1 << TIMER_SHIFT));
timer_set_delay_u64(&rtc_timer, (uint64_t)(RTCCONST * c));
}
else
rtctime = 0x7fffffff;
timer_disable(&rtc_timer);
}
else
{
@ -333,7 +331,7 @@ void loadnvr()
nvrram[RTC_REGA] = 6;
nvrram[RTC_REGB] = RTC_2412;
c = 1 << ((nvrram[RTC_REGA] & RTC_RS) - 1);
rtctime += (int)(RTCCONST * c * (1 << TIMER_SHIFT));
timer_set_delay_u64(&rtc_timer, (uint64_t)(RTCCONST * c));
}
void savenvr()
{
@ -408,8 +406,8 @@ void savenvr()
void nvr_init()
{
io_sethandler(0x0070, 0x0002, readnvr, NULL, NULL, writenvr, NULL, NULL, NULL);
timer_add(nvr_rtc, &rtctime, TIMER_ALWAYS_ENABLED, NULL);
timer_add(nvr_onesec, &nvr_onesec_time, TIMER_ALWAYS_ENABLED, NULL);
timer_add(nvr_update_end, &nvr_update_end_count, &nvr_update_end_count, NULL);
timer_add(&rtc_timer, nvr_rtc, NULL, 1);
timer_add(&nvr_onesec_timer, nvr_onesec, NULL, 1);
timer_add(&nvr_update_end_timer, nvr_update_end, NULL, 0);
}

View file

@ -11,7 +11,8 @@
#include "config.h"
#include "nmi.h"
static int nvr_onesec_time = 0, nvr_onesec_cnt = 0;
static pc_timer_t nvr_onesec_timer;
static int nvr_onesec_cnt = 0;
static void tc8521_onesec(void *p)
{
@ -21,7 +22,7 @@ static void tc8521_onesec(void *p)
tc8521_tick();
nvr_onesec_cnt = 0;
}
nvr_onesec_time += (int)(10000 * TIMER_USEC);
timer_advance_u64(&nvr_onesec_timer, 10000 * TIMER_USEC);
}
void write_tc8521(uint16_t addr, uint8_t val, void *priv)
@ -96,5 +97,5 @@ void tc8521_savenvr()
void nvr_tc8521_init()
{
io_sethandler(0x2C0, 0x10, read_tc8521, NULL, NULL, write_tc8521, NULL, NULL, NULL);
timer_add(tc8521_onesec, &nvr_onesec_time, TIMER_ALWAYS_ENABLED, NULL);
timer_add(&nvr_onesec_timer, tc8521_onesec, NULL, 1);
}

194
src/pit.c
View file

@ -21,7 +21,12 @@
//Tyrian writes 4300 or 17512
int displine;
double PITCONST;
uint64_t PITCONST;
uint64_t CGACONST;
uint64_t MDACONST;
uint64_t VGACONST1, VGACONST2;
uint64_t RTCCONST;
float cpuclock;
float isa_timing, bus_timing;
@ -30,23 +35,23 @@ void setpitclock(float clock)
{
// printf("PIT clock %f\n",clock);
cpuclock=clock;
PITCONST=clock/1193182.0;
CGACONST=(clock/(19687503.0/11.0));
MDACONST=(clock/2032125.0);
VGACONST1=(clock/25175000.0);
VGACONST2=(clock/28322000.0);
PITCONST = (uint64_t)(clock / 1193182.0 * (float)(1ull << 32));
CGACONST = (uint64_t)((clock / (19687503.0/11.0)) * (float)(1ull << 32));
MDACONST = (uint64_t)((clock / 2032125.0) * (float)(1ull << 32));
VGACONST1 = (uint64_t)((clock / 25175000.0) * (float)(1ull << 32));
VGACONST2 = (uint64_t)((clock / 28322000.0) * (float)(1ull << 32));
isa_timing = clock/8000000.0;
bus_timing = clock/(double)cpu_busspeed;
video_updatetiming();
// pclog("PITCONST=%f CGACONST=%f\n", PITCONST, CGACONST);
// pclog("CPUMULTI=%g\n", ((14318184.0*(double)(1 << TIMER_SHIFT)) / (double)models[model].cpu[cpu_manufacturer].cpus[cpu].rspeed));
xt_cpu_multi = (int)((14318184.0*(double)(1 << TIMER_SHIFT)) / (double)cpu_get_speed());
xt_cpu_multi = (uint64_t)((14318184.0*(double)(1ull << 32)) / (double)cpu_get_speed());
// pclog("egacycles %i egacycles2 %i temp %f clock %f\n",egacycles,egacycles2,temp,clock);
/* if (video_recalctimings)
video_recalctimings();*/
RTCCONST=clock/32768.0;
TIMER_USEC = (int)((clock / 1000000.0f) * (float)(1 << TIMER_SHIFT));
RTCCONST = (uint64_t)((clock / 32768.0) * (float)(1ull << 32));
TIMER_USEC = (uint64_t)((clock / 1000000.0) * (float)(1ull << 32));
device_speed_changed();
}
@ -55,9 +60,9 @@ void setpitclock(float clock)
void pit_reset(PIT *pit)
{
memset(pit, 0, sizeof(PIT));
pit->l[0] = 0xFFFF; pit->c[0] = 0xFFFF*PITCONST;
pit->l[1] = 0xFFFF; pit->c[1] = 0xFFFF*PITCONST;
pit->l[2] = 0xFFFF; pit->c[2] = 0xFFFF*PITCONST;
pit->l[0] = 0xFFFF;
pit->l[1] = 0xFFFF;
pit->l[2] = 0xFFFF;
pit->m[0] = pit->m[1] = pit->m[2] = 0;
pit->ctrls[0] = pit->ctrls[1] = pit->ctrls[2] = 0;
pit->thit[0]=1;
@ -66,11 +71,6 @@ void pit_reset(PIT *pit)
pit->using_timer[0] = pit->using_timer[1] = pit->using_timer[2] = 1;
}
void clearpit()
{
pit.c[0]=(pit.l[0]<<2);
}
float pit_timer0_freq()
{
if (pit.l[0])
@ -85,18 +85,52 @@ static void pit_set_out(PIT *pit, int t, int out)
pit->out[t] = out;
}
static int pit_read_timer(PIT *pit, int t)
{
// pclog("pit_read_timer: t=%i using_timer=%i m=%i enabled=%i\n", t, pit->using_timer[t], pit->m[t], timer_is_enabled(&pit->timer[t]));
if (pit->using_timer[t] && !(pit->m[t] == 3 && !pit->gate[t]) && timer_is_enabled(&pit->timer[t]))
{
int read = (int)((timer_get_remaining_u64(&pit->timer[t])) / PITCONST);
// pclog(" read %i %08x %016llx\n", t, read, timer_get_remaining_u64(&pit->timer[t]));
if (pit->m[t] == 2)
read++;
if (read < 0)
read = 0;
if (read > 0x10000)
read = 0x10000;
if (pit->m[t] == 3)
read <<= 1;
return read;
}
if (pit->m[t] == 2)
return pit->count[t] + 1;
return pit->count[t];
}
/*Dump timer count back to pit->count[], and disable timer. This should be used
when stopping a PIT timer, to ensure the correct value can be read back.*/
static void pit_dump_and_disable_timer(PIT *pit, int t)
{
if (pit->using_timer[t] && timer_is_enabled(&pit->timer[t]))
{
pit->count[t] = pit_read_timer(pit, t);
timer_disable(&pit->timer[t]);
}
}
static void pit_load(PIT *pit, int t)
{
int l = pit->l[t] ? pit->l[t] : 0x10000;
timer_clock();
pit->newcount[t] = 0;
pit->disabled[t] = 0;
// pclog("pit_load: t=%i l=%x\n", t, l);
// pclog("pit_load: t=%i l=%x m=%i %016llx\n", t, l, pit->m[t], PITCONST);
switch (pit->m[t])
{
case 0: /*Interrupt on terminal count*/
pit->count[t] = l;
pit->c[t] = (int)((l << TIMER_SHIFT) * PITCONST);
if (pit->using_timer[t])
timer_set_delay_u64(&pit->timer[t], (uint64_t)(l * PITCONST));
pit_set_out(pit, t, 0);
pit->thit[t] = 0;
pit->enabled[t] = pit->gate[t];
@ -108,7 +142,8 @@ static void pit_load(PIT *pit, int t)
if (pit->initial[t])
{
pit->count[t] = l - 1;
pit->c[t] = (int)(((l - 1) << TIMER_SHIFT) * PITCONST);
if (pit->using_timer[t])
timer_set_delay_u64(&pit->timer[t], (uint64_t)((l - 1) * PITCONST));
pit_set_out(pit, t, 1);
pit->thit[t] = 0;
}
@ -118,12 +153,13 @@ static void pit_load(PIT *pit, int t)
if (pit->initial[t])
{
pit->count[t] = l;
pit->c[t] = (int)((((l + 1) >> 1) << TIMER_SHIFT) * PITCONST);
if (pit->using_timer[t])
timer_set_delay_u64(&pit->timer[t], (uint64_t)(((l + 1) >> 1) * PITCONST));
pit_set_out(pit, t, 1);
pit->thit[t] = 0;
}
pit->enabled[t] = pit->gate[t];
// pclog("pit_load: square wave mode c=%x\n", pit->c[t]);
// pclog("pit_load: square wave mode c=%x\n", );
break;
case 4: /*Software triggered stobe*/
if (!pit->thit[t] && !pit->initial[t])
@ -131,7 +167,8 @@ static void pit_load(PIT *pit, int t)
else
{
pit->count[t] = l;
pit->c[t] = (int)((l << TIMER_SHIFT) * PITCONST);
if (pit->using_timer[t])
timer_set_delay_u64(&pit->timer[t], (uint64_t)(l * PITCONST));
pit_set_out(pit, t, 0);
pit->thit[t] = 0;
}
@ -143,7 +180,9 @@ static void pit_load(PIT *pit, int t)
}
pit->initial[t] = 0;
pit->running[t] = pit->enabled[t] && pit->using_timer[t] && !pit->disabled[t];
timer_update_outstanding();
if (pit->using_timer[t] && !pit->running[t])
pit_dump_and_disable_timer(pit, t);
// pclog("pit_load: t=%i running=%i thit=%i enabled=%i m=%i l=%x c=%g gate=%i\n", t, pit.running[t], pit.thit[t], pit.enabled[t], pit.m[t], pit.l[t], pit.c[t], pit.gate[t]);
}
@ -161,6 +200,8 @@ void pit_set_gate_no_timer(PIT *pit, int t, int gate)
{
case 0: /*Interrupt on terminal count*/
case 4: /*Software triggered stobe*/
if (pit->using_timer[t] && !pit->running[t])
timer_set_delay_u64(&pit->timer[t], (uint64_t)(l * PITCONST));
pit->enabled[t] = gate;
break;
case 1: /*Hardware retriggerable one-shot*/
@ -168,7 +209,8 @@ void pit_set_gate_no_timer(PIT *pit, int t, int gate)
if (gate && !pit->gate[t])
{
pit->count[t] = l;
pit->c[t] = (int)((l << TIMER_SHIFT) * PITCONST);
if (pit->using_timer[t])
timer_set_delay_u64(&pit->timer[t], (uint64_t)(l * PITCONST));
pit_set_out(pit, t, 0);
pit->thit[t] = 0;
pit->enabled[t] = 1;
@ -178,7 +220,8 @@ void pit_set_gate_no_timer(PIT *pit, int t, int gate)
if (gate && !pit->gate[t])
{
pit->count[t] = l - 1;
pit->c[t] = (int)(((l - 1) << TIMER_SHIFT) * PITCONST);
if (pit->using_timer[t])
timer_set_delay_u64(&pit->timer[t], (uint64_t)(l * PITCONST));
pit_set_out(pit, t, 1);
pit->thit[t] = 0;
}
@ -188,7 +231,8 @@ void pit_set_gate_no_timer(PIT *pit, int t, int gate)
if (gate && !pit->gate[t])
{
pit->count[t] = l;
pit->c[t] = (int)((((l + 1) >> 1) << TIMER_SHIFT) * PITCONST);
if (pit->using_timer[t])
timer_set_delay_u64(&pit->timer[t], (uint64_t)(((l + 1) >> 1) * PITCONST));
pit_set_out(pit, t, 1);
pit->thit[t] = 0;
}
@ -197,23 +241,21 @@ void pit_set_gate_no_timer(PIT *pit, int t, int gate)
}
pit->gate[t] = gate;
pit->running[t] = pit->enabled[t] && pit->using_timer[t] && !pit->disabled[t];
if (pit->using_timer[t] && !pit->running[t])
pit_dump_and_disable_timer(pit, t);
// pclog("pit_set_gate: t=%i gate=%i\n", t, gate);
}
void pit_set_gate(PIT *pit, int t, int gate)
{
// pclog("pit_set_gate: t=%i gate=%i\n", t, gate);
if (pit->disabled[t])
{
pit->gate[t] = gate;
return;
}
timer_process();
pit_set_gate_no_timer(pit, t, gate);
timer_update_outstanding();
// pclog("pit_set_gate: t=%i gate=%i\n", t, gate);
}
static void pit_over(PIT *pit, int t)
@ -222,11 +264,12 @@ static void pit_over(PIT *pit, int t)
if (pit->disabled[t])
{
pit->count[t] += 0xffff;
pit->c[t] += (int)((0xffff << TIMER_SHIFT) * PITCONST);
if (pit->using_timer[t])
timer_advance_u64(&pit->timer[t], (uint64_t)(0xffff * PITCONST));
return;
}
// if (!t) pclog("pit_over: t=%i l=%x c=%x %i hit=%i\n", t, pit->l[t], pit.c[t], pit.c[t] >> TIMER_SHIFT, pit.thit[t]);
// if (t == 2) pclog("pit_over: t=%i l=%x c=%llx hit=%i %016llx\n", t, pit->l[t], timer_get_remaining_u64(&pit->timer[t]), pit->thit[t], tsc);
switch (pit->m[t])
{
case 0: /*Interrupt on terminal count*/
@ -235,11 +278,13 @@ static void pit_over(PIT *pit, int t)
pit_set_out(pit, t, 1);
pit->thit[t] = 1;
pit->count[t] += 0xffff;
pit->c[t] += (int)((0xffff << TIMER_SHIFT) * PITCONST);
if (pit->using_timer[t])
timer_advance_u64(&pit->timer[t], (uint64_t)(0xffff * PITCONST));
break;
case 2: /*Rate generator*/
pit->count[t] += l;
pit->c[t] += (int)((l << TIMER_SHIFT) * PITCONST);
if (pit->using_timer[t])
timer_advance_u64(&pit->timer[t], (uint64_t)(l * PITCONST));
pit_set_out(pit, t, 0);
pit_set_out(pit, t, 1);
break;
@ -248,13 +293,15 @@ static void pit_over(PIT *pit, int t)
{
pit_set_out(pit, t, 0);
pit->count[t] += (l >> 1);
pit->c[t] += (int)(((l >> 1) << TIMER_SHIFT) * PITCONST);
if (pit->using_timer[t])
timer_advance_u64(&pit->timer[t], (uint64_t)((l >> 1) * PITCONST));
}
else
{
pit_set_out(pit, t, 1);
pit->count[t] += ((l + 1) >> 1);
pit->c[t] = (int)((((l + 1) >> 1) << TIMER_SHIFT) * PITCONST);
if (pit->using_timer[t])
timer_advance_u64(&pit->timer[t], (uint64_t)(((l + 1) >> 1) * PITCONST));
}
// if (!t) pclog("pit_over: square wave mode c=%x %lli %f\n", pit.c[t], tsc, PITCONST);
break;
@ -268,13 +315,15 @@ static void pit_over(PIT *pit, int t)
{
pit->newcount[t] = 0;
pit->count[t] += l;
pit->c[t] += (int)((l << TIMER_SHIFT) * PITCONST);
if (pit->using_timer[t])
timer_advance_u64(&pit->timer[t], (uint64_t)(l * PITCONST));
}
else
{
pit->thit[t] = 1;
pit->count[t] += 0xffff;
pit->c[t] += (int)((0xffff << TIMER_SHIFT) * PITCONST);
if (pit->using_timer[t])
timer_advance_u64(&pit->timer[t], (uint64_t)(0xffff * PITCONST));
}
break;
case 5: /*Hardware triggered strove*/
@ -285,54 +334,20 @@ static void pit_over(PIT *pit, int t)
}
pit->thit[t] = 1;
pit->count[t] += 0xffff;
pit->c[t] += (int)((0xffff << TIMER_SHIFT) * PITCONST);
if (pit->using_timer[t])
timer_advance_u64(&pit->timer[t], (uint64_t)(0xffff * PITCONST));
break;
}
pit->running[t] = pit->enabled[t] && pit->using_timer[t] && !pit->disabled[t];
}
int pit_get_timer_0()
{
int read = (int)((pit.c[0] + ((1 << TIMER_SHIFT) - 1)) / PITCONST) >> TIMER_SHIFT;
//pclog("pit_get_timer_0: t=%i using_timer=%i m=%i\n", 0, pit.using_timer[0], pit.m[0]);
if (pit.m[0] == 2)
read++;
if (read < 0)
read = 0;
if (read > 0x10000)
read = 0x10000;
if (pit.m[0] == 3)
read <<= 1;
return read;
}
static int pit_read_timer(PIT *pit, int t)
{
timer_clock();
// pclog("pit_read_timer: t=%i using_timer=%i m=%i\n", t, pit.using_timer[t], pit.m[t]);
if (pit->using_timer[t] && !(pit->m[t] == 3 && !pit->gate[t]))
{
int read = (int)((pit->c[t] + ((1 << TIMER_SHIFT) - 1)) / PITCONST) >> TIMER_SHIFT;
if (pit->m[t] == 2)
read++;
if (read < 0)
read = 0;
if (read > 0x10000)
read = 0x10000;
if (pit->m[t] == 3)
read <<= 1;
return read;
}
if (pit->m[t] == 2)
return pit->count[t] + 1;
return pit->count[t];
if (pit->using_timer[t] && !pit->running[t])
pit_dump_and_disable_timer(pit, t);
}
void pit_write(uint16_t addr, uint8_t val, void *p)
{
PIT *pit = (PIT *)p;
int t;
// /*if (val != 0x40) */pclog("Write PIT %04X %02X %04X:%08X %i %i\n",addr,val,CS,pc,ins, pit->gate[0]);
// /*if (val != 0x40) */pclog("Write PIT %04X %02X %04X:%08X %i %i\n",addr,val,CS,cpu_state.pc,ins, pit->gate[0]);
switch (addr&3)
{
@ -456,7 +471,7 @@ uint8_t pit_read(uint16_t addr, void *p)
PIT *pit = (PIT *)p;
int t;
uint8_t temp = 0xff;
// printf("Read PIT %04X ",addr);
// printf("Read PIT %04X\n",addr);
switch (addr&3)
{
case 0: case 1: case 2: /*Timers*/
@ -537,11 +552,12 @@ void pit_set_using_timer(PIT *pit, int t, int using_timer)
timer_process();
if (pit->using_timer[t] && !using_timer)
pit->count[t] = pit_read_timer(pit, t);
if (!pit->using_timer[t] && using_timer)
pit->c[t] = (int)((pit->count[t] << TIMER_SHIFT) * PITCONST);
pit->running[t] = pit->enabled[t] && using_timer && !pit->disabled[t];
if (!pit->using_timer[t] && using_timer && pit->running[t])
timer_set_delay_u64(&pit->timer[t], (uint64_t)(pit->count[t] * PITCONST));
else if (!pit->running[t])
timer_disable(&pit->timer[t]);
pit->using_timer[t] = using_timer;
pit->running[t] = pit->enabled[t] && pit->using_timer[t] && !pit->disabled[t];
timer_update_outstanding();
}
void pit_set_out_func(PIT *pit, int t, void (*func)(int new_out, int old_out))
@ -633,9 +649,9 @@ void pit_init()
pit.pit_nr[2].nr = 2;
pit.pit_nr[0].pit = pit.pit_nr[1].pit = pit.pit_nr[2].pit = &pit;
timer_add(pit_timer_over, &pit.c[0], &pit.running[0], (void *)&pit.pit_nr[0]);
timer_add(pit_timer_over, &pit.c[1], &pit.running[1], (void *)&pit.pit_nr[1]);
timer_add(pit_timer_over, &pit.c[2], &pit.running[2], (void *)&pit.pit_nr[2]);
timer_add(&pit.timer[0], pit_timer_over, (void *)&pit.pit_nr[0], 0);
timer_add(&pit.timer[1], pit_timer_over, (void *)&pit.pit_nr[1], 0);
timer_add(&pit.timer[2], pit_timer_over, (void *)&pit.pit_nr[2], 0);
pit_set_out_func(&pit, 0, pit_irq0_timer);
pit_set_out_func(&pit, 1, pit_null_timer);
@ -656,7 +672,7 @@ void pit_ps2_init()
pit2.pit_nr[0].nr = 0;
pit2.pit_nr[0].pit = &pit2;
timer_add(pit_timer_over, &pit2.c[0], &pit2.running[0], (void *)&pit2.pit_nr[0]);
timer_add(&pit2.timer[0], pit_timer_over, (void *)&pit2.pit_nr[0], 0);
pit_set_out_func(&pit, 0, pit_irq0_ps2);
pit_set_out_func(&pit2, 0, pit_nmi_ps2);

View file

@ -1,4 +1,4 @@
extern double PITCONST;
extern uint64_t PITCONST;
void pit_init();
void pit_ps2_init();
void pit_reset();

View file

@ -8,9 +8,8 @@
#include "scsi_53c400.h"
#include "timer.h"
#define POLL_TIME_US 10
#define POLL_TIME_US 1
#define MAX_BYTES_TRANSFERRED_PER_POLL 50
/*10us poll period with 50 bytes transferred per poll = 5MB/sec*/
typedef struct ncr5380_t
{
@ -57,8 +56,7 @@ typedef struct lcs6821n_t
int ncr5380_dma_enabled;
int dma_callback;
int dma_enabled;
pc_timer_t dma_timer;
int ncr_busy;
} lcs6821n_t;
@ -96,13 +94,24 @@ enum
DMA_INITIATOR_RECEIVE
};
static void set_dma_enable(lcs6821n_t *scsi, int enable)
{
if (enable)
{
if (!timer_is_enabled(&scsi->dma_timer))
timer_set_delay_u64(&scsi->dma_timer, TIMER_USEC * POLL_TIME_US);
}
else
timer_disable(&scsi->dma_timer);
}
static void ncr53c400_dma_changed(ncr5380_t *ncr, int mode, int enable)
{
lcs6821n_t *scsi = (lcs6821n_t *)ncr->p;
scsi->ncr5380_dma_enabled = (mode && enable);
scsi->dma_enabled = (scsi->ncr5380_dma_enabled && scsi->block_count_loaded);
set_dma_enable(scsi, scsi->ncr5380_dma_enabled && scsi->block_count_loaded);
}
void ncr5380_reset(ncr5380_t *ncr)
@ -424,7 +433,7 @@ static void lcs6821n_write(uint32_t addr, uint8_t val, void *p)
case 0x3981: /*Block counter register*/
scsi->block_count = val;
scsi->block_count_loaded = 1;
scsi->dma_enabled = (scsi->ncr5380_dma_enabled && scsi->block_count_loaded);
set_dma_enable(scsi, scsi->ncr5380_dma_enabled && scsi->block_count_loaded);
if (scsi->status_ctrl & CTRL_DATA_DIR)
{
scsi->buffer_host_pos = 128;
@ -533,7 +542,7 @@ static void ncr53c400_dma_callback(void *p)
int bytes_transferred = 0;
//pclog("dma_Callback poll\n");
scsi->dma_callback += POLL_TIME_US;
timer_advance_u64(&scsi->dma_timer, TIMER_USEC * POLL_TIME_US);
switch (scsi->ncr.dma_mode)
{
@ -600,7 +609,7 @@ static void ncr53c400_dma_callback(void *p)
if (!scsi->block_count)
{
scsi->block_count_loaded = 0;
scsi->dma_enabled = 0;
set_dma_enable(scsi, 0);
// scsi->buffer_host_pos = 128;
// scsi->status_ctrl |= STATUS_BUFFER_NOT_READY;
@ -665,7 +674,7 @@ static void ncr53c400_dma_callback(void *p)
if (!scsi->block_count)
{
scsi->block_count_loaded = 0;
scsi->dma_enabled = 0;
set_dma_enable(scsi, 0);
// output=3;
ncr->isr |= STATUS_END_OF_DMA;
@ -717,7 +726,7 @@ static void *scsi_53c400_init(char *bios_fn)
scsi_bus_init(&scsi->ncr.bus);
timer_add(ncr53c400_dma_callback, &scsi->dma_callback, &scsi->dma_enabled, scsi);
timer_add(&scsi->dma_timer, ncr53c400_dma_callback, scsi, 0);
return scsi;
}
@ -757,7 +766,7 @@ static void *scsi_t130b_init(char *bios_fn)
scsi_bus_init(&scsi->ncr.bus);
timer_add(ncr53c400_dma_callback, &scsi->dma_callback, &scsi->dma_enabled, scsi);
timer_add(&scsi->dma_timer, ncr53c400_dma_callback, scsi, 0);
return scsi;
}

View file

@ -126,7 +126,7 @@ typedef struct aha154x_t
int bios_cmd_state;
int timer;
pc_timer_t timer;
int current_mbo;
int current_mbo_is_bios;
@ -2165,7 +2165,7 @@ static void aha154x_callback(void *p)
{
aha154x_t *scsi = (aha154x_t *)p;
scsi->timer += TIMER_USEC * POLL_TIME_US;
timer_advance_u64(&scsi->timer, TIMER_USEC * POLL_TIME_US);
// pclog("poll %i\n", scsi->cmd_state);
process_cmd(scsi);
@ -2253,7 +2253,7 @@ static void *scsi_aha1542c_init(char *bios_fn)
scsi->ccb_state = CCB_STATE_IDLE;
scsi->scsi_state = SCSI_STATE_IDLE;
timer_add(aha154x_callback, &scsi->timer, TIMER_ALWAYS_ENABLED, scsi);
timer_add(&scsi->timer, aha154x_callback, scsi, 1);
addr = device_get_config_int("addr");
io_sethandler(addr, 0x0004,
@ -2298,7 +2298,7 @@ static void *scsi_bt545s_init(char *bios_fn)
scsi->ccb_state = CCB_STATE_IDLE;
scsi->scsi_state = SCSI_STATE_IDLE;
timer_add(aha154x_callback, &scsi->timer, TIMER_ALWAYS_ENABLED, scsi);
timer_add(&scsi->timer, aha154x_callback, scsi, 1);
addr = device_get_config_int("addr");
io_sethandler(addr, 0x0004,

View file

@ -164,7 +164,7 @@ typedef struct scsi_cd_data_t
int blocks;
int cmd_pos, new_cmd_pos;
int callback;
pc_timer_t callback_timer;
int wait_time;
scsi_bus_t *bus;
@ -275,15 +275,12 @@ static void scsi_cd_callback(void *p)
data->wait_time--;
if (!data->wait_time)
{
data->callback = 0;
data->cmd_pos = data->new_cmd_pos;
scsi_bus_kick(data->bus);
}
else
data->callback = 1000 * TIMER_USEC;
timer_advance_u64(&data->callback_timer, 1000 * TIMER_USEC);
}
else
data->callback = 0;
}
//#define SECTOR_TIME 13333 /*Time between sectors on 1x drive*/
@ -397,7 +394,7 @@ static void *scsi_cd_init(scsi_bus_t *bus, int id)
memset(mode_pages_in[GPMODE_CDROM_AUDIO_PAGE], 0, 256); /* Clear the page itself. */
page_flags[GPMODE_CDROM_AUDIO_PAGE] &= ~PAGE_CHANGED;
timer_add(scsi_cd_callback, &data->callback, &data->callback, data);
timer_add(&data->callback_timer, scsi_cd_callback, data, 0);
cd_data = data;
cd_set_speed(cd_speed);
@ -697,7 +694,7 @@ static int scsi_cd_command(uint8_t *cdb, void *p)
data->cmd_pos = CMD_POS_WAIT;
data->new_cmd_pos = CMD_POS_COMPLETE;
data->wait_time = seek_time;
data->callback = 1000 * TIMER_USEC;
timer_set_delay_u64(&data->callback_timer, 1000 * TIMER_USEC);
return SCSI_PHASE_COMMAND;
}
}
@ -761,7 +758,7 @@ static int scsi_cd_command(uint8_t *cdb, void *p)
data->cmd_pos = CMD_POS_WAIT;
data->new_cmd_pos = CMD_POS_COMPLETE;
data->wait_time = seek_time;
data->callback = 1000 * TIMER_USEC;
timer_set_delay_u64(&data->callback_timer, 1000 * TIMER_USEC);
return SCSI_PHASE_COMMAND;
}
}
@ -862,7 +859,7 @@ static int scsi_cd_command(uint8_t *cdb, void *p)
data->cmd_pos = CMD_POS_WAIT;
data->new_cmd_pos = CMD_POS_START_SECTOR;
data->wait_time = seek_time;
data->callback = 1000 * TIMER_USEC;
timer_set_delay_u64(&data->callback_timer, 1000 * TIMER_USEC);
return SCSI_PHASE_COMMAND;
}
}
@ -875,23 +872,21 @@ static int scsi_cd_command(uint8_t *cdb, void *p)
}
if (data->cmd_pos == CMD_POS_START_SECTOR)
{
uint64_t time = (((uint64_t)SECTOR_TIME * (uint64_t)TIMER_USEC) / data->cur_speed) * (uint64_t)data->cdlen;
uint64_t time = (((uint64_t)SECTOR_TIME * TIMER_USEC) / data->cur_speed) * (uint64_t)data->cdlen;
data->cmd_pos = CMD_POS_WAIT;
data->new_cmd_pos = CMD_POS_TRANSFER;
if (time > 0x7fffffffull)
if (time > (TIMER_USEC * 1000ull))
{
data->wait_time = (int)(time / ((uint64_t)TIMER_USEC * 1000ull));
data->callback = (int)(time % ((uint64_t)TIMER_USEC * 1000ull));;
data->wait_time = (int)(time / (TIMER_USEC * 1000ull));
timer_set_delay_u64(&data->callback_timer, time % (TIMER_USEC * 1000ull));
}
else
{
data->callback = time;
timer_set_delay_u64(&data->callback_timer, time);
data->wait_time = 1;
}
if (data->callback == 0)
data->callback = 1;
return SCSI_PHASE_COMMAND;
}
@ -969,7 +964,7 @@ static int scsi_cd_command(uint8_t *cdb, void *p)
data->cmd_pos = CMD_POS_WAIT;
data->new_cmd_pos = CMD_POS_START_SECTOR;
data->wait_time = seek_time;
data->callback = 1000 * TIMER_USEC;
timer_set_delay_u64(&data->callback_timer, 1000 * TIMER_USEC);
return SCSI_PHASE_COMMAND;
}
}
@ -982,23 +977,21 @@ static int scsi_cd_command(uint8_t *cdb, void *p)
}
if (data->cmd_pos == CMD_POS_START_SECTOR)
{
uint64_t time = (((uint64_t)SECTOR_TIME * (uint64_t)TIMER_USEC) / data->cur_speed) * (uint64_t)data->cdlen;
uint64_t time = (((uint64_t)SECTOR_TIME * TIMER_USEC) / data->cur_speed) * (uint64_t)data->cdlen;
data->cmd_pos = CMD_POS_WAIT;
data->new_cmd_pos = CMD_POS_TRANSFER;
if (time > 0x7fffffffull)
if (time > (TIMER_USEC * 1000ull))
{
data->wait_time = (int)(time / ((uint64_t)TIMER_USEC * 1000ull));
data->callback = (int)(time % ((uint64_t)TIMER_USEC * 1000ull));;
data->wait_time = (int)(time / (TIMER_USEC * 1000ull));
timer_set_delay_u64(&data->callback_timer, time % (TIMER_USEC * 1000ull));
}
else
{
data->callback = time;
timer_set_delay_u64(&data->callback_timer, time);
data->wait_time = 1;
}
if (data->callback == 0)
data->callback = 1;
return SCSI_PHASE_COMMAND;
}
@ -1372,7 +1365,7 @@ atapi_out:
data->cmd_pos = CMD_POS_WAIT;
data->new_cmd_pos = CMD_POS_COMPLETE;
data->wait_time = seek_time;
data->callback = 1000 * TIMER_USEC;
timer_set_delay_u64(&data->callback_timer, 1000 * TIMER_USEC);
return SCSI_PHASE_COMMAND;
}
}

View file

@ -47,7 +47,7 @@ typedef struct scsi_hd_data
int hd_id;
int callback;
pc_timer_t callback_timer;
scsi_bus_t *bus;
} scsi_hd_data;
@ -56,8 +56,6 @@ static void scsi_hd_callback(void *p)
{
scsi_hd_data *data = p;
data->callback = 0;
if (data->cmd_pos == CMD_POS_WAIT)
{
data->cmd_pos = data->new_cmd_pos;
@ -80,7 +78,7 @@ static void *scsi_hd_init(scsi_bus_t *bus, int id)
data->hd_id = id;
data->bus = bus;
timer_add(scsi_hd_callback, &data->callback, &data->callback, data);
timer_add(&data->callback_timer, scsi_hd_callback, data, 0);
return data;
}
@ -464,7 +462,7 @@ static int scsi_hd_command(uint8_t *cdb, void *p)
// pclog("SCSI_READ_6: addr=%08x len=%04x\n", data->addr, data->len);
data->cmd_pos = CMD_POS_WAIT;
data->callback = RW_DELAY;
timer_set_delay_u64(&data->callback_timer, RW_DELAY);
data->new_cmd_pos = CMD_POS_START_SECTOR;
data->sector_pos = 0;
@ -524,7 +522,7 @@ static int scsi_hd_command(uint8_t *cdb, void *p)
// pclog("SCSI_READ_10: addr=%08x len=%04x\n", data->addr, data->len);
data->cmd_pos = CMD_POS_WAIT;
data->callback = RW_DELAY;
timer_set_delay_u64(&data->callback_timer, RW_DELAY);
data->new_cmd_pos = CMD_POS_START_SECTOR;
data->sector_pos = 0;
@ -585,7 +583,7 @@ static int scsi_hd_command(uint8_t *cdb, void *p)
data->bytes_required = data->len * 512;
data->cmd_pos = CMD_POS_WAIT;
data->callback = RW_DELAY;
timer_set_delay_u64(&data->callback_timer, RW_DELAY);
data->new_cmd_pos = CMD_POS_TRANSFER;
data->sector_pos = 0;
@ -644,7 +642,7 @@ static int scsi_hd_command(uint8_t *cdb, void *p)
data->bytes_required = data->len * 512;
data->cmd_pos = CMD_POS_WAIT;
data->callback = RW_DELAY;
timer_set_delay_u64(&data->callback_timer, RW_DELAY);
data->new_cmd_pos = CMD_POS_TRANSFER;
data->sector_pos = 0;

View file

@ -68,7 +68,7 @@ typedef struct scsi_zip_data
int hd_id;
int callback;
pc_timer_t callback_timer;
scsi_bus_t *bus;
@ -176,8 +176,6 @@ static void scsi_zip_callback(void *p)
{
scsi_zip_data *data = p;
data->callback = 0;
if (data->cmd_pos == CMD_POS_WAIT)
{
data->cmd_pos = data->new_cmd_pos;
@ -194,7 +192,7 @@ static void *scsi_zip_init(scsi_bus_t *bus, int id)
data->hd_id = id;
data->bus = bus;
timer_add(scsi_zip_callback, &data->callback, &data->callback, data);
timer_add(&data->callback_timer, scsi_zip_callback, data, 0);
zip_data = data;
return data;
@ -689,7 +687,7 @@ static int scsi_zip_command(uint8_t *cdb, void *p)
// pclog("SCSI_READ_6: addr=%08x len=%04x\n", data->addr, data->len);
data->cmd_pos = CMD_POS_WAIT;
data->callback = RW_DELAY;
timer_set_delay_u64(&data->callback_timer, RW_DELAY);
data->new_cmd_pos = CMD_POS_START_SECTOR;
data->sector_pos = 0;
@ -750,7 +748,7 @@ static int scsi_zip_command(uint8_t *cdb, void *p)
// pclog("SCSI_READ_10: addr=%08x len=%04x\n", data->addr, data->len);
data->cmd_pos = CMD_POS_WAIT;
data->callback = RW_DELAY;
timer_set_delay_u64(&data->callback_timer, RW_DELAY);
data->new_cmd_pos = CMD_POS_START_SECTOR;
data->sector_pos = 0;
@ -819,7 +817,7 @@ static int scsi_zip_command(uint8_t *cdb, void *p)
data->bytes_required = data->len * 512;
data->cmd_pos = CMD_POS_WAIT;
data->callback = RW_DELAY;
timer_set_delay_u64(&data->callback_timer, RW_DELAY);
data->new_cmd_pos = CMD_POS_TRANSFER;
data->sector_pos = 0;
@ -887,7 +885,7 @@ static int scsi_zip_command(uint8_t *cdb, void *p)
data->bytes_required = data->len * 512;
data->cmd_pos = CMD_POS_WAIT;
data->callback = RW_DELAY;
timer_set_delay_u64(&data->callback_timer, RW_DELAY);
data->new_cmd_pos = CMD_POS_TRANSFER;
data->sector_pos = 0;

View file

@ -35,7 +35,7 @@ void serial_update_ints(SERIAL *serial)
stat = 1;
serial->iir = 6;
}
else if ((serial->ier & 1) && (serial->int_status & SERIAL_INT_RECEIVE)) /*Recieved data available*/
else if ((serial->ier & 1) && (serial->int_status & SERIAL_INT_RECEIVE)) /*Received data available*/
{
stat = 1;
serial->iir = 4;
@ -185,7 +185,7 @@ uint8_t serial_read(uint16_t addr, void *p)
serial_update_ints(serial);
temp = serial_read_fifo(serial);
if (serial->fifo_read != serial->fifo_write)
serial->recieve_delay = 1000 * TIMER_USEC;
timer_set_delay_u64(&serial->receive_timer, 1000 * TIMER_USEC);
break;
case 1:
if (serial->lcr & 0x80)
@ -234,12 +234,10 @@ uint8_t serial_read(uint16_t addr, void *p)
return temp;
}
void serial_recieve_callback(void *p)
void serial_receive_callback(void *p)
{
SERIAL *serial = (SERIAL *)p;
serial->recieve_delay = 0;
if (serial->fifo_read != serial->fifo_write)
{
serial->lsr |= 1;
@ -256,7 +254,7 @@ void serial1_init(uint16_t addr, int irq)
serial1.irq = irq;
serial1.addr = addr;
serial1.rcr_callback = NULL;
timer_add(serial_recieve_callback, &serial1.recieve_delay, &serial1.recieve_delay, &serial1);
timer_add(&serial1.receive_timer, serial_receive_callback, &serial1, 0);
}
void serial1_set(uint16_t addr, int irq)
{
@ -277,7 +275,7 @@ void serial2_init(uint16_t addr, int irq)
serial2.irq = irq;
serial2.addr = addr;
serial2.rcr_callback = NULL;
timer_add(serial_recieve_callback, &serial2.recieve_delay, &serial2.recieve_delay, &serial2);
timer_add(&serial2.receive_timer, serial_receive_callback, &serial2, 0);
}
void serial2_set(uint16_t addr, int irq)
{

View file

@ -1,3 +1,5 @@
#include "timer.h"
void serial1_init(uint16_t addr, int irq);
void serial2_init(uint16_t addr, int irq);
void serial1_set(uint16_t addr, int irq);
@ -25,7 +27,7 @@ typedef struct
uint8_t fifo[256];
int fifo_read, fifo_write;
int recieve_delay;
pc_timer_t receive_timer;
} SERIAL;
void serial_write_fifo(SERIAL *serial, uint8_t dat);

View file

@ -114,7 +114,8 @@ static struct
static int sound_handlers_num;
static int sound_poll_time = 0, sound_poll_latch;
static pc_timer_t sound_poll_timer;
static uint64_t sound_poll_latch;
int sound_pos_global = 0;
int soundon = 1;
@ -226,7 +227,7 @@ void sound_add_handler(void (*get_buffer)(int32_t *buffer, int len, void *p), vo
static int cd_pos = 0;
void sound_poll(void *priv)
{
sound_poll_time += sound_poll_latch;
timer_advance_u64(&sound_poll_timer, sound_poll_latch);
cd_pos++;
if (cd_pos == (CD_BUFLEN * 48000) / CD_FREQ)
@ -269,12 +270,12 @@ void sound_poll(void *priv)
void sound_speed_changed()
{
sound_poll_latch = (int)((double)TIMER_USEC * (1000000.0 / 48000.0));
sound_poll_latch = (uint64_t)((double)TIMER_USEC * (1000000.0 / 48000.0));
}
void sound_reset()
{
timer_add(sound_poll, &sound_poll_time, TIMER_ALWAYS_ENABLED, NULL);
timer_add(&sound_poll_timer, sound_poll, NULL, 1);
sound_handlers_num = 0;

View file

@ -71,9 +71,19 @@ void ad1848_write(uint16_t addr, uint8_t val, void *p)
break;
case 9:
if (!ad1848->enable && (val & 0x41) == 0x01)
{
if (ad1848->timer_latch)
timer_advance_u64(&ad1848->timer, ad1848->timer_latch);
else
timer_advance_u64(&ad1848->timer, TIMER_USEC);
}
ad1848->enable = ((val & 0x41) == 0x01);
if (!ad1848->enable)
{
timer_disable(&ad1848->timer);
ad1848->out_l = ad1848->out_r = 0;
}
break;
case 12:
@ -93,7 +103,7 @@ void ad1848_write(uint16_t addr, uint8_t val, void *p)
void ad1848_speed_changed(ad1848_t *ad1848)
{
ad1848->timer_latch = (int)((double)TIMER_USEC * (1000000.0 / (double)ad1848->freq));
ad1848->timer_latch = (uint64_t)((double)TIMER_USEC * (1000000.0 / (double)ad1848->freq));
}
void ad1848_update(ad1848_t *ad1848)
@ -110,9 +120,9 @@ static void ad1848_poll(void *p)
ad1848_t *ad1848 = (ad1848_t *)p;
if (ad1848->timer_latch)
ad1848->timer_count += ad1848->timer_latch;
timer_advance_u64(&ad1848->timer, ad1848->timer_latch);
else
ad1848->timer_count = TIMER_USEC;
timer_advance_u64(&ad1848->timer, TIMER_USEC);
ad1848_update(ad1848);
@ -214,5 +224,5 @@ void ad1848_init(ad1848_t *ad1848)
// pclog("ad1848_vols %i = %f %i\n", c, attenuation, ad1848_vols[c]);
}
timer_add(ad1848_poll, &ad1848->timer_count, &ad1848->enable, ad1848);
timer_add(&ad1848->timer, ad1848_poll, ad1848, 0);
}

View file

@ -19,7 +19,8 @@ typedef struct ad1848_t
int freq;
int timer_count, timer_latch;
pc_timer_t timer;
uint64_t timer_latch;
int16_t buffer[MAXSOUNDBUFLEN * 2];
int pos;

View file

@ -36,7 +36,7 @@ typedef struct adgold_t
int16_t adgold_mma_out[2];
int adgold_mma_intpos[2];
int adgold_mma_timer_count;
pc_timer_t adgold_mma_timer;
struct
{
@ -586,9 +586,10 @@ void adgold_timer_poll(void *p)
{
adgold_t *adgold = (adgold_t *)p;
while (adgold->adgold_mma_timer_count <= 0)
{
adgold->adgold_mma_timer_count += (int)((double)TIMER_USEC * 1.88964);
timer_advance_u64(&adgold->adgold_mma_timer, (uint64_t)((double)TIMER_USEC * 1.88964));
// while (adgold->adgold_mma_timer_count <= 0)
// {
// adgold->adgold_mma_timer_count += (int)((double)TIMER_USEC * 1.88964);
if (adgold->adgold_mma_regs[0][8] & 0x01) /*Timer 0*/
{
adgold->adgold_mma.timer0_count--;
@ -649,7 +650,7 @@ void adgold_timer_poll(void *p)
adgold_mma_poll(adgold, 1);
}
}
}
// }
}
static void adgold_get_buffer(int32_t *buffer, int len, void *p)
@ -817,7 +818,7 @@ void *adgold_init()
/*388/389 are handled by adlib_init*/
io_sethandler(0x0388, 0x0008, adgold_read, NULL, NULL, adgold_write, NULL, NULL, adgold);
timer_add(adgold_timer_poll, &adgold->adgold_mma_timer_count, TIMER_ALWAYS_ENABLED, adgold);
timer_add(&adgold->adgold_mma_timer, adgold_timer_poll, adgold, 1);
sound_add_handler(adgold_get_buffer, adgold);

View file

@ -49,7 +49,8 @@ typedef struct es1371_t
uint16_t samp_ct, curr_samp_ct;
int time, latch;
pc_timer_t timer;
uint64_t latch;
uint32_t vf, ac;
@ -1077,7 +1078,7 @@ static void es1371_poll(void *p)
{
es1371_t *es1371 = (es1371_t *)p;
es1371->dac[1].time += es1371->dac[1].latch;
timer_advance_u64(&es1371->dac[1].timer, es1371->dac[1].latch);
es1371_update(es1371);
@ -1205,7 +1206,7 @@ static void *es1371_init()
es1371->card = pci_add(es1371_pci_read, es1371_pci_write, es1371);
timer_add(es1371_poll, &es1371->dac[1].time, TIMER_ALWAYS_ENABLED, es1371);
timer_add(&es1371->dac[1].timer, es1371_poll, es1371, 1);
generate_es1371_filter();

View file

@ -42,13 +42,14 @@ typedef struct gus_t
int16_t buffer[2][MAXSOUNDBUFLEN];
int pos;
int samp_timer, samp_latch;
pc_timer_t samp_timer;
uint64_t samp_latch;
uint8_t *ram;
int irqnext;
int timer_1, timer_2;
pc_timer_t timer_1, timer_2;
int irq, dma, irq_midi;
int latch_enable;
@ -365,9 +366,9 @@ gus->curx[gus->voice]=(gus->curx[gus->voice]&0xFFF8000)|((val&0x7F)<<8);
gus->global=val;
// printf("GUS voices %i\n",val&31);
if (gus->voices < 14)
gus->samp_latch = (int)(TIMER_USEC * (1000000.0 / 44100.0));
gus->samp_latch = (uint64_t)(TIMER_USEC * (1000000.0 / 44100.0));
else
gus->samp_latch = (int)(TIMER_USEC * (1000000.0 / gusfreqs[gus->voices - 14]));
gus->samp_latch = (uint64_t)(TIMER_USEC * (1000000.0 / gusfreqs[gus->voices - 14]));
break;
case 0x41: /*DMA*/
@ -824,7 +825,7 @@ void gus_poll_timer_1(void *p)
{
gus_t *gus = (gus_t *)p;
gus->timer_1 += (TIMER_USEC * 80);
timer_advance_u64(&gus->timer_1, (uint64_t)(TIMER_USEC * 80));
// pclog("gus_poll_timer_1 %i %i %i %i %02X\n", gustime, gus->t1on, gus->t1, gus->t1l, gus->tctrl);
if (gus->t1on)
{
@ -859,7 +860,7 @@ void gus_poll_timer_2(void *p)
{
gus_t *gus = (gus_t *)p;
gus->timer_2 += (TIMER_USEC * 320);
timer_advance_u64(&gus->timer_2, (uint64_t)(TIMER_USEC * 320));
// pclog("pollgus2 %i %i %i %i %02X\n", gustime, gus->t2on, gus->t2, gus->t2l, gus->tctrl);
if (gus->t2on)
{
@ -919,7 +920,7 @@ void gus_poll_wave(void *p)
gus_update(gus);
gus->samp_timer += gus->samp_latch;
timer_advance_u64(&gus->samp_timer, gus->samp_latch);
gus->out_l = gus->out_r = 0;
@ -1120,7 +1121,7 @@ void *gus_init()
printf("Top volume %f %f %f %f\n",vol16bit[4095],vol16bit[3800],vol16bit[3000],vol16bit[2048]);
gus->voices=14;
gus->samp_timer = gus->samp_latch = (int)(TIMER_USEC * (1000000.0 / 44100.0));
gus->samp_latch = (uint64_t)(TIMER_USEC * (1000000.0 / 44100.0));
gus->t1l = gus->t2l = 0xff;
@ -1128,9 +1129,9 @@ void *gus_init()
io_sethandler(0x0340, 0x0010, readgus, NULL, NULL, writegus, NULL, NULL, gus);
io_sethandler(0x0746, 0x0001, readgus, NULL, NULL, writegus, NULL, NULL, gus);
io_sethandler(0x0388, 0x0002, readgus, NULL, NULL, writegus, NULL, NULL, gus);
timer_add(gus_poll_wave, &gus->samp_timer, TIMER_ALWAYS_ENABLED, gus);
timer_add(gus_poll_timer_1, &gus->timer_1, TIMER_ALWAYS_ENABLED, gus);
timer_add(gus_poll_timer_2, &gus->timer_2, TIMER_ALWAYS_ENABLED, gus);
timer_add(&gus->samp_timer, gus_poll_wave, gus, 1);
timer_add(&gus->timer_1, gus_poll_timer_1, gus, 1);
timer_add(&gus->timer_2, gus_poll_timer_2, gus, 1);
sound_add_handler(gus_get_buffer, gus);
@ -1150,9 +1151,9 @@ void gus_speed_changed(void *p)
gus_t *gus = (gus_t *)p;
if (gus->voices < 14)
gus->samp_latch = (int)(TIMER_USEC * (1000000.0 / 44100.0));
gus->samp_latch = (uint64_t)(TIMER_USEC * (1000000.0 / 44100.0));
else
gus->samp_latch = (int)(TIMER_USEC * (1000000.0 / gusfreqs[gus->voices - 14]));
gus->samp_latch = (uint64_t)(TIMER_USEC * (1000000.0 / gusfreqs[gus->voices - 14]));
}
device_t gus_device =

View file

@ -106,54 +106,45 @@ void ym3812_timer_set_0(void *param, int timer, int64_t period)
{
opl_t *opl = (opl_t *)param;
opl->timers[0][timer] = period * TIMER_USEC * 20;
if (!opl->timers[0][timer]) opl->timers[0][timer] = 1;
opl->timers_enable[0][timer] = period ? 1 : 0;
if (period)
timer_set_delay_u64(&opl->timers[0][timer], period * TIMER_USEC * 20);
else
timer_disable(&opl->timers[0][timer]);
}
void ym3812_timer_set_1(void *param, int timer, int64_t period)
{
opl_t *opl = (opl_t *)param;
opl->timers[1][timer] = period * TIMER_USEC * 20;
if (!opl->timers[1][timer]) opl->timers[1][timer] = 1;
opl->timers_enable[1][timer] = period ? 1 : 0;
if (period)
timer_set_delay_u64(&opl->timers[1][timer], period * TIMER_USEC * 20);
else
timer_disable(&opl->timers[1][timer]);
}
void ymf262_timer_set(void *param, int timer, int64_t period)
{
opl_t *opl = (opl_t *)param;
opl->timers[0][timer] = period * TIMER_USEC * 20;
if (!opl->timers[0][timer]) opl->timers[0][timer] = 1;
opl->timers_enable[0][timer] = period ? 1 : 0;
if (period)
timer_set_delay_u64(&opl->timers[0][timer], period * TIMER_USEC * 20);
else
timer_disable(&opl->timers[0][timer]);
}
static void opl_timer_callback00(void *p)
{
opl_t *opl = (opl_t *)p;
opl->timers_enable[0][0] = 0;
opl_timer_over(0, 0);
}
static void opl_timer_callback01(void *p)
{
opl_t *opl = (opl_t *)p;
opl->timers_enable[0][1] = 0;
opl_timer_over(0, 1);
}
static void opl_timer_callback10(void *p)
{
opl_t *opl = (opl_t *)p;
opl->timers_enable[1][0] = 0;
opl_timer_over(1, 0);
}
static void opl_timer_callback11(void *p)
{
opl_t *opl = (opl_t *)p;
opl->timers_enable[1][1] = 0;
opl_timer_over(1, 1);
}
@ -161,16 +152,16 @@ void opl2_init(opl_t *opl)
{
opl_init(ym3812_timer_set_0, opl, 0, 0, 0);
opl_init(ym3812_timer_set_1, opl, 1, 0, 0);
timer_add(opl_timer_callback00, &opl->timers[0][0], &opl->timers_enable[0][0], (void *)opl);
timer_add(opl_timer_callback01, &opl->timers[0][1], &opl->timers_enable[0][1], (void *)opl);
timer_add(opl_timer_callback10, &opl->timers[1][0], &opl->timers_enable[1][0], (void *)opl);
timer_add(opl_timer_callback11, &opl->timers[1][1], &opl->timers_enable[1][1], (void *)opl);
timer_add(&opl->timers[0][0], opl_timer_callback00, (void *)opl, 0);
timer_add(&opl->timers[0][1], opl_timer_callback01, (void *)opl, 0);
timer_add(&opl->timers[1][0], opl_timer_callback10, (void *)opl, 0);
timer_add(&opl->timers[1][1], opl_timer_callback11, (void *)opl, 0);
}
void opl3_init(opl_t *opl, int opl_emu)
{
opl_init(ymf262_timer_set, opl, 0, 1, opl_emu);
timer_add(opl_timer_callback00, &opl->timers[0][0], &opl->timers_enable[0][0], (void *)opl);
timer_add(opl_timer_callback01, &opl->timers[0][1], &opl->timers_enable[0][1], (void *)opl);
timer_add(&opl->timers[0][0], opl_timer_callback00, (void *)opl, 0);
timer_add(&opl->timers[0][1], opl_timer_callback01, (void *)opl, 0);
}

View file

@ -4,8 +4,7 @@ typedef struct opl_t
{
int chip_nr[2];
int timers[2][2];
int timers_enable[2][2];
pc_timer_t timers[2][2];
int16_t filtbuf[2];

View file

@ -118,7 +118,8 @@ typedef struct pas16_t
struct
{
uint32_t l[3];
int c[3];
int c[3];
pc_timer_t timer[3];
uint8_t m[3];
uint8_t ctrl, ctrls[2];
int wp, rm[3], wm[3];
@ -398,7 +399,7 @@ static void pas16_pit_out(uint16_t port, uint8_t val, void *p)
{
if (!(val & 0x20))
{
if (val & 2) pas16->pit.rl[0] = pas16->pit.c[0] / (PITCONST * (1 << TIMER_SHIFT));
if (val & 2) pas16->pit.rl[0] = timer_get_remaining_u64(&pit.timer[0]) / PITCONST;;
if (val & 4) pas16->pit.rl[1] = pas16->pit.c[1];
if (val & 8) pas16->pit.rl[2] = pas16->pit.c[2];
}
@ -413,11 +414,14 @@ static void pas16_pit_out(uint16_t port, uint8_t val, void *p)
}
if (!(pas16->pit.ctrl & 0x30))
{
pas16->pit.rl[t] = pas16->pit.c[t];
if (!t)
pas16->pit.rl[t] /= (PITCONST * (1 << TIMER_SHIFT));
if (pas16->pit.c[t] < 0)
pas16->pit.rl[t] = 0;
if (!t)
pas16->pit.rl[t] = timer_get_remaining_u64(&pit.timer[t]) / PITCONST;
else
{
pas16->pit.rl[t] = pas16->pit.c[t];
if (pas16->pit.c[t] < 0)
pas16->pit.rl[t] = 0;
}
pas16->pit.ctrl |= 0x30;
pas16->pit.rereadlatch[t] = 0;
pas16->pit.rm[t] = 3;
@ -431,9 +435,10 @@ static void pas16_pit_out(uint16_t port, uint8_t val, void *p)
if (!pas16->pit.rm[t])
{
pas16->pit.rm[t] = 3;
pas16->pit.rl[t] = pit.c[t];
if (!t)
pas16->pit.rl[t] /= (PITCONST * (1 << TIMER_SHIFT));
if (!t)
pas16->pit.rl[t] = timer_get_remaining_u64(&pit.timer[t]) / PITCONST;
else
pas16->pit.rl[t] = pas16->pit.c[t];
}
pas16->pit.rereadlatch[t] = 1;
}
@ -449,7 +454,7 @@ static void pas16_pit_out(uint16_t port, uint8_t val, void *p)
pas16->pit.thit[t] = 0;
pas16->pit.c[t] = pas16->pit.l[t];
if (!t)
pas16->pit.c[t] *= PITCONST * (1 << TIMER_SHIFT);
timer_set_delay_u64(&pas16->pit.timer[t], pas16->pit.c[t] * PITCONST);
pas16->pit.enable[t] = 1;
break;
case 2:
@ -457,7 +462,7 @@ static void pas16_pit_out(uint16_t port, uint8_t val, void *p)
pas16->pit.thit[t] = 0;
pas16->pit.c[t] = pas16->pit.l[t];
if (!t)
pas16->pit.c[t] *= PITCONST * (1 << TIMER_SHIFT);
timer_set_delay_u64(&pas16->pit.timer[t], pas16->pit.c[t] * PITCONST);
pas16->pit.enable[t] = 1;
break;
case 0:
@ -465,7 +470,7 @@ static void pas16_pit_out(uint16_t port, uint8_t val, void *p)
pas16->pit.l[t] |= (val << 8);
pas16->pit.c[t] = pas16->pit.l[t];
if (!t)
pas16->pit.c[t] *= PITCONST * (1 << TIMER_SHIFT);
timer_set_delay_u64(&pas16->pit.timer[t], pas16->pit.c[t] * PITCONST);
pas16->pit.thit[t] = 0;
pas16->pit.wm[t] = 3;
pas16->pit.enable[t] = 1;
@ -481,7 +486,7 @@ static void pas16_pit_out(uint16_t port, uint8_t val, void *p)
pas16->pit.l[t] |= 0x10000;
pas16->pit.c[t] = pas16->pit.l[t];
if (!t)
pas16->pit.c[t] *= PITCONST * (1 << TIMER_SHIFT);
timer_set_delay_u64(&pas16->pit.timer[t], pas16->pit.c[t] * PITCONST);
}
break;
}
@ -501,8 +506,8 @@ static uint8_t pas16_pit_in(uint16_t port, void *p)
pas16->pit.rereadlatch[t] = 0;
if (!t)
{
pas16->pit.rl[t] = pas16->pit.c[t] / (PITCONST * (1 << TIMER_SHIFT));
if ((pas16->pit.c[t] / (PITCONST * (1 << TIMER_SHIFT))) > 65536)
pas16->pit.rl[t] = timer_get_remaining_u64(&pit.timer[t]) / PITCONST;
if ((timer_get_remaining_u64(&pit.timer[t]) / PITCONST) > 65536)
pas16->pit.rl[t] = 0xFFFF;
}
else
@ -557,13 +562,12 @@ static void pas16_pcm_poll(void *p)
if (pas16->pit.m[0] & 2)
{
if (pas16->pit.l[0])
pas16->pit.c[0] += (pas16->pit.l[0] * PITCONST * (1 << TIMER_SHIFT));
timer_advance_u64(&pas16->pit.timer[0], pas16->pit.l[0] * PITCONST);
else
pas16->pit.c[0] += (0x10000 * PITCONST * (1 << TIMER_SHIFT));
timer_advance_u64(&pas16->pit.timer[0], 0x10000 * PITCONST);
}
else
{
pas16->pit.c[0] = -1;
pas16->pit.enable[0] = 0;
}
// if (pas16->pcm_ctrl & PAS16_PCM_ENA)
@ -736,7 +740,7 @@ void *pas16_init()
io_sethandler(0x9a01, 0x0001, NULL, NULL, NULL, pas16_out_base, NULL, NULL, pas16);
timer_add(pas16_pcm_poll, &pas16->pit.c[0], &pas16->pit.enable[0], pas16);
timer_add(&pas16->pit.timer[0], pas16_pcm_poll, pas16, 0);
sound_add_handler(pas16_get_buffer, pas16);

View file

@ -13,7 +13,8 @@ typedef struct ps1_audio_t
uint8_t status, ctrl;
int timer_latch, timer_count, timer_enable;
uint64_t timer_latch;
pc_timer_t timer;
uint8_t fifo[2048];
int fifo_read_idx, fifo_write_idx;
@ -89,8 +90,10 @@ static void ps1_audio_write(uint16_t port, uint8_t val, void *p)
break;
case 3: /*Timer reload value*/
ps1->timer_latch = val;
ps1->timer_count = (0xff-val) * TIMER_USEC;
ps1->timer_enable = (val != 0);
if (val)
timer_set_delay_u64(&ps1->timer, (0xff-val) * TIMER_USEC);
else
timer_disable(&ps1->timer);
break;
case 4: /*Almost empty*/
ps1->fifo_threshold = val * 4;
@ -124,7 +127,7 @@ static void ps1_audio_callback(void *p)
ps1->status |= 0x10; /*ADC data ready*/
ps1_update_irq_status(ps1);
ps1->timer_count += ps1->timer_latch * TIMER_USEC;
timer_advance_u64(&ps1->timer, ps1->timer_latch * TIMER_USEC);
}
static void ps1_audio_get_buffer(int32_t *buffer, int len, void *p)
@ -149,7 +152,7 @@ static void *ps1_audio_init()
io_sethandler(0x0200, 0x0001, ps1_audio_read, NULL, NULL, ps1_audio_write, NULL, NULL, ps1);
io_sethandler(0x0202, 0x0006, ps1_audio_read, NULL, NULL, ps1_audio_write, NULL, NULL, ps1);
timer_add(ps1_audio_callback, &ps1->timer_count, &ps1->timer_enable, ps1);
timer_add(&ps1->timer, ps1_audio_callback, ps1, 0);
sound_add_handler(ps1_audio_get_buffer, ps1);
return ps1;

View file

@ -21,7 +21,7 @@ typedef struct pssj_t
int amplitude;
int irq;
int timer_count;
pc_timer_t timer;
int enable;
int wave_pos;
@ -46,7 +46,13 @@ static void pssj_write(uint16_t port, uint8_t val, void *p)
{
case 0:
pssj->ctrl = val;
if (!pssj->enable && ((val & 4) && (pssj->ctrl & 3)))
timer_set_delay_u64(&pssj->timer, (TIMER_USEC * (1000000.0 / 3579545.0) * (double)(pssj->freq ? pssj->freq : 0x400)));
pssj->enable = (val & 4) && (pssj->ctrl & 3);
if (!pssj->enable)
timer_disable(&pssj->timer);
sn74689_set_extra_divide(&pssj->sn76489, val & 0x40);
if (!(val & 8))
pssj->irq = 0;
@ -166,7 +172,7 @@ static void pssj_callback(void *p)
pssj->wave_pos = (pssj->wave_pos + 1) & 31;
}
pssj->timer_count += (int)(TIMER_USEC * (1000000.0 / 3579545.0) * (double)(pssj->freq ? pssj->freq : 0x400));
timer_advance_u64(&pssj->timer, (TIMER_USEC * (1000000.0 / 3579545.0) * (double)(pssj->freq ? pssj->freq : 0x400)));
}
static void pssj_get_buffer(int32_t *buffer, int len, void *p)
@ -190,7 +196,7 @@ void *pssj_init()
sn76489_init(&pssj->sn76489, 0x00c0, 0x0004, PSSJ, 3579545);
io_sethandler(0x00C4, 0x0004, pssj_read, NULL, NULL, pssj_write, NULL, NULL, pssj);
timer_add(pssj_callback, &pssj->timer_count, &pssj->enable, pssj);
timer_add(&pssj->timer, pssj_callback, pssj, 0);
sound_add_handler(pssj_get_buffer, pssj);
return pssj;

View file

@ -164,7 +164,9 @@ void sb_irqc(sb_dsp_t *dsp, int irq8)
void sb_dsp_reset(sb_dsp_t *dsp)
{
dsp->sbenable = dsp->sb_enable_i = 0;
timer_disable(&dsp->output_timer);
timer_disable(&dsp->input_timer);
dsp->sb_command = 0;
dsp->sb_8_length = 0xffff;
@ -181,7 +183,6 @@ void sb_dsp_reset(sb_dsp_t *dsp)
dsp->sbe2count = 0;
dsp->sbreset = 0;
dsp->sbenable = dsp->sb_enable_i = dsp->sb_count_i = 0;
dsp->record_pos_read=0;
dsp->record_pos_write=SB_DSP_REC_SAFEFTY_MARGIN;
@ -219,12 +220,12 @@ void sb_dsp_speed_changed(sb_dsp_t *dsp)
if (dsp->sb_timeo < 256)
dsp->sblatcho = TIMER_USEC * (256 - dsp->sb_timeo);
else
dsp->sblatcho = (int)(TIMER_USEC * (1000000.0f / (float)(dsp->sb_timeo - 256)));
dsp->sblatcho = (uint64_t)(TIMER_USEC * (1000000.0f / (float)(dsp->sb_timeo - 256)));
if (dsp->sb_timei < 256)
dsp->sblatchi = TIMER_USEC * (256 - dsp->sb_timei);
else
dsp->sblatchi = (int)(TIMER_USEC * (1000000.0f / (float)(dsp->sb_timei - 256)));
dsp->sblatchi = (uint64_t)(TIMER_USEC * (1000000.0f / (float)(dsp->sb_timei - 256)));
}
void sb_add_data(sb_dsp_t *dsp, uint8_t v)
@ -249,9 +250,8 @@ void sb_start_dma(sb_dsp_t *dsp, int dma8, int autoinit, uint8_t format, int len
dsp->sb_8_enable = 1;
if (dsp->sb_16_enable && dsp->sb_16_output) dsp->sb_16_enable = 0;
dsp->sb_8_output = 1;
timer_process();
dsp->sbenable = dsp->sb_8_enable;
timer_update_outstanding();
if (!timer_is_enabled(&dsp->output_timer))
timer_set_delay_u64(&dsp->output_timer, dsp->sblatcho);
dsp->sbleftright = 0;
dsp->sbdacpos = 0;
// pclog("Start 8-bit DMA addr %06X len %04X\n",dma.ac[1]+(dma.page[1]<<16),len);
@ -265,9 +265,8 @@ void sb_start_dma(sb_dsp_t *dsp, int dma8, int autoinit, uint8_t format, int len
dsp->sb_16_enable = 1;
if (dsp->sb_8_enable && dsp->sb_8_output) dsp->sb_8_enable = 0;
dsp->sb_16_output = 1;
timer_process();
dsp->sbenable = dsp->sb_16_enable;
timer_update_outstanding();
if (!timer_is_enabled(&dsp->output_timer))
timer_set_delay_u64(&dsp->output_timer, dsp->sblatcho);
// pclog("Start 16-bit DMA addr %06X len %04X\n",dma16.ac[1]+(dma16.page[1]<<16),len);
}
}
@ -290,9 +289,8 @@ void sb_start_dma_i(sb_dsp_t *dsp, int dma8, int autoinit, uint8_t format, int l
dsp->sb_8_enable = 1;
if (dsp->sb_16_enable && !dsp->sb_16_output) dsp->sb_16_enable = 0;
dsp->sb_8_output = 0;
timer_process();
dsp->sb_enable_i = dsp->sb_8_enable;
timer_update_outstanding();
if (!timer_is_enabled(&dsp->input_timer))
timer_set_delay_u64(&dsp->input_timer, dsp->sblatchi);
// pclog("Start 8-bit input DMA addr %06X len %04X\n",dma.ac[1]+(dma.page[1]<<16),len);
}
else
@ -311,9 +309,8 @@ void sb_start_dma_i(sb_dsp_t *dsp, int dma8, int autoinit, uint8_t format, int l
dsp->sb_16_enable = 1;
if (dsp->sb_8_enable && !dsp->sb_8_output) dsp->sb_8_enable = 0;
dsp->sb_16_output = 0;
timer_process();
dsp->sb_enable_i = dsp->sb_16_enable;
timer_update_outstanding();
if (!timer_is_enabled(&dsp->input_timer))
timer_set_delay_u64(&dsp->input_timer, dsp->sblatchi);
// pclog("Start 16-bit input DMA addr %06X len %04X\n",dma.ac[1]+(dma.page[1]<<16),len);
}
memset(dsp->record_buffer,0,sizeof(dsp->record_buffer));
@ -413,15 +410,13 @@ void sb_exec_command(sb_dsp_t *dsp)
sb_add_data(dsp, (dsp->record_buffer[dsp->record_pos_read]>>8) ^0x80);
/*Due to the current implementation, I need to emulate a samplerate, even if this
* mode does not imply such samplerate. Position is increased in sb_poll_i*/
if (dsp->sb_enable_i==0)
if (!timer_is_enabled(&dsp->input_timer))
{
dsp->sb_timei = 256 - 22;
dsp->sblatchi = TIMER_USEC * 22;
temp = 1000000 / 22;
dsp->sb_freq = temp;
timer_process();
dsp->sb_enable_i = 1;
timer_update_outstanding();
timer_set_delay_u64(&dsp->input_timer, dsp->sblatchi);
}
break;
case 0x24: /*8-bit single cycle DMA input*/
@ -444,7 +439,7 @@ void sb_exec_command(sb_dsp_t *dsp)
case 0x41: /*Set output sampling rate*/
case 0x42: /*Set input sampling rate*/
if (dsp->sb_type < SB16) break;
dsp->sblatcho = (int)(TIMER_USEC * (1000000.0f / (float)(dsp->sb_data[1] + (dsp->sb_data[0] << 8))));
dsp->sblatcho = (uint64_t)(TIMER_USEC * (1000000.0f / (float)(dsp->sb_data[1] + (dsp->sb_data[0] << 8))));
// pclog("Sample rate - %ihz (%i)\n",dsp->sb_data[1]+(dsp->sb_data[0]<<8), dsp->sblatcho);
temp = dsp->sb_freq;
dsp->sb_freq = dsp->sb_data[1] + (dsp->sb_data[0] << 8);
@ -494,9 +489,8 @@ void sb_exec_command(sb_dsp_t *dsp)
case 0x80: /*Pause DAC*/
dsp->sb_pausetime = dsp->sb_data[0] + (dsp->sb_data[1] << 8);
// pclog("SB pause %04X\n",sb_pausetime);
timer_process();
dsp->sbenable = 1;
timer_update_outstanding();
if (!timer_is_enabled(&dsp->output_timer))
timer_set_delay_u64(&dsp->output_timer, dsp->sblatcho);
break;
case 0x90: /*High speed 8-bit autoinit DMA output*/
if (dsp->sb_type < SB2) break;
@ -686,10 +680,7 @@ void sb_write(uint16_t a, uint8_t v, void *priv)
dsp->sbreset = v;
return;
case 0xC: /*Command/data write*/
timer_process();
dsp->wb_time = TIMER_USEC * 1;
dsp->wb_full = 1;
timer_update_outstanding();
timer_set_delay_u64(&dsp->wb_timer, TIMER_USEC * 1);
if (dsp->asp_data_len)
{
// pclog("ASP data %i\n", dsp->asp_data_len);
@ -740,7 +731,7 @@ uint8_t sb_read(uint16_t a, void *priv)
dsp->busy_count = 0;
if (dsp->wb_full || (dsp->busy_count & 2))
{
dsp->wb_full = dsp->wb_time;
dsp->wb_full = timer_is_enabled(&dsp->wb_timer);
return 0xff;
}
return 0x7f;
@ -758,9 +749,6 @@ uint8_t sb_read(uint16_t a, void *priv)
static void sb_wb_clear(void *p)
{
sb_dsp_t *dsp = (sb_dsp_t *)p;
dsp->wb_time = 0;
}
void sb_dsp_init(sb_dsp_t *dsp, int type)
@ -774,9 +762,9 @@ void sb_dsp_init(sb_dsp_t *dsp, int type)
sb_doreset(dsp);
timer_add(pollsb, &dsp->sbcount, &dsp->sbenable, dsp);
timer_add(sb_poll_i, &dsp->sb_count_i, &dsp->sb_enable_i, dsp);
timer_add(sb_wb_clear, &dsp->wb_time, &dsp->wb_time, dsp);
timer_add(&dsp->output_timer, pollsb, dsp, 0);
timer_add(&dsp->input_timer, sb_poll_i, dsp, 0);
timer_add(&dsp->wb_timer, sb_wb_clear, dsp, 0);
/*Initialise SB16 filter to same cutoff as 8-bit SBs (3.2 kHz). This will be recalculated when
a set frequency command is sent.*/
@ -806,7 +794,8 @@ void pollsb(void *p)
sb_dsp_t *dsp = (sb_dsp_t *)p;
int tempi,ref;
dsp->sbcount += dsp->sblatcho;
timer_advance_u64(&dsp->output_timer, dsp->sblatcho);
// pclog("PollSB %i %i %i %i\n",sb_8_enable,sb_8_pause,sb_pausetime,sb_8_output);
if (dsp->sb_8_enable && !dsp->sb_8_pause && dsp->sb_pausetime < 0 && dsp->sb_8_output)
{
@ -970,8 +959,13 @@ void pollsb(void *p)
if (dsp->sb_8_length < 0)
{
if (dsp->sb_8_autoinit) dsp->sb_8_length = dsp->sb_8_autolen;
else dsp->sb_8_enable = dsp->sbenable=0;
if (dsp->sb_8_autoinit)
dsp->sb_8_length = dsp->sb_8_autolen;
else
{
dsp->sb_8_enable = 0;
timer_disable(&dsp->output_timer);
}
sb_irq(dsp, 1);
}
}
@ -1022,8 +1016,13 @@ void pollsb(void *p)
if (dsp->sb_16_length < 0)
{
// pclog("16DMA over %i\n",dsp->sb_16_autoinit);
if (dsp->sb_16_autoinit) dsp->sb_16_length = dsp->sb_16_autolen;
else dsp->sb_16_enable = dsp->sbenable = 0;
if (dsp->sb_16_autoinit)
dsp->sb_16_length = dsp->sb_16_autolen;
else
{
dsp->sb_16_enable = 0;
timer_disable(&dsp->output_timer);
}
sb_irq(dsp, 0);
}
}
@ -1033,7 +1032,8 @@ void pollsb(void *p)
if (dsp->sb_pausetime < 0)
{
sb_irq(dsp, 1);
dsp->sbenable = dsp->sb_8_enable;
if (!dsp->sb_8_enable)
timer_disable(&dsp->output_timer);
// pclog("SB pause over\n");
}
}
@ -1043,7 +1043,9 @@ void sb_poll_i(void *p)
{
sb_dsp_t *dsp = (sb_dsp_t *)p;
int processed=0;
dsp->sb_count_i += dsp->sblatchi;
timer_advance_u64(&dsp->input_timer, dsp->sblatchi);
// pclog("PollSBi %i %i %i %i\n",sb_8_enable,sb_8_pause,sb_pausetime,sb_8_output);
if (dsp->sb_8_enable && !dsp->sb_8_pause && dsp->sb_pausetime < 0 && !dsp->sb_8_output)
{
@ -1100,8 +1102,13 @@ void sb_poll_i(void *p)
if (dsp->sb_8_length < 0)
{
// pclog("Input DMA over %i\n",sb_8_autoinit);
if (dsp->sb_8_autoinit) dsp->sb_8_length = dsp->sb_8_autolen;
else dsp->sb_8_enable = dsp->sb_enable_i = 0;
if (dsp->sb_8_autoinit)
dsp->sb_8_length = dsp->sb_8_autolen;
else
{
dsp->sb_8_enable = 0;
timer_disable(&dsp->input_timer);
}
sb_irq(dsp, 1);
}
processed=1;
@ -1167,8 +1174,13 @@ void sb_poll_i(void *p)
if (dsp->sb_16_length < 0)
{
// pclog("16iDMA over %i\n",sb_16_autoinit);
if (dsp->sb_16_autoinit) dsp->sb_16_length = dsp->sb_16_autolen;
else dsp->sb_16_enable = dsp->sb_enable_i = 0;
if (dsp->sb_16_autoinit)
dsp->sb_16_length = dsp->sb_16_autolen;
else
{
dsp->sb_16_enable = 0;
timer_disable(&dsp->input_timer);
}
sb_irq(dsp, 0);
}
processed=1;

View file

@ -47,9 +47,9 @@ typedef struct sb_dsp_t
int sbenable, sb_enable_i;
int sbcount, sb_count_i;
pc_timer_t output_timer, input_timer;
int sblatcho, sblatchi;
uint64_t sblatcho, sblatchi;
uint16_t sb_addr;
@ -57,7 +57,8 @@ typedef struct sb_dsp_t
int asp_data_len;
int wb_time, wb_full;
pc_timer_t wb_timer;
int wb_full;
int busy_count;

View file

@ -1,117 +1,134 @@
#include "ibm.h"
/*#include "sound_opl.h"
#include "adlibgold.h"
#include "sound_pas16.h"
#include "sound_sb.h"
#include "sound_sb_dsp.h"
#include "sound_wss.h"*/
#include "timer.h"
#define TIMERS_MAX 32
uint64_t TIMER_USEC;
uint32_t timer_target;
int TIMER_USEC;
/*Enabled timers are stored in a linked list, with the first timer to expire at
the head.*/
static pc_timer_t *timer_head = NULL;
static struct
void timer_enable(pc_timer_t *timer)
{
int present;
void (*callback)(void *priv);
void *priv;
int *enable;
int *count;
} timers[TIMERS_MAX];
pc_timer_t *timer_node = timer_head;
int timers_present = 0;
int timer_one = 1;
// pclog("timer->enable %p %i\n", timer, timer->enabled);
if (timer->enabled)
timer_disable(timer);
int timer_count = 0, timer_latch = 0;
int timer_start = 0;
if (timer->next || timer->prev)
fatal("timer_enable - timer->next\n");
timer->enabled = 1;
/*List currently empty - add to head*/
if (!timer_head)
{
timer_head = timer;
timer->next = timer->prev = NULL;
timer_target = timer_head->ts_integer;
return;
}
timer_node = timer_head;
while (1)
{
/*Timer expires before timer_node. Add to list in front of timer_node*/
if (TIMER_LESS_THAN(timer, timer_node))
{
timer->next = timer_node;
timer->prev = timer_node->prev;
timer_node->prev = timer;
if (timer->prev)
timer->prev->next = timer;
else
{
timer_head = timer;
timer_target = timer_head->ts_integer;
}
return;
}
/*timer_node is last in the list. Add timer to end of list*/
if (!timer_node->next)
{
timer_node->next = timer;
timer->prev = timer_node;
return;
}
timer_node = timer_node->next;
}
}
void timer_disable(pc_timer_t *timer)
{
// pclog("timer->disable %p\n", timer);
if (!timer->enabled)
return;
if (!timer->next && !timer->prev && timer != timer_head)
fatal("timer_disable - !timer->next\n");
timer->enabled = 0;
if (timer->prev)
timer->prev->next = timer->next;
else
timer_head = timer->next;
if (timer->next)
timer->next->prev = timer->prev;
timer->prev = timer->next = NULL;
}
static void timer_remove_head()
{
if (timer_head)
{
pc_timer_t *timer = timer_head;
// pclog("timer_remove_head %p %p\n", timer_head, timer_head->next);
timer_head = timer->next;
timer_head->prev = NULL;
timer->next = timer->prev = NULL;
timer->enabled = 0;
}
}
void timer_process()
{
int c;
int process = 0;
/*Get actual elapsed time*/
int diff = timer_latch - timer_count;
int enable[TIMERS_MAX];
if (!timer_head)
return;
timer_latch = 0;
for (c = 0; c < timers_present; c++)
{
enable[c] = *timers[c].enable;
if (*timers[c].enable)
{
*timers[c].count = *timers[c].count - diff;
if (*timers[c].count <= 0)
process = 1;
}
}
if (!process)
return;
while (1)
{
int lowest = 1, lowest_c;
for (c = 0; c < timers_present; c++)
{
if (enable[c])
{
if (*timers[c].count < lowest)
{
lowest = *timers[c].count;
lowest_c = c;
}
}
}
if (lowest > 0)
break;
timers[lowest_c].callback(timers[lowest_c].priv);
enable[lowest_c] = *timers[lowest_c].enable;
}
}
void timer_update_outstanding()
{
int c;
timer_latch = 0x7fffffff;
for (c = 0; c < timers_present; c++)
while (1)
{
if (*timers[c].enable && *timers[c].count < timer_latch)
timer_latch = *timers[c].count;
pc_timer_t *timer = timer_head;
if (!TIMER_LESS_THAN_VAL(timer, (uint32_t)tsc))
break;
timer_remove_head();
timer->callback(timer->p);
}
timer_count = timer_latch = (timer_latch + ((1 << TIMER_SHIFT) - 1));
timer_target = timer_head->ts_integer;
}
void timer_reset()
{
pclog("timer_reset\n");
timers_present = 0;
timer_latch = timer_count = 0;
// timer_process();
timer_target = 0;
tsc = 0;
timer_head = NULL;
}
int timer_add(void (*callback)(void *priv), int *count, int *enable, void *priv)
void timer_add(pc_timer_t *timer, void (*callback)(void *p), void *p, int start_timer)
{
if (timers_present < TIMERS_MAX)
{
// pclog("timer_add : adding timer %i\n", timers_present);
timers[timers_present].present = 1;
timers[timers_present].callback = callback;
timers[timers_present].priv = priv;
timers[timers_present].count = count;
timers[timers_present].enable = enable;
timers_present++;
return timers_present - 1;
}
return -1;
}
memset(timer, 0, sizeof(pc_timer_t));
void timer_set_callback(int timer, void (*callback)(void *priv))
{
timers[timer].callback = callback;
timer->callback = callback;
timer->p = p;
timer->enabled = 0;
timer->prev = timer->next = NULL;
if (start_timer)
timer_set_delay_u64(timer, 0);
}

View file

@ -3,56 +3,140 @@
#include "cpu.h"
extern int timer_start;
/*Timers are based on the CPU Time Stamp Counter. Timer timestamps are in a
32:32 fixed point format, with the integer part compared against the TSC. The
fractional part is used when advancing the timestamp to ensure a more accurate
period.
#define timer_start_period(cycles) \
timer_start = cycles;
As the timer only stores 32 bits of integer timestamp, and the TSC is 64 bits,
the timer period can only be at most 0x7fffffff CPU cycles. To allow room for
(optimistic) CPU frequency growth, timer period must be at most 1 second.
#define timer_end_period(cycles) \
do \
{ \
int diff = timer_start - (cycles); \
timer_count -= diff; \
timer_start = cycles; \
if (timer_count <= 0) \
{ \
timer_process(); \
timer_update_outstanding(); \
} \
} while (0)
When a timer callback is called, the timer has been disabled. If the timer is
to repeat, the callback must call timer_advance_u64(). This is a change from
the old timer API.*/
typedef struct pc_timer_t
{
uint32_t ts_integer;
uint32_t ts_frac;
int enabled;
#define timer_clock() \
do \
{ \
int diff; \
if (AT) \
{ \
diff = timer_start - (cycles << TIMER_SHIFT); \
timer_start = cycles << TIMER_SHIFT; \
} \
else \
{ \
diff = timer_start - (cycles * xt_cpu_multi); \
timer_start = cycles * xt_cpu_multi; \
} \
timer_count -= diff; \
timer_process(); \
timer_update_outstanding(); \
} while (0)
void (*callback)(void *p);
void *p;
struct pc_timer_t *prev, *next;
} pc_timer_t;
/*Timestamp of nearest enabled timer. CPU emulation must call timer_process()
when TSC matches or exceeds this.*/
extern uint32_t timer_target;
/*Enable timer, without updating timestamp*/
void timer_enable(pc_timer_t *timer);
/*Disable timer*/
void timer_disable(pc_timer_t *timer);
/*Process any pending timers*/
void timer_process();
void timer_update_outstanding();
/*Reset timer system*/
void timer_reset();
int timer_add(void (*callback)(void *priv), int *count, int *enable, void *priv);
void timer_set_callback(int timer, void (*callback)(void *priv));
#define TIMER_ALWAYS_ENABLED &timer_one
/*Add new timer. If start_timer is set, timer will be enabled with a zero
timestamp - this is useful for permanently enabled timers*/
void timer_add(pc_timer_t *timer, void (*callback)(void *p), void *p, int start_timer);
extern int timer_count;
extern int timer_one;
/*1us in 32:32 format*/
extern uint64_t TIMER_USEC;
#define TIMER_SHIFT 6
/*True if timer a expires before timer b*/
#define TIMER_LESS_THAN(a, b) ((int32_t)((a)->ts_integer - (b)->ts_integer) <= 0)
/*True if timer a expires before 32 bit integer timestamp b*/
#define TIMER_LESS_THAN_VAL(a, b) ((int32_t)((a)->ts_integer - (b)) <= 0)
/*True if 32 bit integer timestamp a expires before 32 bit integer timestamp b*/
#define TIMER_VAL_LESS_THAN_VAL(a, b) ((int32_t)((a) - (b)) <= 0)
extern int TIMER_USEC;
/*Advance timer by delay, specified in 32:32 format. This should be used to
resume a recurring timer in a callback routine*/
static inline void timer_advance_u64(pc_timer_t *timer, uint64_t delay)
{
uint32_t int_delay = delay >> 32;
uint32_t frac_delay = delay & 0xffffffff;
if ((frac_delay + timer->ts_frac) < frac_delay)
timer->ts_integer++;
timer->ts_frac += frac_delay;
timer->ts_integer += int_delay;
timer_enable(timer);
}
/*Set a timer to the given delay, specified in 32:32 format. This should be used
when starting a timer*/
static inline void timer_set_delay_u64(pc_timer_t *timer, uint64_t delay)
{
uint32_t int_delay = delay >> 32;
uint32_t frac_delay = delay & 0xffffffff;
timer->ts_frac = frac_delay;
timer->ts_integer = int_delay + (uint32_t)tsc;
timer_enable(timer);
}
/*True if timer currently enabled*/
static inline int timer_is_enabled(pc_timer_t *timer)
{
return timer->enabled;
}
/*Return integer timestamp of timer*/
static inline uint32_t timer_get_ts_int(pc_timer_t *timer)
{
return timer->ts_integer;
}
/*Return remaining time before timer expires, in us. If the timer has already
expired then return 0*/
static inline uint32_t timer_get_remaining_us(pc_timer_t *timer)
{
if (timer->enabled)
{
int64_t remaining = (((uint64_t)timer->ts_integer << 32) | timer->ts_frac) - (tsc << 32);
if (remaining < 0)
return 0;
return remaining / TIMER_USEC;
}
return 0;
}
/*Return remaining time before timer expires, in 32:32 timestamp format. If the
timer has already expired then return 0*/
static inline uint64_t timer_get_remaining_u64(pc_timer_t *timer)
{
if (timer->enabled)
{
int64_t remaining = (((uint64_t)timer->ts_integer << 32) | timer->ts_frac) - (tsc << 32);
if (remaining < 0)
return 0;
return remaining;
}
return 0;
}
/*Set timer callback function*/
static inline void timer_set_callback(pc_timer_t *timer, void (*callback)(void *p))
{
timer->callback = callback;
}
/*Set timer private data*/
static inline void timer_set_p(pc_timer_t *timer, void *p)
{
timer->p = p;
}
#endif /*_TIMER_H_*/

View file

@ -80,8 +80,9 @@ void cga_write(uint32_t addr, uint8_t val, void *p)
cga->vram[addr & 0x3fff] = val;
if (cga->snow_enabled)
{
cga->charbuffer[ ((int)(((cga->dispontime - cga->vidtime) * 2) / CGACONST)) & 0xfc] = val;
cga->charbuffer[(((int)(((cga->dispontime - cga->vidtime) * 2) / CGACONST)) & 0xfc) | 1] = val;
int offset = ((timer_get_remaining_u64(&cga->timer) / CGACONST) * 2) & 0xfc;
cga->charbuffer[offset] = cga->vram[addr & 0x3fff];
cga->charbuffer[offset | 1] = cga->vram[addr & 0x3fff];
}
egawrites++;
cycles -= 4;
@ -93,8 +94,9 @@ uint8_t cga_read(uint32_t addr, void *p)
cycles -= 4;
if (cga->snow_enabled)
{
cga->charbuffer[ ((int)(((cga->dispontime - cga->vidtime) * 2) / CGACONST)) & 0xfc] = cga->vram[addr & 0x3fff];
cga->charbuffer[(((int)(((cga->dispontime - cga->vidtime) * 2) / CGACONST)) & 0xfc) | 1] = cga->vram[addr & 0x3fff];
int offset = ((timer_get_remaining_u64(&cga->timer) / CGACONST) * 2) & 0xfc;
cga->charbuffer[offset] = cga->vram[addr & 0x3fff];
cga->charbuffer[offset | 1] = cga->vram[addr & 0x3fff];
}
egareads++;
// pclog("CGA_READ %04X\n", addr);
@ -121,8 +123,8 @@ void cga_recalctimings(cga_t *cga)
_dispontime *= CGACONST;
_dispofftime *= CGACONST;
// printf("Timings - on %f off %f frame %f second %f\n",dispontime,dispofftime,(dispontime+dispofftime)*262.0,(dispontime+dispofftime)*262.0*59.92);
cga->dispontime = (int)(_dispontime * (1 << TIMER_SHIFT));
cga->dispofftime = (int)(_dispofftime * (1 << TIMER_SHIFT));
cga->dispontime = (uint64_t)_dispontime;
cga->dispofftime = (uint64_t)_dispofftime;
}
void cga_poll(void *p)
@ -140,7 +142,7 @@ void cga_poll(void *p)
if (!cga->linepos)
{
cga->vidtime += cga->dispofftime;
timer_advance_u64(&cga->timer, cga->dispofftime);
cga->cgastat |= 1;
cga->linepos = 1;
oldsc = cga->sc;
@ -313,7 +315,7 @@ void cga_poll(void *p)
}
else
{
cga->vidtime += cga->dispontime;
timer_advance_u64(&cga->timer, cga->dispontime);
cga->linepos = 0;
if (cga->vsynctime)
{
@ -434,6 +436,7 @@ void cga_poll(void *p)
void cga_init(cga_t *cga)
{
timer_add(&cga->timer, cga_poll, cga, 1);
cga->composite = 0;
}
@ -452,7 +455,8 @@ void *cga_standalone_init()
cga->vram = malloc(0x4000);
cga_comp_init(cga->revision);
timer_add(cga_poll, &cga->vidtime, TIMER_ALWAYS_ENABLED, cga);
timer_add(&cga->timer, cga_poll, cga, 1);
mem_mapping_add(&cga->mapping, 0xb8000, 0x08000, cga_read, NULL, NULL, cga_write, NULL, NULL, NULL, MEM_MAPPING_EXTERNAL, cga);
io_sethandler(0x03d0, 0x0010, cga_in, NULL, NULL, cga_out, NULL, NULL, cga);

View file

@ -18,8 +18,8 @@ typedef struct cga_t
uint16_t ma, maback;
int oddeven;
int dispontime, dispofftime;
int vidtime;
uint64_t dispontime, dispofftime;
pc_timer_t timer;
int firstline, lastline;

View file

@ -119,7 +119,7 @@ void colorplus_poll(void *p)
if (!colorplus->cga.linepos)
{
colorplus->cga.vidtime += colorplus->cga.dispofftime;
timer_advance_u64(&colorplus->cga.timer, colorplus->cga.dispofftime);
colorplus->cga.cgastat |= 1;
colorplus->cga.linepos = 1;
oldsc = colorplus->cga.sc;
@ -215,7 +215,7 @@ void colorplus_poll(void *p)
}
else
{
colorplus->cga.vidtime += colorplus->cga.dispontime;
timer_advance_u64(&colorplus->cga.timer, colorplus->cga.dispontime);
colorplus->cga.linepos = 0;
if (colorplus->cga.vsynctime)
{
@ -346,7 +346,7 @@ void *colorplus_init()
display_type = device_get_config_int("display_type");
contrast = device_get_config_int("contrast");
timer_add(colorplus_poll, &colorplus->cga.vidtime, TIMER_ALWAYS_ENABLED, colorplus);
timer_add(&colorplus->cga.timer, colorplus_poll, colorplus, 1);
mem_mapping_add(&colorplus->cga.mapping, 0xb8000, 0x08000, colorplus_read, NULL, NULL, colorplus_write, NULL, NULL, NULL, 0, colorplus);
io_sethandler(0x03d0, 0x0010, colorplus_in, NULL, NULL, colorplus_out, NULL, NULL, colorplus);

View file

@ -25,8 +25,8 @@ void compaq_cga_recalctimings(compaq_cga_t *self)
_dispofftime = disptime - _dispontime;
_dispontime *= MDACONST;
_dispofftime *= MDACONST;
self->cga.dispontime = (int)(_dispontime * (1 << TIMER_SHIFT));
self->cga.dispofftime = (int)(_dispofftime * (1 << TIMER_SHIFT));
self->cga.dispontime = (uint64_t)_dispontime;
self->cga.dispofftime = (uint64_t)_dispofftime;
}
void compaq_cga_poll(void *p)
@ -52,7 +52,7 @@ void compaq_cga_poll(void *p)
/* We are in Compaq 350-line CGA territory */
if (!self->cga.linepos)
{
self->cga.vidtime += self->cga.dispofftime;
timer_advance_u64(&self->cga.timer, self->cga.dispofftime);
self->cga.cgastat |= 1;
self->cga.linepos = 1;
oldsc = self->cga.sc;
@ -194,7 +194,7 @@ void compaq_cga_poll(void *p)
}
else
{
self->cga.vidtime += self->cga.dispontime;
timer_advance_u64(&self->cga.timer, self->cga.dispontime);
self->cga.linepos = 0;
if (self->cga.vsynctime)
{
@ -325,7 +325,7 @@ void *compaq_cga_init()
self->cga.vram = malloc(0x4000);
timer_add(compaq_cga_poll, &self->cga.vidtime, TIMER_ALWAYS_ENABLED, self);
timer_add(&self->cga.timer, compaq_cga_poll, self, 1);
mem_mapping_add(&self->cga.mapping, 0xb8000, 0x08000, cga_read, NULL, NULL, cga_write, NULL, NULL, NULL, MEM_MAPPING_EXTERNAL, self);
io_sethandler(0x03d0, 0x0010, cga_in, NULL, NULL, cga_out, NULL, NULL, self);

View file

@ -241,10 +241,10 @@ void ega_recalctimings(ega_t *ega)
_dispontime *= crtcconst;
_dispofftime *= crtcconst;
ega->dispontime = (int)(_dispontime * (1 << TIMER_SHIFT));
ega->dispofftime = (int)(_dispofftime * (1 << TIMER_SHIFT));
pclog("dispontime %i (%f) dispofftime %i (%f)\n", ega->dispontime, (float)ega->dispontime / (1 << TIMER_SHIFT),
ega->dispofftime, (float)ega->dispofftime / (1 << TIMER_SHIFT));
ega->dispontime = (uint64_t)_dispontime;
ega->dispofftime = (uint64_t)_dispofftime;
pclog("dispontime %i (%f) dispofftime %i (%f)\n", ega->dispontime, (float)ega->dispontime,
ega->dispofftime, (float)ega->dispofftime);
// printf("EGA horiz total %i display end %i clock rate %i vidclock %i %i\n",crtc[0],crtc[1],egaswitchread,vidclock,((ega3c2>>2)&3) | ((tridentnewctrl2<<2)&4));
// printf("EGA vert total %i display end %i max row %i vsync %i\n",ega_vtotal,ega_dispend,(crtc[9]&31)+1,ega_vsyncstart);
// printf("total %f on %f cycles off %f cycles frame %f sec %f %02X\n",disptime*crtcconst,dispontime,dispofftime,(dispontime+dispofftime)*ega_vtotal,(dispontime+dispofftime)*ega_vtotal*70,seqregs[1]);
@ -500,7 +500,7 @@ void ega_poll(void *p)
if (!ega->linepos)
{
ega->vidtime += ega->dispofftime;
timer_advance_u64(&ega->timer, ega->dispofftime);
ega->stat |= 1;
ega->linepos = 1;
@ -567,7 +567,7 @@ void ega_poll(void *p)
}
else
{
ega->vidtime += ega->dispontime;
timer_advance_u64(&ega->timer, ega->dispontime);
// if (output) printf("Display on %f\n",vidtime);
if (ega->dispon)
ega->stat &= ~1;
@ -983,6 +983,8 @@ void ega_init(ega_t *ega, int monitor_type, int is_mono)
egaswitches = monitor_type & 0xf;
ega->vram_limit = 256 * 1024;
ega->vrammask = ega->vram_limit-1;
timer_add(&ega->timer, ega_poll, ega, 1);
}
void *ega_standalone_init()
@ -1013,8 +1015,8 @@ void *ega_standalone_init()
ega->vrammask = ega->vram_limit-1;
mem_mapping_add(&ega->mapping, 0xa0000, 0x20000, ega_read, NULL, NULL, ega_write, NULL, NULL, NULL, MEM_MAPPING_EXTERNAL, ega);
timer_add(ega_poll, &ega->vidtime, TIMER_ALWAYS_ENABLED, ega);
io_sethandler(0x03a0, 0x0040, ega_in, NULL, NULL, ega_out, NULL, NULL, ega);
return ega;
}

View file

@ -39,8 +39,8 @@ typedef struct ega_t
int vres;
int dispontime, dispofftime;
int vidtime;
uint64_t dispontime, dispofftime;
pc_timer_t timer;
uint8_t scrblank;

View file

@ -98,8 +98,8 @@ typedef struct genius_t
int enabled; /* Display enabled, 0 or 1 */
int detach; /* Detach cursor, 0 or 1 */
int dispontime, dispofftime;
int vidtime;
uint64_t dispontime, dispofftime;
pc_timer_t timer;
int linepos, displine;
int vc;
@ -246,8 +246,8 @@ void genius_recalctimings(genius_t *genius)
_dispofftime = disptime - _dispontime;
_dispontime *= MDACONST;
_dispofftime *= MDACONST;
genius->dispontime = (int)(_dispontime * (1 << TIMER_SHIFT));
genius->dispofftime = (int)(_dispofftime * (1 << TIMER_SHIFT));
genius->dispontime = (uint64_t)_dispontime;
genius->dispofftime = (uint64_t)_dispofftime;
}
@ -462,7 +462,7 @@ void genius_poll(void *p)
if (!genius->linepos)
{
genius->vidtime += genius->dispofftime;
timer_advance_u64(&genius->timer, genius->dispofftime);
genius->cga_stat |= 1;
genius->mda_stat |= 1;
genius->linepos = 1;
@ -526,7 +526,7 @@ void genius_poll(void *p)
genius->cga_stat &= ~1;
genius->mda_stat &= ~1;
}
genius->vidtime += genius->dispontime;
timer_advance_u64(&genius->timer, genius->dispontime);
genius->linepos = 0;
if (genius->displine == 1008)
@ -561,7 +561,7 @@ void *genius_init()
/* 160k video RAM */
genius->vram = malloc(0x28000);
timer_add(genius_poll, &genius->vidtime, TIMER_ALWAYS_ENABLED, genius);
timer_add(&genius->timer, genius_poll, genius, 1);
/* Occupy memory between 0xB0000 and 0xBFFFF (moves to 0xA0000 in
* high-resolution modes) */

View file

@ -17,8 +17,8 @@ typedef struct hercules_t
uint8_t ctrl, ctrl2, stat;
int dispontime, dispofftime;
int vidtime;
uint64_t dispontime, dispofftime;
pc_timer_t timer;
int firstline, lastline;
@ -110,8 +110,8 @@ void hercules_recalctimings(hercules_t *hercules)
_dispofftime = disptime - _dispontime;
_dispontime *= MDACONST;
_dispofftime *= MDACONST;
hercules->dispontime = (int)(_dispontime * (1 << TIMER_SHIFT));
hercules->dispofftime = (int)(_dispofftime * (1 << TIMER_SHIFT));
hercules->dispontime = (uint64_t)_dispontime;
hercules->dispofftime = (uint64_t)_dispofftime;
}
void hercules_poll(void *p)
@ -128,7 +128,7 @@ void hercules_poll(void *p)
if (!hercules->linepos)
{
//pclog("Poll %i %i\n",vc,sc);
hercules->vidtime += hercules->dispofftime;
timer_advance_u64(&hercules->timer, hercules->dispofftime);
hercules->stat |= 1;
hercules->linepos = 1;
oldsc = hercules->sc;
@ -199,7 +199,7 @@ void hercules_poll(void *p)
}
else
{
hercules->vidtime += hercules->dispontime;
timer_advance_u64(&hercules->timer, hercules->dispontime);
if (hercules->dispon)
hercules->stat &= ~1;
hercules->linepos = 0;
@ -314,7 +314,7 @@ void *hercules_init()
hercules->vram = malloc(0x10000);
timer_add(hercules_poll, &hercules->vidtime, TIMER_ALWAYS_ENABLED, hercules);
timer_add(&hercules->timer, hercules_poll, hercules, 1);
mem_mapping_add(&hercules->mapping, 0xb0000, 0x08000, hercules_read, NULL, NULL, hercules_write, NULL, NULL, NULL, MEM_MAPPING_EXTERNAL, hercules);
io_sethandler(0x03b0, 0x0010, hercules_in, NULL, NULL, hercules_out, NULL, NULL, hercules);

View file

@ -148,8 +148,8 @@ typedef struct incolor_t
uint8_t ctrl, ctrl2, stat;
int dispontime, dispofftime;
int vidtime;
uint64_t dispontime, dispofftime;
pc_timer_t timer;
int firstline, lastline;
@ -358,8 +358,8 @@ void incolor_recalctimings(incolor_t *incolor)
_dispofftime = disptime - _dispontime;
_dispontime *= MDACONST;
_dispofftime *= MDACONST;
incolor->dispontime = (int)(_dispontime * (1 << TIMER_SHIFT));
incolor->dispofftime = (int)(_dispofftime * (1 << TIMER_SHIFT));
incolor->dispontime = (uint64_t)_dispontime;
incolor->dispofftime = (uint64_t)_dispofftime;
}
@ -851,7 +851,7 @@ void incolor_poll(void *p)
if (!incolor->linepos)
{
// pclog("InColor poll %i %i\n", incolor->vc, incolor->sc);
incolor->vidtime += incolor->dispofftime;
timer_advance_u64(&incolor->timer, incolor->dispofftime);
incolor->stat |= 1;
incolor->linepos = 1;
oldsc = incolor->sc;
@ -886,7 +886,7 @@ void incolor_poll(void *p)
}
else
{
incolor->vidtime += incolor->dispontime;
timer_advance_u64(&incolor->timer, incolor->dispontime);
if (incolor->dispon)
incolor->stat &= ~1;
incolor->linepos = 0;
@ -1006,7 +1006,7 @@ void *incolor_init()
incolor->vram = malloc(0x40000); /* 4 planes of 64k */
timer_add(incolor_poll, &incolor->vidtime, TIMER_ALWAYS_ENABLED, incolor);
timer_add(&incolor->timer, incolor_poll, incolor, 1);
mem_mapping_add(&incolor->mapping, 0xb0000, 0x08000, incolor_read, NULL, NULL, incolor_write, NULL, NULL, NULL, MEM_MAPPING_EXTERNAL, incolor);
io_sethandler(0x03b0, 0x0010, incolor_in, NULL, NULL, incolor_out, NULL, NULL, incolor);

View file

@ -17,8 +17,8 @@ typedef struct mda_t
uint8_t ctrl, stat;
int dispontime, dispofftime;
int vidtime;
uint64_t dispontime, dispofftime;
pc_timer_t timer;
int firstline, lastline;
@ -96,8 +96,8 @@ void mda_recalctimings(mda_t *mda)
_dispofftime = disptime - _dispontime;
_dispontime *= MDACONST;
_dispofftime *= MDACONST;
mda->dispontime = (int)(_dispontime * (1 << TIMER_SHIFT));
mda->dispofftime = (int)(_dispofftime * (1 << TIMER_SHIFT));
mda->dispontime = (uint64_t)_dispontime;
mda->dispofftime = (uint64_t)_dispofftime;
}
void mda_poll(void *p)
@ -112,7 +112,7 @@ void mda_poll(void *p)
int blink;
if (!mda->linepos)
{
mda->vidtime += mda->dispofftime;
timer_advance_u64(&mda->timer, mda->dispofftime);
mda->stat |= 1;
mda->linepos = 1;
oldsc = mda->sc;
@ -166,7 +166,7 @@ void mda_poll(void *p)
}
else
{
mda->vidtime += mda->dispontime;
timer_advance_u64(&mda->timer, mda->dispontime);
if (mda->dispon) mda->stat&=~1;
mda->linepos=0;
if (mda->vsynctime)
@ -270,7 +270,7 @@ void *mda_init()
mda->vram = malloc(0x1000);
timer_add(mda_poll, &mda->vidtime, TIMER_ALWAYS_ENABLED, mda);
timer_add(&mda->timer, mda_poll, mda, 1);
mem_mapping_add(&mda->mapping, 0xb0000, 0x08000, mda_read, NULL, NULL, mda_write, NULL, NULL, NULL, MEM_MAPPING_EXTERNAL, mda);
io_sethandler(0x03b0, 0x0010, mda_in, NULL, NULL, mda_out, NULL, NULL, mda);

View file

@ -33,7 +33,8 @@ typedef struct m24_t
uint16_t ma, maback;
int dispon;
int dispontime, dispofftime, vidtime;
uint64_t dispontime, dispofftime;
pc_timer_t timer;
int firstline, lastline;
} m24_t;
@ -100,9 +101,11 @@ uint8_t m24_in(uint16_t addr, void *p)
void m24_write(uint32_t addr, uint8_t val, void *p)
{
m24_t *m24 = (m24_t *)p;
int offset = ((timer_get_remaining_u64(&m24->timer) / CGACONST) * 4) & 0xfc;
m24->vram[addr & 0x7FFF]=val;
m24->charbuffer[ ((int)(((m24->dispontime - m24->vidtime) * 2) / (CGACONST / 2))) & 0xfc] = val;
m24->charbuffer[(((int)(((m24->dispontime - m24->vidtime) * 2) / (CGACONST / 2))) & 0xfc) | 1] = val;
m24->charbuffer[offset] = val;
m24->charbuffer[offset | 1] = val;
}
uint8_t m24_read(uint32_t addr, void *p)
@ -129,8 +132,8 @@ void m24_recalctimings(m24_t *m24)
_dispontime *= CGACONST / 2;
_dispofftime *= CGACONST / 2;
// printf("Timings - on %f off %f frame %f second %f\n",dispontime,dispofftime,(dispontime+dispofftime)*262.0,(dispontime+dispofftime)*262.0*59.92);
m24->dispontime = (int)(_dispontime * (1 << TIMER_SHIFT));
m24->dispofftime = (int)(_dispofftime * (1 << TIMER_SHIFT));
m24->dispontime = (uint64_t)_dispontime;
m24->dispofftime = (uint64_t)_dispofftime;
}
void m24_poll(void *p)
@ -148,7 +151,7 @@ void m24_poll(void *p)
if (!m24->linepos)
{
// pclog("Line poll %i %i %i %i - %04X %i %i %i\n", m24_lineff, vc, sc, vadj, ma, firstline, lastline, displine);
m24->vidtime += m24->dispofftime;
timer_advance_u64(&m24->timer, m24->dispofftime);
m24->stat |= 1;
m24->linepos = 1;
oldsc = m24->sc;
@ -324,7 +327,7 @@ void m24_poll(void *p)
else
{
// pclog("Line poll %i %i %i %i\n", m24_lineff, vc, sc, vadj);
m24->vidtime += m24->dispontime;
timer_advance_u64(&m24->timer, m24->dispontime);
if (m24->dispon) m24->stat &= ~1;
m24->linepos = 0;
m24->lineff ^= 1;
@ -456,7 +459,7 @@ void *m24_init()
m24->vram = malloc(0x8000);
timer_add(m24_poll, &m24->vidtime, TIMER_ALWAYS_ENABLED, m24);
timer_add(&m24->timer, m24_poll, m24, 1);
mem_mapping_add(&m24->mapping, 0xb8000, 0x08000, m24_read, NULL, NULL, m24_write, NULL, NULL, NULL, 0, m24);
io_sethandler(0x03d0, 0x0010, m24_in, NULL, NULL, m24_out, NULL, NULL, m24);
return m24;

View file

@ -35,7 +35,8 @@ typedef struct pc1512_t
int dispon;
int blink;
int dispontime, dispofftime, vidtime;
uint64_t dispontime, dispofftime;
pc_timer_t timer;
int firstline, lastline;
uint8_t *vram;
@ -153,8 +154,8 @@ static void pc1512_recalctimings(pc1512_t *pc1512)
_dispontime *= CGACONST;
_dispofftime *= CGACONST;
// printf("Timings - on %f off %f frame %f second %f\n",dispontime,dispofftime,(dispontime+dispofftime)*262.0,(dispontime+dispofftime)*262.0*59.92);
pc1512->dispontime = (int)(_dispontime * (1 << TIMER_SHIFT));
pc1512->dispofftime = (int)(_dispofftime * (1 << TIMER_SHIFT));
pc1512->dispontime = (uint64_t)_dispontime;
pc1512->dispofftime = (uint64_t)_dispofftime;
}
static void pc1512_poll(void *p)
@ -171,7 +172,7 @@ static void pc1512_poll(void *p)
if (!pc1512->linepos)
{
pc1512->vidtime += pc1512->dispofftime;
timer_advance_u64(&pc1512->timer, pc1512->dispofftime);
pc1512->stat |= 1;
pc1512->linepos = 1;
oldsc = pc1512->sc;
@ -337,7 +338,7 @@ static void pc1512_poll(void *p)
}
else
{
pc1512->vidtime += pc1512->dispontime;
timer_advance_u64(&pc1512->timer, pc1512->dispontime);
if ((pc1512->lastline - pc1512->firstline) == 199)
pc1512->dispon = 0; /*Amstrad PC1512 always displays 200 lines, regardless of CRTC settings*/
if (pc1512->dispon)
@ -459,7 +460,7 @@ static void *pc1512_init()
pc1512->cgacol = 7;
pc1512->cgamode = 0x12;
timer_add(pc1512_poll, &pc1512->vidtime, TIMER_ALWAYS_ENABLED, pc1512);
timer_add(&pc1512->timer, pc1512_poll, pc1512, 1);
mem_mapping_add(&pc1512->mapping, 0xb8000, 0x08000, pc1512_read, NULL, NULL, pc1512_write, NULL, NULL, NULL, 0, pc1512);
io_sethandler(0x03d0, 0x0010, pc1512_in, NULL, NULL, pc1512_out, NULL, NULL, pc1512);
return pc1512;

View file

@ -23,7 +23,8 @@ typedef struct pc1640_t
rom_t bios_rom;
int cga_enabled;
int dispontime, dispofftime, vidtime;
uint64_t dispontime, dispofftime;
pc_timer_t timer;
} pc1640_t;
void pc1640_out(uint16_t addr, uint8_t val, void *p)
@ -33,29 +34,36 @@ void pc1640_out(uint16_t addr, uint8_t val, void *p)
switch (addr)
{
case 0x3db:
pc1640->cga_enabled = val & 0x40;
if (pc1640->cga_enabled)
if (pc1640->cga_enabled != (val & 0x40))
{
mem_mapping_enable(&pc1640->cga_mapping);
mem_mapping_disable(&pc1640->ega_mapping);
}
else
{
mem_mapping_disable(&pc1640->cga_mapping);
switch (pc1640->ega.gdcreg[6] & 0xc)
pc1640->cga_enabled = val & 0x40;
if (pc1640->cga_enabled)
{
case 0x0: /*128k at A0000*/
mem_mapping_set_addr(&pc1640->ega_mapping, 0xa0000, 0x20000);
break;
case 0x4: /*64k at A0000*/
mem_mapping_set_addr(&pc1640->ega_mapping, 0xa0000, 0x10000);
break;
case 0x8: /*32k at B0000*/
mem_mapping_set_addr(&pc1640->ega_mapping, 0xb0000, 0x08000);
break;
case 0xC: /*32k at B8000*/
mem_mapping_set_addr(&pc1640->ega_mapping, 0xb8000, 0x08000);
break;
timer_disable(&pc1640->ega.timer);
timer_set_delay_u64(&pc1640->cga.timer, 0);
mem_mapping_enable(&pc1640->cga_mapping);
mem_mapping_disable(&pc1640->ega_mapping);
}
else
{
timer_disable(&pc1640->cga.timer);
timer_set_delay_u64(&pc1640->ega.timer, 0);
mem_mapping_disable(&pc1640->cga_mapping);
switch (pc1640->ega.gdcreg[6] & 0xc)
{
case 0x0: /*128k at A0000*/
mem_mapping_set_addr(&pc1640->ega_mapping, 0xa0000, 0x20000);
break;
case 0x4: /*64k at A0000*/
mem_mapping_set_addr(&pc1640->ega_mapping, 0xa0000, 0x10000);
break;
case 0x8: /*32k at B0000*/
mem_mapping_set_addr(&pc1640->ega_mapping, 0xb0000, 0x08000);
break;
case 0xC: /*32k at B8000*/
mem_mapping_set_addr(&pc1640->ega_mapping, 0xb8000, 0x08000);
break;
}
}
}
pclog("3DB write %02X\n", val);
@ -93,23 +101,6 @@ void pc1640_recalctimings(pc1640_t *pc1640)
}
}
void pc1640_poll(void *p)
{
pc1640_t *pc1640 = (pc1640_t *)p;
if (pc1640->cga_enabled)
{
pc1640->cga.vidtime = pc1640->vidtime;
cga_poll(&pc1640->cga);
pc1640->vidtime = pc1640->cga.vidtime;
}
else
{
pc1640->ega.vidtime = pc1640->vidtime;
ega_poll(&pc1640->ega);
pc1640->vidtime = pc1640->ega.vidtime;
}
}
void *pc1640_init()
{
pc1640_t *pc1640 = malloc(sizeof(pc1640_t));
@ -123,8 +114,8 @@ void *pc1640_init()
pc1640->cga.vram = pc1640->ega.vram;
pc1640->cga_enabled = 1;
cga_init(&pc1640->cga);
timer_disable(&pc1640->ega.timer);
timer_add(pc1640_poll, &pc1640->vidtime, TIMER_ALWAYS_ENABLED, pc1640);
mem_mapping_add(&pc1640->cga_mapping, 0xb8000, 0x08000, cga_read, NULL, NULL, cga_write, NULL, NULL, NULL, 0, cga);
mem_mapping_add(&pc1640->ega_mapping, 0, 0, ega_read, NULL, NULL, ega_write, NULL, NULL, NULL, 0, ega);
io_sethandler(0x03a0, 0x0040, pc1640_in, NULL, NULL, pc1640_out, NULL, NULL, pc1640);

View file

@ -111,7 +111,6 @@ void *pc200_init()
pc200->cga.vram = malloc(0x4000);
cga_init(&pc200->cga);
timer_add(cga_poll, &cga->vidtime, TIMER_ALWAYS_ENABLED, cga);
mem_mapping_add(&pc200->mapping, 0xb8000, 0x08000, cga_read, NULL, NULL, cga_write, NULL, NULL, NULL, 0, cga);
io_sethandler(0x03d0, 0x0010, pc200_in, NULL, NULL, pc200_out, NULL, NULL, pc200);
return pc200;

View file

@ -36,7 +36,8 @@ typedef struct pcjr_t
int vsynctime, vadj;
uint16_t ma, maback;
int dispontime, dispofftime, vidtime;
uint64_t dispontime, dispofftime;
pc_timer_t timer;
int firstline, lastline;
int composite;
@ -168,8 +169,8 @@ void pcjr_recalctimings(pcjr_t *pcjr)
_dispofftime = disptime - _dispontime;
_dispontime *= CGACONST;
_dispofftime *= CGACONST;
pcjr->dispontime = (int)(_dispontime * (1 << TIMER_SHIFT));
pcjr->dispofftime = (int)(_dispofftime * (1 << TIMER_SHIFT));
pcjr->dispontime = (uint64_t)_dispontime;
pcjr->dispofftime = (uint64_t)_dispofftime;
}
void pcjr_poll(void *p)
@ -189,7 +190,7 @@ void pcjr_poll(void *p)
{
// cgapal[0]=pcjr->col&15;
// printf("Firstline %i Lastline %i pcjr->displine %i\n",firstline,lastline,pcjr->displine);
pcjr->vidtime += pcjr->dispofftime;
timer_advance_u64(&pcjr->timer, pcjr->dispofftime);
pcjr->stat &= ~1;
pcjr->linepos = 1;
oldsc = pcjr->sc;
@ -435,7 +436,7 @@ void pcjr_poll(void *p)
}
else
{
pcjr->vidtime += pcjr->dispontime;
timer_advance_u64(&pcjr->timer, pcjr->dispontime);
if (pcjr->dispon)
pcjr->stat |= 1;
pcjr->linepos = 0;
@ -552,7 +553,7 @@ static void *pcjr_video_init()
pcjr->memctrl = -1;
timer_add(pcjr_poll, &pcjr->vidtime, TIMER_ALWAYS_ENABLED, pcjr);
timer_add(&pcjr->timer, pcjr_poll, pcjr, 1);
mem_mapping_add(&pcjr->mapping, 0xb8000, 0x08000, pcjr_read, NULL, NULL, pcjr_write, NULL, NULL, NULL, 0, pcjr);
io_sethandler(0x03d0, 0x0010, pcjr_in, NULL, NULL, pcjr_out, NULL, NULL, pcjr);
return pcjr;

View file

@ -1206,7 +1206,7 @@ void s3_recalctimings(svga_t *svga)
else if (svga->crtc[0x43] & 0x04) svga->rowoffset += 0x100;
if (!svga->rowoffset) svga->rowoffset = 256;
svga->interlace = svga->crtc[0x42] & 0x20;
svga->clock = cpuclock / s3->getclock((svga->miscout >> 2) & 3, s3->getclock_p);
svga->clock = (cpuclock * (float)(1ull << 32)) / s3->getclock((svga->miscout >> 2) & 3, s3->getclock_p);
switch (svga->crtc[0x67] >> 4)
{

View file

@ -433,8 +433,8 @@ void svga_recalctimings(svga_t *svga)
_dispontime *= crtcconst;
_dispofftime *= crtcconst;
svga->dispontime = (int)(_dispontime * (1 << TIMER_SHIFT));
svga->dispofftime = (int)(_dispofftime * (1 << TIMER_SHIFT));
svga->dispontime = (uint64_t)_dispontime;
svga->dispofftime = (uint64_t)_dispofftime;
/* printf("SVGA horiz total %i display end %i vidclock %f\n",svga->crtc[0],svga->crtc[1],svga->clock);
printf("SVGA vert total %i display end %i max row %i vsync %i\n",svga->vtotal,svga->dispend,(svga->crtc[9]&31)+1,svga->vsyncstart);
printf("total %f on %i cycles off %i cycles frame %i sec %i %02X\n",disptime*crtcconst,svga->dispontime,svga->dispofftime,(svga->dispontime+svga->dispofftime)*svga->vtotal,(svga->dispontime+svga->dispofftime)*svga->vtotal*70,svga->seqregs[1]);
@ -478,7 +478,7 @@ void svga_poll(void *p)
svga->overlay_oddeven = 1;
}
svga->vidtime += svga->dispofftime;
timer_advance_u64(&svga->timer, svga->dispofftime);
// if (output) printf("Display off %f\n",vidtime);
svga->cgastat |= 1;
svga->linepos = 1;
@ -540,7 +540,7 @@ void svga_poll(void *p)
else
{
// pclog("VC %i ma %05X\n", svga->vc, svga->ma);
svga->vidtime += svga->dispontime;
timer_advance_u64(&svga->timer, svga->dispontime);
// if (output) printf("Display on %f\n",vidtime);
if (svga->dispon)
@ -730,8 +730,8 @@ int svga_init(svga_t *svga, void *p, int memsize,
svga->crtc[0] = 63;
svga->crtc[6] = 255;
svga->dispontime = 1000 * (1 << TIMER_SHIFT);
svga->dispofftime = 1000 * (1 << TIMER_SHIFT);
svga->dispontime = 1000ull << 32;
svga->dispofftime = 1000ull << 32;
svga->bpp = 8;
svga->vram = malloc(memsize);
svga->vram_max = memsize;
@ -749,7 +749,7 @@ int svga_init(svga_t *svga, void *p, int memsize,
mem_mapping_add(&svga->mapping, 0xa0000, 0x20000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel, NULL, MEM_MAPPING_EXTERNAL, svga);
timer_add(svga_poll, &svga->vidtime, TIMER_ALWAYS_ENABLED, svga);
timer_add(&svga->timer, svga_poll, svga, 1);
svga_pri = svga;

View file

@ -63,8 +63,8 @@ typedef struct svga_t
uint32_t ma_latch;
int bpp;
int dispontime, dispofftime;
int vidtime;
uint64_t dispontime, dispofftime;
pc_timer_t timer;
uint8_t scrblank;

View file

@ -13,6 +13,9 @@
#define T1000_XSIZE 640
#define T1000_YSIZE 200
/*Very rough estimate*/
#define VID_CLOCK (double)(651 * 216 * 60)
/* Mapping of attributes to colours */
static uint32_t blue, grey;
static uint8_t boldcols[256]; /* Which attributes use the bold font */
@ -65,7 +68,7 @@ typedef struct t1000_t
int internal; /* Using internal display? */
uint8_t attrmap; /* Attribute mapping register */
int dispontime, dispofftime;
uint64_t dispontime, dispofftime;
int linepos, displine;
int vc;
@ -176,8 +179,8 @@ static void t1000_recalctimings(t1000_t *t1000)
disptime = 651;
_dispontime = 640;
_dispofftime = disptime - _dispontime;
t1000->dispontime = (int)(_dispontime * (1 << TIMER_SHIFT));
t1000->dispofftime = (int)(_dispofftime * (1 << TIMER_SHIFT));
t1000->dispontime = (uint64_t)(_dispontime * (cpuclock / VID_CLOCK) * (double)(1ull << 32));
t1000->dispofftime = (uint64_t)(_dispofftime * (cpuclock / VID_CLOCK) * (double)(1ull << 32));
}
/* Draw a row of text in 80-column mode */
@ -446,7 +449,7 @@ static void t1000_poll(void *p)
if (!t1000->linepos)
{
t1000->cga.vidtime += t1000->dispofftime;
timer_advance_u64(&t1000->cga.timer, t1000->dispofftime);
t1000->cga.cgastat |= 1;
t1000->linepos = 1;
if (t1000->dispon)
@ -493,7 +496,7 @@ static void t1000_poll(void *p)
{
t1000->cga.cgastat &= ~1;
}
t1000->cga.vidtime += t1000->dispontime;
timer_advance_u64(&t1000->cga.timer, t1000->dispontime);
t1000->linepos = 0;
if (t1000->displine == 200)
@ -635,7 +638,8 @@ static void *t1000_init()
/* 16k video RAM */
t1000->vram = malloc(0x4000);
timer_add(t1000_poll, &t1000->cga.vidtime, TIMER_ALWAYS_ENABLED, t1000);
timer_set_callback(&t1000->cga.timer, t1000_poll);
timer_set_p(&t1000->cga.timer, t1000);
/* Occupy memory between 0xB8000 and 0xBFFFF */
mem_mapping_add(&t1000->mapping, 0xb8000, 0x8000, t1000_read, NULL, NULL, t1000_write, NULL, NULL, NULL, 0, t1000);

View file

@ -13,6 +13,9 @@
#define T3100E_XSIZE 640
#define T3100E_YSIZE 400
/*Very rough estimate*/
#define VID_CLOCK (double)(651 * 416 * 60)
/* T3100e CRTC regs (from the ROM):
*
* Selecting a character height of 3 seems to be sufficient to convert the
@ -73,7 +76,7 @@ typedef struct t3100e_t
int internal; /* Using internal display? */
uint8_t attrmap; /* Attribute mapping register */
int dispontime, dispofftime;
uint64_t dispontime, dispofftime;
int linepos, displine;
int vc;
@ -186,8 +189,8 @@ void t3100e_recalctimings(t3100e_t *t3100e)
disptime = 651;
_dispontime = 640;
_dispofftime = disptime - _dispontime;
t3100e->dispontime = (int)(_dispontime * (1 << TIMER_SHIFT));
t3100e->dispofftime = (int)(_dispofftime * (1 << TIMER_SHIFT));
t3100e->dispontime = (uint64_t)(_dispontime * (cpuclock / VID_CLOCK) * (double)(1ull << 32));
t3100e->dispofftime = (uint64_t)(_dispofftime * (cpuclock / VID_CLOCK) * (double)(1ull << 32));
}
@ -481,7 +484,7 @@ void t3100e_poll(void *p)
if (!t3100e->linepos)
{
t3100e->cga.vidtime += t3100e->dispofftime;
timer_advance_u64(&t3100e->cga.timer, t3100e->dispofftime);
t3100e->cga.cgastat |= 1;
t3100e->linepos = 1;
if (t3100e->dispon)
@ -528,7 +531,7 @@ void t3100e_poll(void *p)
{
t3100e->cga.cgastat &= ~1;
}
t3100e->cga.vidtime += t3100e->dispontime;
timer_advance_u64(&t3100e->cga.timer, t3100e->dispontime);
t3100e->linepos = 0;
if (t3100e->displine == 400)
@ -672,7 +675,8 @@ void *t3100e_init()
/* 32k video RAM */
t3100e->vram = malloc(0x8000);
timer_add(t3100e_poll, &t3100e->cga.vidtime, TIMER_ALWAYS_ENABLED, t3100e);
timer_set_callback(&t3100e->cga.timer, t3100e_poll);
timer_set_p(&t3100e->cga.timer, t3100e);
/* Occupy memory between 0xB8000 and 0xBFFFF */
mem_mapping_add(&t3100e->mapping, 0xb8000, 0x8000, t3100e_read, NULL, NULL, t3100e_write, NULL, NULL, NULL, 0, t3100e);

View file

@ -37,7 +37,8 @@ typedef struct tandy_t
int vsynctime, vadj;
uint16_t ma, maback;
int dispontime, dispofftime, vidtime;
uint64_t dispontime, dispofftime;
pc_timer_t timer;
int firstline, lastline;
int composite;
@ -186,8 +187,8 @@ void tandy_recalctimings(tandy_t *tandy)
_dispofftime = disptime - _dispontime;
_dispontime *= CGACONST;
_dispofftime *= CGACONST;
tandy->dispontime = (int)(_dispontime * (1 << TIMER_SHIFT));
tandy->dispofftime = (int)(_dispofftime * (1 << TIMER_SHIFT));
tandy->dispontime = (uint64_t)_dispontime;
tandy->dispofftime = (uint64_t)_dispofftime;
}
@ -208,7 +209,7 @@ void tandy_poll(void *p)
{
// cgapal[0]=tandy->col&15;
// printf("Firstline %i Lastline %i tandy->displine %i\n",firstline,lastline,tandy->displine);
tandy->vidtime += tandy->dispofftime;
timer_advance_u64(&tandy->timer, tandy->dispofftime);
tandy->stat |= 1;
tandy->linepos = 1;
oldsc = tandy->sc;
@ -476,7 +477,7 @@ void tandy_poll(void *p)
}
else
{
tandy->vidtime += tandy->dispontime;
timer_advance_u64(&tandy->timer, tandy->dispontime);
if (tandy->dispon)
tandy->stat &= ~1;
tandy->linepos = 0;
@ -624,7 +625,7 @@ void *tandy_init()
tandy->memctrl = -1;
tandy->base = (mem_size - 128) * 1024;
timer_add(tandy_poll, &tandy->vidtime, TIMER_ALWAYS_ENABLED, tandy);
timer_add(&tandy->timer, tandy_poll, tandy, 1);
mem_mapping_add(&tandy->mapping, 0xb8000, 0x08000, tandy_read, NULL, NULL, tandy_write, NULL, NULL, NULL, 0, tandy);
mem_mapping_add(&tandy->ram_mapping, 0x80000, 0x20000, tandy_ram_read, NULL, NULL, tandy_ram_write, NULL, NULL, NULL, 0, tandy);
/*Base 128k mapping is controlled via port 0xA0, so we remove it from the main mapping*/

View file

@ -35,7 +35,8 @@ typedef struct tandysl_t
int vsynctime, vadj;
uint16_t ma, maback;
int dispontime, dispofftime, vidtime;
uint64_t dispontime, dispofftime;
pc_timer_t timer;
int firstline, lastline;
} tandysl_t;
@ -249,8 +250,8 @@ static void tandysl_recalctimings(tandysl_t *tandy)
_dispofftime = disptime - _dispontime;
_dispontime *= CGACONST;
_dispofftime *= CGACONST;
tandy->dispontime = (int)(_dispontime * (1 << TIMER_SHIFT));
tandy->dispofftime = (int)(_dispofftime * (1 << TIMER_SHIFT));
tandy->dispontime = (uint64_t)_dispontime;
tandy->dispofftime = (uint64_t)_dispofftime;
}
@ -272,7 +273,7 @@ static void tandysl_poll(void *p)
// pclog("tandy_poll vc=%i sc=%i dispon=%i\n", tandy->vc, tandy->sc, tandy->dispon);
// cgapal[0]=tandy->col&15;
// printf("Firstline %i Lastline %i tandy->displine %i\n",firstline,lastline,tandy->displine);
tandy->vidtime += tandy->dispofftime;
timer_advance_u64(&tandy->timer, tandy->dispofftime);
tandy->stat |= 1;
tandy->linepos = 1;
oldsc = tandy->sc;
@ -537,7 +538,7 @@ static void tandysl_poll(void *p)
}
else
{
tandy->vidtime += tandy->dispontime;
timer_advance_u64(&tandy->timer, tandy->dispontime);
if (tandy->dispon)
tandy->stat &= ~1;
tandy->linepos = 0;
@ -694,7 +695,7 @@ static void *tandysl_init()
tandy->b8000_limit = 0x8000;
tandy->planar_ctrl = 4;
timer_add(tandysl_poll, &tandy->vidtime, TIMER_ALWAYS_ENABLED, tandy);
timer_add(&tandy->timer, tandysl_poll, tandy, 1);
mem_mapping_add(&tandy->mapping, 0xb8000, 0x08000, tandysl_read, NULL, NULL, tandysl_write, NULL, NULL, NULL, 0, tandy);
mem_mapping_add(&tandy->ram_mapping, 0x80000, 0x20000, tandysl_ram_read, NULL, NULL, tandysl_ram_write, NULL, NULL, NULL, 0, tandy);
/*Base 128k mapping is controlled via port 0xffe8, so we remove it from the main mapping*/

View file

@ -214,7 +214,7 @@ typedef struct voodoo_t
uint16_t dac_pll_regs[16];
float pixel_clock;
int line_time;
uint64_t line_time;
voodoo_params_t params;
@ -248,7 +248,7 @@ typedef struct voodoo_t
int swap_count;
int disp_buffer, draw_buffer;
int timer_count;
pc_timer_t timer;
int line;
svga_t *svga;
@ -386,7 +386,7 @@ typedef struct voodoo_t
int read_time, write_time, burst_time;
int wake_timer;
pc_timer_t wake_timer;
uint8_t thefilter[256][256]; // pixel filter, feeding from one or two
uint8_t thefilterg[256][256]; // for green
@ -5860,15 +5860,13 @@ static void voodoo_tex_writel(uint32_t addr, uint32_t val, void *p)
#define WAKE_DELAY (TIMER_USEC * 100)
static inline void wake_fifo_thread(voodoo_t *voodoo)
{
if (!voodoo->wake_timer)
if (!timer_is_enabled(&voodoo->wake_timer))
{
/*Don't wake FIFO thread immediately - if we do that it will probably
process one word and go back to sleep, requiring it to be woken on
almost every write. Instead, wait a short while so that the CPU
emulation writes more data so we have more batched-up work.*/
timer_process();
voodoo->wake_timer = WAKE_DELAY;
timer_update_outstanding();
timer_set_delay_u64(&voodoo->wake_timer, WAKE_DELAY);
}
}
@ -5881,8 +5879,6 @@ static void voodoo_wake_timer(void *p)
{
voodoo_t *voodoo = (voodoo_t *)p;
voodoo->wake_timer = 0;
thread_set_event(voodoo->wake_fifo_thread); /*Wake up FIFO thread if moving from idle*/
}
@ -6126,13 +6122,11 @@ static uint32_t voodoo_readl(uint32_t addr, void *p)
break;
case SST_vRetrace:
timer_clock();
temp = voodoo->line & 0x1fff;
break;
case SST_hvRetrace:
timer_clock();
temp = voodoo->line & 0x1fff;
temp |= ((((voodoo->line_time - voodoo->timer_count) * voodoo->h_total) / voodoo->timer_count) << 16) & 0x7ff0000;
temp |= ((((tsc - timer_get_ts_int(&voodoo->timer)) * voodoo->h_total) / (voodoo->line_time >> 32)) << 16) & 0x7ff0000;
break;
case SST_fbiInit5:
@ -6208,7 +6202,7 @@ static void voodoo_pixelclock_update(voodoo_t *voodoo)
voodoo->pixel_clock = t;
clock_const = cpuclock / t;
voodoo->line_time = (int)((double)line_length * clock_const * (double)(1 << TIMER_SHIFT));
voodoo->line_time = (uint64_t)((double)line_length * clock_const * (double)(1ull << 32));
}
static void voodoo_writel(uint32_t addr, uint32_t val, void *p)
@ -7440,9 +7434,9 @@ skip_draw:
voodoo->v_retrace = 0;
}
if (voodoo->line_time)
voodoo->timer_count += voodoo->line_time;
timer_advance_u64(&voodoo->timer, voodoo->line_time);
else
voodoo->timer_count += TIMER_USEC * 32;
timer_advance_u64(&voodoo->timer, TIMER_USEC * 32);
}
static void voodoo_add_status_info(char *s, int max_len, void *p)
@ -7610,7 +7604,7 @@ void *voodoo_card_init()
}
}
timer_add(voodoo_callback, &voodoo->timer_count, TIMER_ALWAYS_ENABLED, voodoo);
timer_add(&voodoo->timer, voodoo_callback, voodoo, 1);
voodoo->svga = svga_get_pri();
voodoo->fbiInit0 = 0;
@ -7627,7 +7621,7 @@ void *voodoo_card_init()
if (voodoo->render_threads == 2)
voodoo->render_thread[1] = thread_create(render_thread_2, voodoo);
timer_add(voodoo_wake_timer, &voodoo->wake_timer, &voodoo->wake_timer, (void *)voodoo);
timer_add(&voodoo->wake_timer, voodoo_wake_timer, (void *)voodoo, 0);
for (c = 0; c < 0x100; c++)
{

View file

@ -190,8 +190,8 @@ typedef struct wy700_t
int enabled; /* Display enabled, 0 or 1 */
int detach; /* Detach cursor, 0 or 1 */
int dispontime, dispofftime;
int vidtime;
uint64_t dispontime, dispofftime;
pc_timer_t timer;
int linepos, displine;
int vc;
@ -490,8 +490,8 @@ void wy700_recalctimings(wy700_t *wy700)
_dispofftime = disptime - _dispontime;
_dispontime *= MDACONST;
_dispofftime *= MDACONST;
wy700->dispontime = (int)(_dispontime * (1 << TIMER_SHIFT));
wy700->dispofftime = (int)(_dispofftime * (1 << TIMER_SHIFT));
wy700->dispontime = (uint64_t)_dispontime;
wy700->dispofftime = (uint64_t)_dispofftime;
}
@ -759,7 +759,7 @@ void wy700_poll(void *p)
if (!wy700->linepos)
{
wy700->vidtime += wy700->dispofftime;
timer_advance_u64(&wy700->timer, wy700->dispofftime);
wy700->cga_stat |= 1;
wy700->mda_stat |= 1;
wy700->linepos = 1;
@ -820,7 +820,7 @@ void wy700_poll(void *p)
wy700->cga_stat &= ~1;
wy700->mda_stat &= ~1;
}
wy700->vidtime += wy700->dispontime;
timer_advance_u64(&wy700->timer, wy700->dispontime);
wy700->linepos = 0;
if (wy700->displine == 800)
@ -868,7 +868,7 @@ void *wy700_init()
/* 128k video RAM */
wy700->vram = malloc(0x20000);
timer_add(wy700_poll, &wy700->vidtime, TIMER_ALWAYS_ENABLED, wy700);
timer_add(&wy700->timer, wy700_poll, wy700, 1);
/* Occupy memory between 0xB0000 and 0xBFFFF (moves to 0xA0000 in
* high-resolution modes) */