Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
alexbevi
GitHub Repository: alexbevi/BizHawk
Path: blob/master/libsnes/bsnes/snes/alt/cpu/timing.cpp
2 views
1
#ifdef CPU_CPP
2
3
void CPU::queue_event(unsigned id) {
4
switch(id) {
5
case QueueEvent::DramRefresh: return add_clocks(40);
6
case QueueEvent::HdmaRun: return hdma_run();
7
}
8
}
9
10
void CPU::last_cycle() {
11
if(status.irq_lock) {
12
status.irq_lock = false;
13
return;
14
}
15
16
if(status.nmi_transition) {
17
regs.wai = false;
18
status.nmi_transition = false;
19
status.nmi_pending = true;
20
}
21
22
if(status.irq_transition || regs.irq) {
23
regs.wai = false;
24
status.irq_transition = false;
25
status.irq_pending = !regs.p.i;
26
}
27
}
28
29
void CPU::add_clocks(unsigned clocks) {
30
if(status.hirq_enabled) {
31
if(status.virq_enabled) {
32
unsigned cpu_time = vcounter() * 1364 + hcounter();
33
unsigned irq_time = status.vtime * 1364 + status.htime * 4;
34
unsigned framelines = (system.region() == System::Region::NTSC ? 262 : 312) + field();
35
if(cpu_time > irq_time) irq_time += framelines * 1364;
36
bool irq_valid = status.irq_valid;
37
status.irq_valid = cpu_time <= irq_time && cpu_time + clocks > irq_time;
38
if(!irq_valid && status.irq_valid) status.irq_line = true;
39
} else {
40
unsigned irq_time = status.htime * 4;
41
if(hcounter() > irq_time) irq_time += 1364;
42
bool irq_valid = status.irq_valid;
43
status.irq_valid = hcounter() <= irq_time && hcounter() + clocks > irq_time;
44
if(!irq_valid && status.irq_valid) status.irq_line = true;
45
}
46
if(status.irq_line) status.irq_transition = true;
47
} else if(status.virq_enabled) {
48
bool irq_valid = status.irq_valid;
49
status.irq_valid = vcounter() == status.vtime;
50
if(!irq_valid && status.irq_valid) status.irq_line = true;
51
if(status.irq_line) status.irq_transition = true;
52
} else {
53
status.irq_valid = false;
54
}
55
56
tick(clocks);
57
queue.tick(clocks);
58
step(clocks);
59
}
60
61
void CPU::scanline() {
62
synchronize_smp();
63
synchronize_ppu();
64
synchronize_coprocessors();
65
system.scanline();
66
67
if(vcounter() == 0) hdma_init();
68
69
queue.enqueue(534, QueueEvent::DramRefresh);
70
71
if(vcounter() <= (ppu.overscan() == false ? 224 : 239)) {
72
queue.enqueue(1104 + 8, QueueEvent::HdmaRun);
73
}
74
75
bool nmi_valid = status.nmi_valid;
76
status.nmi_valid = vcounter() >= (ppu.overscan() == false ? 225 : 240);
77
if(!nmi_valid && status.nmi_valid) {
78
status.nmi_line = true;
79
if(status.nmi_enabled) status.nmi_transition = true;
80
} else if(nmi_valid && !status.nmi_valid) {
81
status.nmi_line = false;
82
}
83
84
if(status.auto_joypad_poll_enabled && vcounter() == (ppu.overscan() == false ? 227 : 242)) {
85
run_auto_joypad_poll();
86
}
87
}
88
89
void CPU::run_auto_joypad_poll() {
90
91
input.port1->latch(1);
92
input.port2->latch(1);
93
input.port1->latch(0);
94
input.port2->latch(0);
95
interface()->inputNotify(1);
96
interface()->inputNotify(0);
97
98
99
uint16 joy1 = 0, joy2 = 0, joy3 = 0, joy4 = 0;
100
for(unsigned i = 0; i < 16; i++) {
101
uint8 port0 = input.port1->data();
102
uint8 port1 = input.port2->data();
103
104
joy1 |= (port0 & 1) ? (0x8000 >> i) : 0;
105
joy2 |= (port1 & 1) ? (0x8000 >> i) : 0;
106
joy3 |= (port0 & 2) ? (0x8000 >> i) : 0;
107
joy4 |= (port1 & 2) ? (0x8000 >> i) : 0;
108
}
109
110
status.joy1l = joy1;
111
status.joy1h = joy1 >> 8;
112
113
status.joy2l = joy2;
114
status.joy2h = joy2 >> 8;
115
116
status.joy3l = joy3;
117
status.joy3h = joy3 >> 8;
118
119
status.joy4l = joy4;
120
status.joy4h = joy4 >> 8;
121
}
122
123
#endif
124
125