2010-12-28 06:03:02 +00:00
|
|
|
//70224 clocks/frame
|
|
|
|
// 456 clocks/scanline
|
|
|
|
// 154 scanlines/frame
|
|
|
|
|
|
|
|
#ifdef CPU_CPP
|
|
|
|
|
|
|
|
void CPU::add_clocks(unsigned clocks) {
|
2013-12-14 06:25:12 +00:00
|
|
|
if(oamdma.active) {
|
2013-12-20 11:40:39 +00:00
|
|
|
for(unsigned n = 0; n < 4 * clocks; n++) {
|
2013-12-14 06:25:12 +00:00
|
|
|
bus.write(0xfe00 + oamdma.offset, bus.read((oamdma.bank << 8) + oamdma.offset));
|
|
|
|
if(++oamdma.offset == 160) {
|
|
|
|
oamdma.active = false;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-01-06 10:16:07 +00:00
|
|
|
system.clocks_executed += clocks;
|
2011-10-28 09:51:43 +00:00
|
|
|
if(system.sgb()) scheduler.exit(Scheduler::ExitReason::StepEvent);
|
2011-01-06 10:16:07 +00:00
|
|
|
|
2011-01-04 10:42:27 +00:00
|
|
|
status.clock += clocks;
|
2011-10-27 13:30:19 +00:00
|
|
|
if(status.clock >= 4 * 1024 * 1024) {
|
|
|
|
status.clock -= 4 * 1024 * 1024;
|
2011-01-04 10:42:27 +00:00
|
|
|
cartridge.mbc3.second();
|
|
|
|
}
|
|
|
|
|
2011-10-27 13:30:19 +00:00
|
|
|
//4MHz / N(hz) - 1 = mask
|
|
|
|
if((status.clock & 15) == 0) timer_262144hz();
|
|
|
|
if((status.clock & 63) == 0) timer_65536hz();
|
|
|
|
if((status.clock & 255) == 0) timer_16384hz();
|
|
|
|
if((status.clock & 511) == 0) timer_8192hz();
|
|
|
|
if((status.clock & 1023) == 0) timer_4096hz();
|
2010-12-28 06:03:02 +00:00
|
|
|
|
Update to v088r08 release.
byuu says:
From this WIP, I'm starting on the impossible task of
a declarative-based GUI, which I'm calling Ethos.
base/ becomes emulator/, and we add emulator/interface.hpp, which is
a base API that all emulation cores must implement in full.
(Right now, it's kind of a hybrid to work with the old GUI and the new
GUI at the same time, of course.)
Unlike the old interfaces, the new base class also provides all general
usability hooks: loading and saving files and states, cheat codes, etc.
The new interface also contains information and vector structs to
describe all possible loading methods, controller bindings, etc; and
gives names for them all.
The actual GUI in fact should not include eg <gba/gba.hpp> anymore.
Should speed up GUI compilation.
So the idea going forward is that ethos will build a list of emulators
right when the application starts up.
Once you've appended an emulator to that list, you're done. No more GUI
changes are needed to support that system.
The GUI will have code to parse the emulator interfaces list, and build
all the requisite GUI options dynamically, declarative style.
Ultimately, once the project is finished, the new GUI should look ~99%
identical to the current GUI. But it'll probably be a whole lot smaller.
2012-04-29 06:29:54 +00:00
|
|
|
ppu.clock -= clocks * ppu.frequency;
|
2012-04-26 10:51:13 +00:00
|
|
|
if(ppu.clock < 0) co_switch(scheduler.active_thread = ppu.thread);
|
2011-02-02 10:37:31 +00:00
|
|
|
|
Update to v088r08 release.
byuu says:
From this WIP, I'm starting on the impossible task of
a declarative-based GUI, which I'm calling Ethos.
base/ becomes emulator/, and we add emulator/interface.hpp, which is
a base API that all emulation cores must implement in full.
(Right now, it's kind of a hybrid to work with the old GUI and the new
GUI at the same time, of course.)
Unlike the old interfaces, the new base class also provides all general
usability hooks: loading and saving files and states, cheat codes, etc.
The new interface also contains information and vector structs to
describe all possible loading methods, controller bindings, etc; and
gives names for them all.
The actual GUI in fact should not include eg <gba/gba.hpp> anymore.
Should speed up GUI compilation.
So the idea going forward is that ethos will build a list of emulators
right when the application starts up.
Once you've appended an emulator to that list, you're done. No more GUI
changes are needed to support that system.
The GUI will have code to parse the emulator interfaces list, and build
all the requisite GUI options dynamically, declarative style.
Ultimately, once the project is finished, the new GUI should look ~99%
identical to the current GUI. But it'll probably be a whole lot smaller.
2012-04-29 06:29:54 +00:00
|
|
|
apu.clock -= clocks * apu.frequency;
|
2012-04-26 10:51:13 +00:00
|
|
|
if(apu.clock < 0) co_switch(scheduler.active_thread = apu.thread);
|
2010-12-28 06:03:02 +00:00
|
|
|
}
|
|
|
|
|
Update to v075r05 release.
byuu says:
Added Game Boy sound emulation, all four channels.
It's really, really, really bad. Plenty of bugs, I don't even know what
the fuck a high-pass filter is so that isn't there. Hermite resampling
from 4MHz down to 44KHz. But it's tolerable.
I don't understand what sweep is for at all, and I'm sure I have that
insane recursive reload behavior wrong.
This is pretty much my own design. I referenced blargg's gb snd emu,
blargg's older gb apu ref, Cydrak's APU core, that lousy gbdev wiki
article, the completely and utterly worthless pandocs, and received
nothing but bad and wrong information that just wasted my time from
But I managed to pull it off. It's also painfully slow, like 250fps on
my machine slow. Countless optimizations are possible.
2011-02-02 10:38:28 +00:00
|
|
|
void CPU::timer_262144hz() {
|
2011-01-02 04:46:54 +00:00
|
|
|
if(status.timer_enable && status.timer_clock == 1) {
|
2010-12-30 07:18:47 +00:00
|
|
|
if(++status.tima == 0) {
|
|
|
|
status.tima = status.tma;
|
2011-01-02 04:46:54 +00:00
|
|
|
interrupt_raise(Interrupt::Timer);
|
2010-12-30 07:18:47 +00:00
|
|
|
}
|
|
|
|
}
|
2010-12-28 06:03:02 +00:00
|
|
|
}
|
|
|
|
|
Update to v075r05 release.
byuu says:
Added Game Boy sound emulation, all four channels.
It's really, really, really bad. Plenty of bugs, I don't even know what
the fuck a high-pass filter is so that isn't there. Hermite resampling
from 4MHz down to 44KHz. But it's tolerable.
I don't understand what sweep is for at all, and I'm sure I have that
insane recursive reload behavior wrong.
This is pretty much my own design. I referenced blargg's gb snd emu,
blargg's older gb apu ref, Cydrak's APU core, that lousy gbdev wiki
article, the completely and utterly worthless pandocs, and received
nothing but bad and wrong information that just wasted my time from
But I managed to pull it off. It's also painfully slow, like 250fps on
my machine slow. Countless optimizations are possible.
2011-02-02 10:38:28 +00:00
|
|
|
void CPU::timer_65536hz() {
|
2011-01-02 04:46:54 +00:00
|
|
|
if(status.timer_enable && status.timer_clock == 2) {
|
2010-12-30 07:18:47 +00:00
|
|
|
if(++status.tima == 0) {
|
|
|
|
status.tima = status.tma;
|
2011-01-02 04:46:54 +00:00
|
|
|
interrupt_raise(Interrupt::Timer);
|
2010-12-30 07:18:47 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
Update to v075r05 release.
byuu says:
Added Game Boy sound emulation, all four channels.
It's really, really, really bad. Plenty of bugs, I don't even know what
the fuck a high-pass filter is so that isn't there. Hermite resampling
from 4MHz down to 44KHz. But it's tolerable.
I don't understand what sweep is for at all, and I'm sure I have that
insane recursive reload behavior wrong.
This is pretty much my own design. I referenced blargg's gb snd emu,
blargg's older gb apu ref, Cydrak's APU core, that lousy gbdev wiki
article, the completely and utterly worthless pandocs, and received
nothing but bad and wrong information that just wasted my time from
But I managed to pull it off. It's also painfully slow, like 250fps on
my machine slow. Countless optimizations are possible.
2011-02-02 10:38:28 +00:00
|
|
|
void CPU::timer_16384hz() {
|
2011-01-02 04:46:54 +00:00
|
|
|
if(status.timer_enable && status.timer_clock == 3) {
|
2010-12-30 07:18:47 +00:00
|
|
|
if(++status.tima == 0) {
|
|
|
|
status.tima = status.tma;
|
2011-01-02 04:46:54 +00:00
|
|
|
interrupt_raise(Interrupt::Timer);
|
2010-12-30 07:18:47 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
status.div++;
|
|
|
|
}
|
|
|
|
|
Update to v075r05 release.
byuu says:
Added Game Boy sound emulation, all four channels.
It's really, really, really bad. Plenty of bugs, I don't even know what
the fuck a high-pass filter is so that isn't there. Hermite resampling
from 4MHz down to 44KHz. But it's tolerable.
I don't understand what sweep is for at all, and I'm sure I have that
insane recursive reload behavior wrong.
This is pretty much my own design. I referenced blargg's gb snd emu,
blargg's older gb apu ref, Cydrak's APU core, that lousy gbdev wiki
article, the completely and utterly worthless pandocs, and received
nothing but bad and wrong information that just wasted my time from
But I managed to pull it off. It's also painfully slow, like 250fps on
my machine slow. Countless optimizations are possible.
2011-02-02 10:38:28 +00:00
|
|
|
void CPU::timer_8192hz() {
|
Update to v074r11 release.
byuu says:
Changelog:
- debugger compiles on all three profiles
- libsnes compiles on all three platforms (no API changes to libsnes)
- memory.cpp : namespace memory removed (wram -> cpu, apuram -> smp,
vram, oam, cgram -> ppu)
- sa1.cpp : namespace memory removed (SA-1 specific functions merged
inline to SA1::bus_read,write)
- GameBoy: added serial link support with interrupts and proper 8192hz
timing, but obviously it acts as if no other GB is connected to it
- GameBoy: added STAT OAM interrupt, and better STAT d1,d0 mode values
- UI: since Qt is dead, I've renamed the config files back to bsnes.cfg
and bsnes-geometry.cfg
- SA1: IRAM was not syncing to CPU on SA-1 side
- PPU/Accuracy and PPU/Performance needed Sprite oam renamed to Sprite
sprite; so that I could add uint8 oam[544]
- makes more sense anyway, OAM = object attribute memory, obj or
sprite are better names for Sprite rendering class
- more cleanup
2011-01-24 09:03:17 +00:00
|
|
|
if(status.serial_transfer && status.serial_clock) {
|
|
|
|
if(--status.serial_bits == 0) {
|
|
|
|
status.serial_transfer = 0;
|
|
|
|
interrupt_raise(Interrupt::Serial);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
Update to v075r05 release.
byuu says:
Added Game Boy sound emulation, all four channels.
It's really, really, really bad. Plenty of bugs, I don't even know what
the fuck a high-pass filter is so that isn't there. Hermite resampling
from 4MHz down to 44KHz. But it's tolerable.
I don't understand what sweep is for at all, and I'm sure I have that
insane recursive reload behavior wrong.
This is pretty much my own design. I referenced blargg's gb snd emu,
blargg's older gb apu ref, Cydrak's APU core, that lousy gbdev wiki
article, the completely and utterly worthless pandocs, and received
nothing but bad and wrong information that just wasted my time from
But I managed to pull it off. It's also painfully slow, like 250fps on
my machine slow. Countless optimizations are possible.
2011-02-02 10:38:28 +00:00
|
|
|
void CPU::timer_4096hz() {
|
2011-01-02 04:46:54 +00:00
|
|
|
if(status.timer_enable && status.timer_clock == 0) {
|
2010-12-30 07:18:47 +00:00
|
|
|
if(++status.tima == 0) {
|
|
|
|
status.tima = status.tma;
|
2011-01-02 04:46:54 +00:00
|
|
|
interrupt_raise(Interrupt::Timer);
|
2010-12-30 07:18:47 +00:00
|
|
|
}
|
|
|
|
}
|
2010-12-28 06:03:02 +00:00
|
|
|
}
|
|
|
|
|
2011-10-27 00:00:17 +00:00
|
|
|
void CPU::hblank() {
|
2013-12-10 12:12:54 +00:00
|
|
|
if(status.dma_mode == 1 && status.dma_length && ppu.status.ly < 144) {
|
2011-10-27 00:00:17 +00:00
|
|
|
for(unsigned n = 0; n < 16; n++) {
|
2013-12-10 12:12:54 +00:00
|
|
|
dma_write(status.dma_target++, dma_read(status.dma_source++));
|
2011-10-27 00:00:17 +00:00
|
|
|
}
|
2013-12-10 12:12:54 +00:00
|
|
|
add_clocks(8 << status.speed_double);
|
2011-10-27 00:00:17 +00:00
|
|
|
status.dma_length -= 16;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-12-28 06:03:02 +00:00
|
|
|
#endif
|