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:
parent
ab359ca9c5
commit
a7d006b637
79 changed files with 1050 additions and 1033 deletions
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
18
src/808x.c
18
src/808x.c
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
18
src/disc.c
18
src/disc.c
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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
123
src/fdc.c
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
13
src/ibm.h
13
src/ibm.h
|
|
@ -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;
|
||||
|
||||
|
||||
|
|
|
|||
76
src/ide.c
76
src/ide.c
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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];
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
14
src/intel.c
14
src/intel.c
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
{
|
||||
|
|
@ -213,10 +202,8 @@ 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 =
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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,8 +126,7 @@ 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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
50
src/mfm_at.c
50
src/mfm_at.c
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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,13 +314,11 @@ 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;
|
||||
|
||||
drive = &xebec->drives[xebec->drive_sel];
|
||||
|
||||
|
||||
switch (xebec->command[0])
|
||||
{
|
||||
case CMD_TEST_DRIVE_READY:
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
34
src/nvr.c
34
src/nvr.c
|
|
@ -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);
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
194
src/pit.c
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
extern double PITCONST;
|
||||
extern uint64_t PITCONST;
|
||||
void pit_init();
|
||||
void pit_ps2_init();
|
||||
void pit_reset();
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
@ -269,21 +269,18 @@ void cd_set_speed(int speed)
|
|||
static void scsi_cd_callback(void *p)
|
||||
{
|
||||
scsi_cd_data_t *data = p;
|
||||
|
||||
|
||||
if (data->cmd_pos == CMD_POS_WAIT)
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
12
src/serial.c
12
src/serial.c
|
|
@ -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)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
||||
|
|
|
|||
|
|
@ -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 =
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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];
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
205
src/timer.c
205
src/timer.c
|
|
@ -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;
|
||||
|
||||
int timer_count = 0, timer_latch = 0;
|
||||
int timer_start = 0;
|
||||
// pclog("timer->enable %p %i\n", timer, timer->enabled);
|
||||
if (timer->enabled)
|
||||
timer_disable(timer);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
void timer_set_callback(int timer, void (*callback)(void *priv))
|
||||
{
|
||||
timers[timer].callback = callback;
|
||||
memset(timer, 0, sizeof(pc_timer_t));
|
||||
|
||||
timer->callback = callback;
|
||||
timer->p = p;
|
||||
timer->enabled = 0;
|
||||
timer->prev = timer->next = NULL;
|
||||
if (start_timer)
|
||||
timer_set_delay_u64(timer, 0);
|
||||
}
|
||||
|
|
|
|||
166
src/timer.h
166
src/timer.h
|
|
@ -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.
|
||||
|
||||
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_start_period(cycles) \
|
||||
timer_start = cycles;
|
||||
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_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)
|
||||
void (*callback)(void *p);
|
||||
void *p;
|
||||
|
||||
#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)
|
||||
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_*/
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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) */
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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*/
|
||||
|
|
|
|||
|
|
@ -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*/
|
||||
|
|
|
|||
|
|
@ -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++)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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) */
|
||||
|
|
|
|||
Loading…
Reference in a new issue