Skip to content

Commit 25e82a2

Browse files
authored
Merge pull request #20 from allkern/master
Merge master work
2 parents b44dd3c + dc08cd7 commit 25e82a2

File tree

3 files changed

+101
-64
lines changed

3 files changed

+101
-64
lines changed

src/ee/timers.c

Lines changed: 83 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ uint64_t ps2_ee_timers_read32(struct ps2_ee_timers* timers, uint32_t addr) {
3232
// printf("ee: timer %d read %08x\n", t, addr & 0xff);
3333

3434
switch (addr & 0xff) {
35-
case 0x00: return timers->timer[t].counter;
35+
case 0x00: return timers->timer[t].counter & 0xffff;
3636
case 0x10: return timers->timer[t].mode;
3737
case 0x20: return timers->timer[t].compare;
3838
case 0x30: return timers->timer[t].hold;
@@ -42,11 +42,61 @@ uint64_t ps2_ee_timers_read32(struct ps2_ee_timers* timers, uint32_t addr) {
4242
}
4343

4444
static inline void ee_timers_write_mode(struct ps2_ee_timers* timers, uint32_t data, int t) {
45-
timers->timer[t].mode &= 0xc00;
46-
timers->timer[t].mode |= data & (~0xc00);
47-
timers->timer[t].mode &= ~(data & 0xc00);
45+
struct ee_timer* timer = &timers->timer[t];
46+
47+
timer->mode &= 0xc00;
48+
timer->mode |= data & (~0xc00);
49+
timer->mode &= ~(data & 0xc00);
50+
51+
timer->clks = data & 3;
52+
timer->gate = (data >> 2) & 1;
53+
timer->gats = (data >> 3) & 1;
54+
timer->gatm = (data >> 4) & 3;
55+
timer->zret = (data >> 6) & 1;
56+
timer->cue = (data >> 7) & 1;
57+
timer->cmpe = (data >> 8) & 1;
58+
timer->ovfe = (data >> 9) & 1;
59+
60+
if (timer->gate) {
61+
printf("timers: Timer %d gate write %08x\n", t, data);
62+
63+
exit(1);
64+
}
65+
66+
// printf("timers: Timer %d mode write %08x mode=%08x counter=%04x compare=%04x clks=%d gate=%d gats=%d gatm=%d zret=%d cue=%d cmpe=%d ovfe=%d\n",
67+
// t, data,
68+
// timer->mode,
69+
// timer->counter,
70+
// timer->compare,
71+
// timer->clks, timer->gate, timer->gats, timer->gatm,
72+
// timer->zret, timer->cue, timer->cmpe, timer->ovfe
73+
// );
74+
75+
switch (timer->clks) {
76+
case 0: timer->delta = 1; break;
77+
case 1: timer->delta = 16; break;
78+
case 2: timer->delta = 256; break;
79+
case 3: timer->delta = 9370; break;
80+
}
81+
82+
timer->delta_reload = timer->delta;
4883

49-
// printf("timers: timer %d write %08x -> %08x\n", t, data, timers->timer[t].mode);
84+
if (timer->cmpe || timer->ovfe) {
85+
timer->check_enabled = 1;
86+
87+
if (timer->counter < timer->compare) {
88+
timer->cycles_until_check = timer->compare - timer->counter;
89+
} else {
90+
timer->cycles_until_check = 0;
91+
}
92+
93+
timer->check_reload = timer->cycles_until_check;
94+
95+
printf("timer %d: compare/overflow IRQ enabled counter=%04x target=%04x\n", t, timer->counter, timer->compare);
96+
97+
if (timer->ovfe)
98+
exit(1);
99+
}
50100
}
51101

52102
void ps2_ee_timers_write32(struct ps2_ee_timers* timers, uint32_t addr, uint64_t data) {
@@ -62,77 +112,47 @@ void ps2_ee_timers_write32(struct ps2_ee_timers* timers, uint32_t addr, uint64_t
62112
}
63113
}
64114

65-
void ee_timer_tick(struct ps2_ee_timers* timers, int timer) {
66-
struct ee_timer* t = &timers->timer[timer];
115+
int loop2 = 1;
67116

68-
if (!(t->mode & 0x80))
69-
return;
117+
void ps2_ee_timers_tick(struct ps2_ee_timers* timers) {
118+
for (int i = 0; i < 4; i++) {
119+
struct ee_timer* t = &timers->timer[i];
70120

71-
uint32_t prev = t->counter;
121+
if (!t->cue)
122+
continue;
72123

73-
switch (t->mode & 3) {
74-
case 0: {
75-
++t->counter;
76-
} break;
77-
case 1: {
78-
if (t->internal >= 16) {
79-
++t->counter;
80-
t->internal = 0;
81-
} else {
82-
++t->internal;
83-
}
84-
} break;
85-
case 2: {
86-
if (t->internal >= 256) {
87-
++t->counter;
88-
t->internal = 0;
89-
} else {
90-
++t->internal;
91-
}
92-
} break;
93-
case 3: {
94-
if (t->internal >= 9370) {
95-
++t->counter;
96-
t->internal = 0;
97-
} else {
98-
++t->internal;
99-
}
100-
} break;
101-
}
124+
t->delta--;
102125

103-
// printf("ee: timer %d counter=%08x\n", timer, t->counter);
126+
if (t->delta)
127+
continue;
104128

105-
if ((t->counter >= t->compare) && (prev < t->compare)) {
106-
t->mode |= 0x400;
129+
t->delta = t->delta_reload;
130+
t->counter++;
131+
t->counter &= 0xffff;
107132

108-
if (t->mode & 0x100) {
109-
// printf("ee: timer %d compare IRQ\n", timer);
133+
if (t->check_enabled) {
134+
t->cycles_until_check--;
110135

111-
ps2_intc_irq(timers->intc, EE_INTC_TIMER0 + timer);
112-
}
136+
if (t->cycles_until_check)
137+
continue;
113138

114-
if (t->mode & 0x40) {
115-
t->counter = 0;
116-
}
117-
}
139+
// printf("timer %d: counter=%04x target=%04x cycles_until_check=%04x\n", i, t->counter, t->compare, t->cycles_until_check);
118140

119-
if (t->counter > 0xffff) {
120-
t->mode |= 0x800;
121-
t->counter -= 0xffff;
141+
// if (!loop2--)
142+
// exit(1);
122143

123-
if (t->mode & 0x200) {
124-
// printf("ee: timer %d overflow IRQ\n", timer);
144+
if (t->cmpe && t->counter == t->compare) {
145+
ps2_intc_irq(timers->intc, EE_INTC_TIMER0 + i);
146+
}
125147

126-
ps2_intc_irq(timers->intc, EE_INTC_TIMER0 + timer);
148+
if (t->zret) {
149+
t->counter = 0;
150+
t->cycles_until_check = t->compare;
151+
} else {
152+
t->cycles_until_check = 0x10000;
153+
}
127154
}
128155
}
129-
130-
t->counter &= 0xffff;
131-
}
132-
133-
void ps2_ee_timers_tick(struct ps2_ee_timers* timers) {
134-
for (int i = 0; i < 4; i++)
135-
ee_timer_tick(timers, i);
136156
}
137157

138158
void ps2_ee_timers_write16(struct ps2_ee_timers* timers, uint32_t addr, uint64_t data) {

src/ee/timers.h

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,24 @@ struct ee_timer {
1515
uint16_t mode;
1616
uint32_t compare;
1717
uint16_t hold;
18+
19+
// Internal state
1820
uint32_t internal;
21+
uint32_t delta;
22+
uint32_t delta_reload;
23+
uint32_t cycles_until_check;
24+
uint32_t check_reload;
25+
int check_enabled;
26+
27+
// Mode fields
28+
int clks;
29+
int gate;
30+
int gats;
31+
int gatm;
32+
int zret;
33+
int cue;
34+
int cmpe;
35+
int ovfe;
1936
};
2037

2138
struct ps2_ee_timers {

src/gs/renderer/software_thread.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -398,7 +398,7 @@ void software_thread_render_thread(software_thread_state* ctx) {
398398
ctx->render_mtx.unlock();
399399
}
400400

401-
std::this_thread::yield();
401+
// std::this_thread::yield();
402402
}
403403
}
404404

0 commit comments

Comments
 (0)