2012-03-19 11:19:53 +00:00
|
|
|
#include <gba/gba.hpp>
|
|
|
|
|
2012-04-26 10:51:13 +00:00
|
|
|
namespace GameBoyAdvance {
|
2012-03-19 11:19:53 +00:00
|
|
|
|
Update to v103r07 release.
byuu says:
Changelog:
- gba/cpu: massive code cleanup effort
- gba/cpu: DMA can run in between active instructions¹
- gba/cpu: added two-cycle startup delay between DMA activation and
DMA transfers²
- processor/spc700: BBC, BBC, CBNE cycle 4 is an idle cycle
- processor/spc700: ADDW, SUBW, MOVW (read) cycle 4 is an idle cycle
¹: unfortunately, this causes yet another performance penalty for the
poor GBA core =( Also, I think I may have missed disabling DMAs while
the CPU is stopped. I'll fix that in the next WIP.
²: I put the waiting counter decrement at the wrong place, so this
doesn't actually work. Needs to be more like
this:
auto CPU::step(uint clocks) -> void {
for(auto _ : range(clocks)) {
for(auto& timer : this->timer) timer.run();
for(auto& dma : this->dma) if(dma.active && dma.waiting) dma.waiting--;
context.clock++;
}
...
auto CPU::DMA::run() -> bool {
if(cpu.stopped() || !active || waiting) return false;
transfer();
if(irq) cpu.irq.flag |= CPU::Interrupt::DMA0 << id;
if(drq && id == 3) cpu.irq.flag |= CPU::Interrupt::Cartridge;
return true;
}
Of course, the real fix will be restructuring how DMA works, so that
it's always running in parallel with the CPU instead of this weird
design where it tries to run all channels in some kind of loop until no
channels are active anymore whenever one channel is activated.
Not really sure how to design that yet, however.
2017-07-05 05:29:27 +00:00
|
|
|
CPU cpu;
|
2015-06-27 02:38:08 +00:00
|
|
|
#include "prefetch.cpp"
|
2015-07-01 10:58:42 +00:00
|
|
|
#include "bus.cpp"
|
Update to v099r13 release.
byuu says:
Changelog:
- GB core code cleanup completed
- GBA core code cleanup completed
- some more cleanup on missed processor/arm functions/variables
- fixed FC loading icarus bug
- "Load ROM File" icarus functionality restored
- minor code unification efforts all around (not perfect yet)
- MMIO->IO
- mmio.cpp->io.cpp
- read,write->readIO,writeIO
It's been a very long work in progress ... starting all the way back with
v094r09, but the major part of the higan code cleanup is now completed! Of
course, it's very important to note that this is only for the basic style:
- under_score functions and variables are now camelCase
- return-type function-name() are now auto function-name() -> return-type
- Natural<T>/Integer<T> replace (u)intT_n types where possible
- signed/unsigned are now int/uint
- most of the x==true,x==false tests changed to x,!x
A lot of spot improvements to consistency, simplicity and quality have
gone in along the way, of course. But we'll probably never fully finishing
beautifying every last line of code in the entire codebase. Still,
this is a really great start. Going forward, WIP diffs should start
being smaller and of higher quality once again.
I know the joke is, "until my coding style changes again", but ... this
was way too stressful, way too time consuming, and way too risky. I'm
too old and tired now for extreme upheavel like this again. The only
major change I'm slowly mulling over would be renaming the using
Natural<T>/Integer<T> = (u)intT; shorthand to something that isn't as
easily confused with the (u)int_t types ... but we'll see. I'll definitely
continue to change small things all the time, but for the larger picture,
I need to just accept the style I have and live with it.
2016-06-29 11:10:28 +00:00
|
|
|
#include "io.cpp"
|
Update to v087r26 release.
byuu says:
Changelog:
- fixed FIFO[1] reset behavior (fixes audio in Sword of Mana)
- added FlashROM emulation (both sizes)
- GBA parses RAM settings from manifest.xml now
- save RAM is written to disk now
- added save state support (it's currently broken, though)
- fixed ROM/RAM access timings
- open bus should mostly work (we don't do the PC+12 stuff yet)
- emulated the undocumented memory control register (mirror IWRAM,
disable I+EWRAM, EWRAM wait state count)
- emulated keypad interrupts
- emulated STOP (freezes video, audio, DMA and timers; only breaks on
keypad IRQs)
- probably a lot more, it was a long night ...
Show stoppers, missing things, broken things, etc:
- ST018 is still completely broken
- GBC audio sequencer apparently needs work
- GBA audio FIFO buffer seems too quiet
- PHI / ROM prefetch needs to be emulated (no idea on how to do this,
especially PHI)
- SOUNDBIAS 64/128/256khz modes should output at that resolution
(really, we need to simulate PWM properly, no idea on how to do this)
- object mosaic top-left coordinates are wrong (minor, fixing will
actually make the effect look worse)
- need to emulate PPU greenswap and color palette distortion (no idea on
how do this)
- need GBA save type database (I would also LIKE to blacklist
/ patch-out trainers, but that's a discussion for another day.)
- some ARM ops advance the prefetch buffer, so you can read PC+12 in
some cases
2012-04-16 12:19:39 +00:00
|
|
|
#include "memory.cpp"
|
2012-04-03 23:50:40 +00:00
|
|
|
#include "dma.cpp"
|
2012-04-07 08:17:49 +00:00
|
|
|
#include "timer.cpp"
|
Update to v103r07 release.
byuu says:
Changelog:
- gba/cpu: massive code cleanup effort
- gba/cpu: DMA can run in between active instructions¹
- gba/cpu: added two-cycle startup delay between DMA activation and
DMA transfers²
- processor/spc700: BBC, BBC, CBNE cycle 4 is an idle cycle
- processor/spc700: ADDW, SUBW, MOVW (read) cycle 4 is an idle cycle
¹: unfortunately, this causes yet another performance penalty for the
poor GBA core =( Also, I think I may have missed disabling DMAs while
the CPU is stopped. I'll fix that in the next WIP.
²: I put the waiting counter decrement at the wrong place, so this
doesn't actually work. Needs to be more like
this:
auto CPU::step(uint clocks) -> void {
for(auto _ : range(clocks)) {
for(auto& timer : this->timer) timer.run();
for(auto& dma : this->dma) if(dma.active && dma.waiting) dma.waiting--;
context.clock++;
}
...
auto CPU::DMA::run() -> bool {
if(cpu.stopped() || !active || waiting) return false;
transfer();
if(irq) cpu.irq.flag |= CPU::Interrupt::DMA0 << id;
if(drq && id == 3) cpu.irq.flag |= CPU::Interrupt::Cartridge;
return true;
}
Of course, the real fix will be restructuring how DMA works, so that
it's always running in parallel with the CPU instead of this weird
design where it tries to run all channels in some kind of loop until no
channels are active anymore whenever one channel is activated.
Not really sure how to design that yet, however.
2017-07-05 05:29:27 +00:00
|
|
|
#include "keypad.cpp"
|
Update to v087r26 release.
byuu says:
Changelog:
- fixed FIFO[1] reset behavior (fixes audio in Sword of Mana)
- added FlashROM emulation (both sizes)
- GBA parses RAM settings from manifest.xml now
- save RAM is written to disk now
- added save state support (it's currently broken, though)
- fixed ROM/RAM access timings
- open bus should mostly work (we don't do the PC+12 stuff yet)
- emulated the undocumented memory control register (mirror IWRAM,
disable I+EWRAM, EWRAM wait state count)
- emulated keypad interrupts
- emulated STOP (freezes video, audio, DMA and timers; only breaks on
keypad IRQs)
- probably a lot more, it was a long night ...
Show stoppers, missing things, broken things, etc:
- ST018 is still completely broken
- GBC audio sequencer apparently needs work
- GBA audio FIFO buffer seems too quiet
- PHI / ROM prefetch needs to be emulated (no idea on how to do this,
especially PHI)
- SOUNDBIAS 64/128/256khz modes should output at that resolution
(really, we need to simulate PWM properly, no idea on how to do this)
- object mosaic top-left coordinates are wrong (minor, fixing will
actually make the effect look worse)
- need to emulate PPU greenswap and color palette distortion (no idea on
how do this)
- need GBA save type database (I would also LIKE to blacklist
/ patch-out trainers, but that's a discussion for another day.)
- some ARM ops advance the prefetch buffer, so you can read PC+12 in
some cases
2012-04-16 12:19:39 +00:00
|
|
|
#include "serialization.cpp"
|
2015-11-16 08:38:05 +00:00
|
|
|
|
2015-06-25 09:52:32 +00:00
|
|
|
auto CPU::Enter() -> void {
|
2016-02-09 11:51:12 +00:00
|
|
|
while(true) scheduler.synchronize(), cpu.main();
|
Update to v087r26 release.
byuu says:
Changelog:
- fixed FIFO[1] reset behavior (fixes audio in Sword of Mana)
- added FlashROM emulation (both sizes)
- GBA parses RAM settings from manifest.xml now
- save RAM is written to disk now
- added save state support (it's currently broken, though)
- fixed ROM/RAM access timings
- open bus should mostly work (we don't do the PC+12 stuff yet)
- emulated the undocumented memory control register (mirror IWRAM,
disable I+EWRAM, EWRAM wait state count)
- emulated keypad interrupts
- emulated STOP (freezes video, audio, DMA and timers; only breaks on
keypad IRQs)
- probably a lot more, it was a long night ...
Show stoppers, missing things, broken things, etc:
- ST018 is still completely broken
- GBC audio sequencer apparently needs work
- GBA audio FIFO buffer seems too quiet
- PHI / ROM prefetch needs to be emulated (no idea on how to do this,
especially PHI)
- SOUNDBIAS 64/128/256khz modes should output at that resolution
(really, we need to simulate PWM properly, no idea on how to do this)
- object mosaic top-left coordinates are wrong (minor, fixing will
actually make the effect look worse)
- need to emulate PPU greenswap and color palette distortion (no idea on
how do this)
- need GBA save type database (I would also LIKE to blacklist
/ patch-out trainers, but that's a discussion for another day.)
- some ARM ops advance the prefetch buffer, so you can read PC+12 in
some cases
2012-04-16 12:19:39 +00:00
|
|
|
}
|
|
|
|
|
2015-06-25 09:52:32 +00:00
|
|
|
auto CPU::main() -> void {
|
2017-08-09 11:11:59 +00:00
|
|
|
ARM7TDMI::irq = irq.ime && (irq.enable & irq.flag);
|
Update to v087r26 release.
byuu says:
Changelog:
- fixed FIFO[1] reset behavior (fixes audio in Sword of Mana)
- added FlashROM emulation (both sizes)
- GBA parses RAM settings from manifest.xml now
- save RAM is written to disk now
- added save state support (it's currently broken, though)
- fixed ROM/RAM access timings
- open bus should mostly work (we don't do the PC+12 stuff yet)
- emulated the undocumented memory control register (mirror IWRAM,
disable I+EWRAM, EWRAM wait state count)
- emulated keypad interrupts
- emulated STOP (freezes video, audio, DMA and timers; only breaks on
keypad IRQs)
- probably a lot more, it was a long night ...
Show stoppers, missing things, broken things, etc:
- ST018 is still completely broken
- GBC audio sequencer apparently needs work
- GBA audio FIFO buffer seems too quiet
- PHI / ROM prefetch needs to be emulated (no idea on how to do this,
especially PHI)
- SOUNDBIAS 64/128/256khz modes should output at that resolution
(really, we need to simulate PWM properly, no idea on how to do this)
- object mosaic top-left coordinates are wrong (minor, fixing will
actually make the effect look worse)
- need to emulate PPU greenswap and color palette distortion (no idea on
how do this)
- need GBA save type database (I would also LIKE to blacklist
/ patch-out trainers, but that's a discussion for another day.)
- some ARM ops advance the prefetch buffer, so you can read PC+12 in
some cases
2012-04-16 12:19:39 +00:00
|
|
|
|
Update to v103r07 release.
byuu says:
Changelog:
- gba/cpu: massive code cleanup effort
- gba/cpu: DMA can run in between active instructions¹
- gba/cpu: added two-cycle startup delay between DMA activation and
DMA transfers²
- processor/spc700: BBC, BBC, CBNE cycle 4 is an idle cycle
- processor/spc700: ADDW, SUBW, MOVW (read) cycle 4 is an idle cycle
¹: unfortunately, this causes yet another performance penalty for the
poor GBA core =( Also, I think I may have missed disabling DMAs while
the CPU is stopped. I'll fix that in the next WIP.
²: I put the waiting counter decrement at the wrong place, so this
doesn't actually work. Needs to be more like
this:
auto CPU::step(uint clocks) -> void {
for(auto _ : range(clocks)) {
for(auto& timer : this->timer) timer.run();
for(auto& dma : this->dma) if(dma.active && dma.waiting) dma.waiting--;
context.clock++;
}
...
auto CPU::DMA::run() -> bool {
if(cpu.stopped() || !active || waiting) return false;
transfer();
if(irq) cpu.irq.flag |= CPU::Interrupt::DMA0 << id;
if(drq && id == 3) cpu.irq.flag |= CPU::Interrupt::Cartridge;
return true;
}
Of course, the real fix will be restructuring how DMA works, so that
it's always running in parallel with the CPU instead of this weird
design where it tries to run all channels in some kind of loop until no
channels are active anymore whenever one channel is activated.
Not really sure how to design that yet, however.
2017-07-05 05:29:27 +00:00
|
|
|
if(stopped()) {
|
Update to v104 release.
byuu says:
Changelog:
- emulator/interface: removed unused Region struct
- gba/cpu: optimized CPU::step() as much as I could for a slight
speedup¹
- gba/cpu: synchronize the APU better during FIFO updates
- higan/md, icarus: add automatic region detection; make it the
default option [hex\_usr]
- picks NTSC-J if there's more than one match ... eventually, this
will be a setting
- higan/md, icarus: support all three combinations of SRAM (8-bit low,
8-bit high, 16-bit)
- processor/arm7tdmi: fix bug when changing to THUMB mode via MSR
[MerryMage]
- tomoko: redesigned crash detector to only occur once for all three
ruby drivers
- this will reduce disk thrashing since the configuration file
only needs to be written out one extra time
- technically, it's twice ... but we should've always been writing
one out on first run in case it crashes then
- tomoko: defaulted back to the safest ruby drivers, given the optimal
drivers have some stability concerns
¹: minor errata: spotted a typo saying `synchronize(cpu)` when the CPU
is stopped, instead of `synchronize(ppu)`. This will be fixed in the v104
official 7zip archives.
I'm kind of rushing here but, it's really good timing for me to push out
a new official release. The blocking issues are resolved or close to it,
and we need lots of testing of the new major changes.
I'm going to consider this a semi-stable testing release and leave links
to v103 just in case.
2017-08-12 10:53:13 +00:00
|
|
|
if(!(irq.enable & irq.flag & Interrupt::Keypad)) {
|
|
|
|
Thread::step(16);
|
Update to v104 public release.
[As mentioned in the v104 internal release notes, byuu fixed a small typo in
the GBA core. -Ed.]
byuu says:
There are lots of improvements in this new release, both to core
emulation and to the user interface. However, some of these changes are
quite substantial, so regressions are a possibility. Please report any
regressions from v103 on the forums if found.
Note that Mega Drive save RAM files will not be compatible with v103,
but will now be compatible with save RAM files from all other Mega Drive
emulators, and the format will be stable going forward.
Also!! Thanks to the tireless work of Screwtape, the
Help->Documentation link in higan now takes you to a very comprehensive
user guide. Please be sure to consult this if you have any questions
about using higan.
Lastly, I've added a link to my Patreon page (https://patreon.com/byuu/)
to the higan downloads page. The money will go exclusively toward
purchasing SNES games for preservation, hardware and flash carts for
reverse engineering, equipment such as backup drives, etc. Donating is
entirely optional and comes with no rewards, but would of course be
greatly appreciated! ^^;
Changelog (since v103):
- nall/dsp: improved first-order IIR filtering
- Famicom: improved audio filtering (90hz lowpass + 440hz lowpass +
14khz highpass)
- Game Boy Advance: corrected bug in PSG wave channel emulation
[Cydrak]
- Mega Drive: added first-order 2.84KHz low-pass filter to match VA6
model hardware
- Mega Drive: lowered PSG volume relative to YM2612 to match VA6 model
hardware
- Mega Drive: Hblank flag is not always set during Vblank
- Mega Drive: fix PAL mode reporting from control port reads
- Famicom: improved phase duty cycle emulation (mode 3 is 25% phase
inverted; counter decrements)
- Mega Drive: reset does not cancel 68K bus requests
- Mega Drive: 68K is not granted bus access on Z80 reset
- Mega Drive: CTRL port is now read-write, maintains value across
controller changes
- Z80: IX, IY override mode can now be serialized in save states
- 68K: fixed calculations for ABCD, NBCD, SBCD [hex\_usr,
SuperMikeMan]
- SPC700: improved all cycle timings to match results observed by
Overload with a logic anaylzer
- Super Famicom: SMP uses a separate 4x8-bit buffer for $f4-f7; not
APU RAM [hex\_usr]
- Super Famicom: SMP TEST register is now finally 100% fully emulated
[byuu, AWJ]
- Game Boy Advance: DMA can run between CPU instruction cycles
- Game Boy Advance: added 2-cycle delay between DMA activation and
transfers
- higan: improved aspect ratio correction accuracy at higher video
scaling sizes
- higan: overscan masking will now actually crop the underlying video
instead of just blanking it
- Mega Drive: center video when overscan is disabled
- higan: added increment/decrement quick save slot hotkeys
- Game Boy Advance: fixed wave RAM nibble ordering (fixes audio in
Castlevania, Pocket NES)
- higan: added new adaptive windowed mode: resizes the window to the
current emulated system's size
- higan: added new integral scaling mode: resizes the window to fill
as much of the screen as possible
- higan: main window is now resizable and will automatically scale
contents based on user settings
- higan: fixed one-time blinking of the main window on startup caused
by focus stealing bug
- ruby: fixed major memory leak in Direct3D driver
- ruby: added fullscreen exclusive mode to Direct3D driver
- Super Famicom: corrected latching behavior of BGnHOFS PPU registers
- higan: all windows sans the main viewport can be dismissed with the
escape key now
- ruby: complete API rewrite; many audio drivers now support device
selection
- higan: output frequency can now be modified
- higan: configuration settings split to individual menu options for
faster access to individual pages
- ruby: improved WASAPI driver to event-driven model; more compatible
in exclusive mode now
- libco: fix compilation of sjlj and fiber targets [Screwtape]
- ruby: added YV12 and I420 support to X-Video driver
- Game Boy: added TAMA emulation (RTC emulation is not working yet)
[thanks to endrift for notes]
- Game Boy: correct data ordering of MMM01 ROMs (MMM01 ROMs will need
to be re-imported into higan)
- Game Boy: store MBC2 save RAM as 256-bytes instead of 512-bytes (RAM
is 4-bit; not 8-bit with padding)
- Game Boy: fixed a bug with RAM serialization in games without a
battery
- Mega Drive: fix CRAM reads (fixes Sonic Spinball) [hex\_usr]
- Game Boy: added rumble support to MBC5 games such as Pokemon Pinball
- Game Boy: added MBC7 emulation (accelerometer X-axis, EEPROM not
working yet) [thanks to endrift for notes]
- hiro: macOS compilation fixes and UI improvements [MerryMage,
ncbncb]
- Game Boy: added MBC6 emulation (no phone link or flash support;
timing bugs in game still)
- Game Boy: HDMA syncs to other components after each byte transfer
now
- Game Boy: disabling the LCD completely halts the PPU (fixes onscreen
graphical corruption in some games)
- Mega Drive: added 6-button Fighting Pad emulation [hex\_usr]
- 68K: TAS sets d7 when EA mode is a direct register (fixes Asterix
graphical corruption)
- Game Boy: STAT mode is forced to zero when LCD is disabled (fixes
Pokemon Pinball)
- LR35902: complete rewrite
- icarus: high-DPI is not supported on Windows yet; remove setting for
consistency with higan window sizes
- hiro: added full support for high-DPI displays on macOS [ncbncb]
- ARM7TDMI: complete rewrite
- Super Famicom: disabled channels during HDMA initialization appear
to set DoTransfer flag
- V30MZ: code cleanup
- Mega Drive: added optional TMSS emulation; disabled by default
[hex\_usr]
- ARM7TDMI: pipeline decode stage caches CPSR.T [MerryMage]
- ARM7TDMI: fixed timing of THUMB stack multiple instruction
[Cydrak]
- higan: detect when ruby drivers crash; disable drivers on next
startup to prevent crash loop
- Mega Drive: added automatic region detection (favors NTSC-J >
NTSC-U > PAL) [hex\_usr]
- Mega Drive: support 8-bit SRAM
- ARM7TDMI: PC should be incremented by 2 when setting CPSR.T via MSR
instruction [MerryMage]
- ruby: add Windows ASIO driver support (does not work on some systems
due to buggy vendor drivers)
- higan: default to safe drivers on a new install; due to instability
with some optimal drivers
2017-08-12 12:36:37 +00:00
|
|
|
synchronize(ppu);
|
Update to v104 release.
byuu says:
Changelog:
- emulator/interface: removed unused Region struct
- gba/cpu: optimized CPU::step() as much as I could for a slight
speedup¹
- gba/cpu: synchronize the APU better during FIFO updates
- higan/md, icarus: add automatic region detection; make it the
default option [hex\_usr]
- picks NTSC-J if there's more than one match ... eventually, this
will be a setting
- higan/md, icarus: support all three combinations of SRAM (8-bit low,
8-bit high, 16-bit)
- processor/arm7tdmi: fix bug when changing to THUMB mode via MSR
[MerryMage]
- tomoko: redesigned crash detector to only occur once for all three
ruby drivers
- this will reduce disk thrashing since the configuration file
only needs to be written out one extra time
- technically, it's twice ... but we should've always been writing
one out on first run in case it crashes then
- tomoko: defaulted back to the safest ruby drivers, given the optimal
drivers have some stability concerns
¹: minor errata: spotted a typo saying `synchronize(cpu)` when the CPU
is stopped, instead of `synchronize(ppu)`. This will be fixed in the v104
official 7zip archives.
I'm kind of rushing here but, it's really good timing for me to push out
a new official release. The blocking issues are resolved or close to it,
and we need lots of testing of the new major changes.
I'm going to consider this a semi-stable testing release and leave links
to v103 just in case.
2017-08-12 10:53:13 +00:00
|
|
|
synchronize(apu);
|
|
|
|
}
|
Update to v103r07 release.
byuu says:
Changelog:
- gba/cpu: massive code cleanup effort
- gba/cpu: DMA can run in between active instructions¹
- gba/cpu: added two-cycle startup delay between DMA activation and
DMA transfers²
- processor/spc700: BBC, BBC, CBNE cycle 4 is an idle cycle
- processor/spc700: ADDW, SUBW, MOVW (read) cycle 4 is an idle cycle
¹: unfortunately, this causes yet another performance penalty for the
poor GBA core =( Also, I think I may have missed disabling DMAs while
the CPU is stopped. I'll fix that in the next WIP.
²: I put the waiting counter decrement at the wrong place, so this
doesn't actually work. Needs to be more like
this:
auto CPU::step(uint clocks) -> void {
for(auto _ : range(clocks)) {
for(auto& timer : this->timer) timer.run();
for(auto& dma : this->dma) if(dma.active && dma.waiting) dma.waiting--;
context.clock++;
}
...
auto CPU::DMA::run() -> bool {
if(cpu.stopped() || !active || waiting) return false;
transfer();
if(irq) cpu.irq.flag |= CPU::Interrupt::DMA0 << id;
if(drq && id == 3) cpu.irq.flag |= CPU::Interrupt::Cartridge;
return true;
}
Of course, the real fix will be restructuring how DMA works, so that
it's always running in parallel with the CPU instead of this weird
design where it tries to run all channels in some kind of loop until no
channels are active anymore whenever one channel is activated.
Not really sure how to design that yet, however.
2017-07-05 05:29:27 +00:00
|
|
|
context.stopped = false;
|
Update to v087r26 release.
byuu says:
Changelog:
- fixed FIFO[1] reset behavior (fixes audio in Sword of Mana)
- added FlashROM emulation (both sizes)
- GBA parses RAM settings from manifest.xml now
- save RAM is written to disk now
- added save state support (it's currently broken, though)
- fixed ROM/RAM access timings
- open bus should mostly work (we don't do the PC+12 stuff yet)
- emulated the undocumented memory control register (mirror IWRAM,
disable I+EWRAM, EWRAM wait state count)
- emulated keypad interrupts
- emulated STOP (freezes video, audio, DMA and timers; only breaks on
keypad IRQs)
- probably a lot more, it was a long night ...
Show stoppers, missing things, broken things, etc:
- ST018 is still completely broken
- GBC audio sequencer apparently needs work
- GBA audio FIFO buffer seems too quiet
- PHI / ROM prefetch needs to be emulated (no idea on how to do this,
especially PHI)
- SOUNDBIAS 64/128/256khz modes should output at that resolution
(really, we need to simulate PWM properly, no idea on how to do this)
- object mosaic top-left coordinates are wrong (minor, fixing will
actually make the effect look worse)
- need to emulate PPU greenswap and color palette distortion (no idea on
how do this)
- need GBA save type database (I would also LIKE to blacklist
/ patch-out trainers, but that's a discussion for another day.)
- some ARM ops advance the prefetch buffer, so you can read PC+12 in
some cases
2012-04-16 12:19:39 +00:00
|
|
|
}
|
2012-03-31 08:14:31 +00:00
|
|
|
|
Update to v103r07 release.
byuu says:
Changelog:
- gba/cpu: massive code cleanup effort
- gba/cpu: DMA can run in between active instructions¹
- gba/cpu: added two-cycle startup delay between DMA activation and
DMA transfers²
- processor/spc700: BBC, BBC, CBNE cycle 4 is an idle cycle
- processor/spc700: ADDW, SUBW, MOVW (read) cycle 4 is an idle cycle
¹: unfortunately, this causes yet another performance penalty for the
poor GBA core =( Also, I think I may have missed disabling DMAs while
the CPU is stopped. I'll fix that in the next WIP.
²: I put the waiting counter decrement at the wrong place, so this
doesn't actually work. Needs to be more like
this:
auto CPU::step(uint clocks) -> void {
for(auto _ : range(clocks)) {
for(auto& timer : this->timer) timer.run();
for(auto& dma : this->dma) if(dma.active && dma.waiting) dma.waiting--;
context.clock++;
}
...
auto CPU::DMA::run() -> bool {
if(cpu.stopped() || !active || waiting) return false;
transfer();
if(irq) cpu.irq.flag |= CPU::Interrupt::DMA0 << id;
if(drq && id == 3) cpu.irq.flag |= CPU::Interrupt::Cartridge;
return true;
}
Of course, the real fix will be restructuring how DMA works, so that
it's always running in parallel with the CPU instead of this weird
design where it tries to run all channels in some kind of loop until no
channels are active anymore whenever one channel is activated.
Not really sure how to design that yet, however.
2017-07-05 05:29:27 +00:00
|
|
|
if(halted()) {
|
Update to v104 release.
byuu says:
Changelog:
- emulator/interface: removed unused Region struct
- gba/cpu: optimized CPU::step() as much as I could for a slight
speedup¹
- gba/cpu: synchronize the APU better during FIFO updates
- higan/md, icarus: add automatic region detection; make it the
default option [hex\_usr]
- picks NTSC-J if there's more than one match ... eventually, this
will be a setting
- higan/md, icarus: support all three combinations of SRAM (8-bit low,
8-bit high, 16-bit)
- processor/arm7tdmi: fix bug when changing to THUMB mode via MSR
[MerryMage]
- tomoko: redesigned crash detector to only occur once for all three
ruby drivers
- this will reduce disk thrashing since the configuration file
only needs to be written out one extra time
- technically, it's twice ... but we should've always been writing
one out on first run in case it crashes then
- tomoko: defaulted back to the safest ruby drivers, given the optimal
drivers have some stability concerns
¹: minor errata: spotted a typo saying `synchronize(cpu)` when the CPU
is stopped, instead of `synchronize(ppu)`. This will be fixed in the v104
official 7zip archives.
I'm kind of rushing here but, it's really good timing for me to push out
a new official release. The blocking issues are resolved or close to it,
and we need lots of testing of the new major changes.
I'm going to consider this a semi-stable testing release and leave links
to v103 just in case.
2017-08-12 10:53:13 +00:00
|
|
|
if(!(irq.enable & irq.flag)) {
|
|
|
|
return step(16);
|
|
|
|
}
|
Update to v103r07 release.
byuu says:
Changelog:
- gba/cpu: massive code cleanup effort
- gba/cpu: DMA can run in between active instructions¹
- gba/cpu: added two-cycle startup delay between DMA activation and
DMA transfers²
- processor/spc700: BBC, BBC, CBNE cycle 4 is an idle cycle
- processor/spc700: ADDW, SUBW, MOVW (read) cycle 4 is an idle cycle
¹: unfortunately, this causes yet another performance penalty for the
poor GBA core =( Also, I think I may have missed disabling DMAs while
the CPU is stopped. I'll fix that in the next WIP.
²: I put the waiting counter decrement at the wrong place, so this
doesn't actually work. Needs to be more like
this:
auto CPU::step(uint clocks) -> void {
for(auto _ : range(clocks)) {
for(auto& timer : this->timer) timer.run();
for(auto& dma : this->dma) if(dma.active && dma.waiting) dma.waiting--;
context.clock++;
}
...
auto CPU::DMA::run() -> bool {
if(cpu.stopped() || !active || waiting) return false;
transfer();
if(irq) cpu.irq.flag |= CPU::Interrupt::DMA0 << id;
if(drq && id == 3) cpu.irq.flag |= CPU::Interrupt::Cartridge;
return true;
}
Of course, the real fix will be restructuring how DMA works, so that
it's always running in parallel with the CPU instead of this weird
design where it tries to run all channels in some kind of loop until no
channels are active anymore whenever one channel is activated.
Not really sure how to design that yet, however.
2017-07-05 05:29:27 +00:00
|
|
|
context.halted = false;
|
2012-03-19 11:19:53 +00:00
|
|
|
}
|
Update to v087r26 release.
byuu says:
Changelog:
- fixed FIFO[1] reset behavior (fixes audio in Sword of Mana)
- added FlashROM emulation (both sizes)
- GBA parses RAM settings from manifest.xml now
- save RAM is written to disk now
- added save state support (it's currently broken, though)
- fixed ROM/RAM access timings
- open bus should mostly work (we don't do the PC+12 stuff yet)
- emulated the undocumented memory control register (mirror IWRAM,
disable I+EWRAM, EWRAM wait state count)
- emulated keypad interrupts
- emulated STOP (freezes video, audio, DMA and timers; only breaks on
keypad IRQs)
- probably a lot more, it was a long night ...
Show stoppers, missing things, broken things, etc:
- ST018 is still completely broken
- GBC audio sequencer apparently needs work
- GBA audio FIFO buffer seems too quiet
- PHI / ROM prefetch needs to be emulated (no idea on how to do this,
especially PHI)
- SOUNDBIAS 64/128/256khz modes should output at that resolution
(really, we need to simulate PWM properly, no idea on how to do this)
- object mosaic top-left coordinates are wrong (minor, fixing will
actually make the effect look worse)
- need to emulate PPU greenswap and color palette distortion (no idea on
how do this)
- need GBA save type database (I would also LIKE to blacklist
/ patch-out trainers, but that's a discussion for another day.)
- some ARM ops advance the prefetch buffer, so you can read PC+12 in
some cases
2012-04-16 12:19:39 +00:00
|
|
|
|
2017-08-09 11:11:59 +00:00
|
|
|
instruction();
|
2012-03-19 11:19:53 +00:00
|
|
|
}
|
|
|
|
|
2015-11-16 08:38:05 +00:00
|
|
|
auto CPU::step(uint clocks) -> void {
|
Update to v104 release.
byuu says:
Changelog:
- emulator/interface: removed unused Region struct
- gba/cpu: optimized CPU::step() as much as I could for a slight
speedup¹
- gba/cpu: synchronize the APU better during FIFO updates
- higan/md, icarus: add automatic region detection; make it the
default option [hex\_usr]
- picks NTSC-J if there's more than one match ... eventually, this
will be a setting
- higan/md, icarus: support all three combinations of SRAM (8-bit low,
8-bit high, 16-bit)
- processor/arm7tdmi: fix bug when changing to THUMB mode via MSR
[MerryMage]
- tomoko: redesigned crash detector to only occur once for all three
ruby drivers
- this will reduce disk thrashing since the configuration file
only needs to be written out one extra time
- technically, it's twice ... but we should've always been writing
one out on first run in case it crashes then
- tomoko: defaulted back to the safest ruby drivers, given the optimal
drivers have some stability concerns
¹: minor errata: spotted a typo saying `synchronize(cpu)` when the CPU
is stopped, instead of `synchronize(ppu)`. This will be fixed in the v104
official 7zip archives.
I'm kind of rushing here but, it's really good timing for me to push out
a new official release. The blocking issues are resolved or close to it,
and we need lots of testing of the new major changes.
I'm going to consider this a semi-stable testing release and leave links
to v103 just in case.
2017-08-12 10:53:13 +00:00
|
|
|
dma[0].waiting = max(0, dma[0].waiting - (int)clocks);
|
|
|
|
dma[1].waiting = max(0, dma[1].waiting - (int)clocks);
|
|
|
|
dma[2].waiting = max(0, dma[2].waiting - (int)clocks);
|
|
|
|
dma[3].waiting = max(0, dma[3].waiting - (int)clocks);
|
Update to v103r08 release.
byuu says:
Changelog:
- emulator: improved aspect correction accuracy by using
floating-point calculations
- emulator: added videoCrop() function, extended videoSize() to take
cropping parameters¹
- tomoko: the overscan masking function will now actually resize the
viewport²
- gba/cpu: fixed two-cycle delay on triggering DMAs; not running DMAs
when the CPU is stopped
- md/vdp: center video when overscan is disabled
- pce/vce: resize video output from 1140x240 to 1120x240
- tomoko: resize window scaling from 326x240 to 320x240
- tomoko: changed save slot naming and status bar messages to indicate
quick states vs managed states
- tomoko: added increment/decrement quick state hotkeys
- tomoko: save/load quick state hotkeys now save to slots 1-5 instead
of always to 0
- tomoko: increased overscan range from 0-16 to 0-24 (in case you want
to mask the Master System to 240x192)
¹: the idea here was to decouple raw pixels from overscan masking.
Overscan was actually horrifically broken before. The Famicom outputs at
256x240, the Super Famicom at 512x480, and the Mega Drive at 1280x480.
Before, a horizontal overscan mask of 8 would not reduce the Super
Famicom or Mega Drive by nearly as much as the Famicom. WIth the new
videoCrop() function, the internals of pixel size distortions can be
handled by each individual core.
²: furthermore, by taking optional cropping information in
videoSize(), games can scale even larger into the viewport window. So
for example, before the Super Famicom could only scale to 1536x1440. But
by cropping the vertical resolution by 6 (228p effectively, still more
than NTSC can even show), I can now scale to 1792x1596. And wiht aspect
correction, that becomes a perfect 8:7 ratio of 2048x1596, giving me
perfectly crisp pixels without linear interpolation being required.
Errata: for some reason, when I save a new managed state with the SFC
core, the default description is being set to a string of what looks to
be hex numbers. I found the cause ... I'll fix this in the next release.
Note: I'd also like to hide the "find codes..." button if cheats.bml
isn't present, as well as update the SMP TEST register comment from
smp/timing.cpp
2017-07-05 05:44:15 +00:00
|
|
|
|
Update to v103r07 release.
byuu says:
Changelog:
- gba/cpu: massive code cleanup effort
- gba/cpu: DMA can run in between active instructions¹
- gba/cpu: added two-cycle startup delay between DMA activation and
DMA transfers²
- processor/spc700: BBC, BBC, CBNE cycle 4 is an idle cycle
- processor/spc700: ADDW, SUBW, MOVW (read) cycle 4 is an idle cycle
¹: unfortunately, this causes yet another performance penalty for the
poor GBA core =( Also, I think I may have missed disabling DMAs while
the CPU is stopped. I'll fix that in the next WIP.
²: I put the waiting counter decrement at the wrong place, so this
doesn't actually work. Needs to be more like
this:
auto CPU::step(uint clocks) -> void {
for(auto _ : range(clocks)) {
for(auto& timer : this->timer) timer.run();
for(auto& dma : this->dma) if(dma.active && dma.waiting) dma.waiting--;
context.clock++;
}
...
auto CPU::DMA::run() -> bool {
if(cpu.stopped() || !active || waiting) return false;
transfer();
if(irq) cpu.irq.flag |= CPU::Interrupt::DMA0 << id;
if(drq && id == 3) cpu.irq.flag |= CPU::Interrupt::Cartridge;
return true;
}
Of course, the real fix will be restructuring how DMA works, so that
it's always running in parallel with the CPU instead of this weird
design where it tries to run all channels in some kind of loop until no
channels are active anymore whenever one channel is activated.
Not really sure how to design that yet, however.
2017-07-05 05:29:27 +00:00
|
|
|
if(!context.dmaActive) {
|
|
|
|
context.dmaActive = true;
|
Update to v104 release.
byuu says:
Changelog:
- emulator/interface: removed unused Region struct
- gba/cpu: optimized CPU::step() as much as I could for a slight
speedup¹
- gba/cpu: synchronize the APU better during FIFO updates
- higan/md, icarus: add automatic region detection; make it the
default option [hex\_usr]
- picks NTSC-J if there's more than one match ... eventually, this
will be a setting
- higan/md, icarus: support all three combinations of SRAM (8-bit low,
8-bit high, 16-bit)
- processor/arm7tdmi: fix bug when changing to THUMB mode via MSR
[MerryMage]
- tomoko: redesigned crash detector to only occur once for all three
ruby drivers
- this will reduce disk thrashing since the configuration file
only needs to be written out one extra time
- technically, it's twice ... but we should've always been writing
one out on first run in case it crashes then
- tomoko: defaulted back to the safest ruby drivers, given the optimal
drivers have some stability concerns
¹: minor errata: spotted a typo saying `synchronize(cpu)` when the CPU
is stopped, instead of `synchronize(ppu)`. This will be fixed in the v104
official 7zip archives.
I'm kind of rushing here but, it's really good timing for me to push out
a new official release. The blocking issues are resolved or close to it,
and we need lots of testing of the new major changes.
I'm going to consider this a semi-stable testing release and leave links
to v103 just in case.
2017-08-12 10:53:13 +00:00
|
|
|
while(dma[0].run() | dma[1].run() | dma[2].run() | dma[3].run());
|
Update to v103r07 release.
byuu says:
Changelog:
- gba/cpu: massive code cleanup effort
- gba/cpu: DMA can run in between active instructions¹
- gba/cpu: added two-cycle startup delay between DMA activation and
DMA transfers²
- processor/spc700: BBC, BBC, CBNE cycle 4 is an idle cycle
- processor/spc700: ADDW, SUBW, MOVW (read) cycle 4 is an idle cycle
¹: unfortunately, this causes yet another performance penalty for the
poor GBA core =( Also, I think I may have missed disabling DMAs while
the CPU is stopped. I'll fix that in the next WIP.
²: I put the waiting counter decrement at the wrong place, so this
doesn't actually work. Needs to be more like
this:
auto CPU::step(uint clocks) -> void {
for(auto _ : range(clocks)) {
for(auto& timer : this->timer) timer.run();
for(auto& dma : this->dma) if(dma.active && dma.waiting) dma.waiting--;
context.clock++;
}
...
auto CPU::DMA::run() -> bool {
if(cpu.stopped() || !active || waiting) return false;
transfer();
if(irq) cpu.irq.flag |= CPU::Interrupt::DMA0 << id;
if(drq && id == 3) cpu.irq.flag |= CPU::Interrupt::Cartridge;
return true;
}
Of course, the real fix will be restructuring how DMA works, so that
it's always running in parallel with the CPU instead of this weird
design where it tries to run all channels in some kind of loop until no
channels are active anymore whenever one channel is activated.
Not really sure how to design that yet, however.
2017-07-05 05:29:27 +00:00
|
|
|
context.dmaActive = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
for(auto _ : range(clocks)) {
|
Update to v104 release.
byuu says:
Changelog:
- emulator/interface: removed unused Region struct
- gba/cpu: optimized CPU::step() as much as I could for a slight
speedup¹
- gba/cpu: synchronize the APU better during FIFO updates
- higan/md, icarus: add automatic region detection; make it the
default option [hex\_usr]
- picks NTSC-J if there's more than one match ... eventually, this
will be a setting
- higan/md, icarus: support all three combinations of SRAM (8-bit low,
8-bit high, 16-bit)
- processor/arm7tdmi: fix bug when changing to THUMB mode via MSR
[MerryMage]
- tomoko: redesigned crash detector to only occur once for all three
ruby drivers
- this will reduce disk thrashing since the configuration file
only needs to be written out one extra time
- technically, it's twice ... but we should've always been writing
one out on first run in case it crashes then
- tomoko: defaulted back to the safest ruby drivers, given the optimal
drivers have some stability concerns
¹: minor errata: spotted a typo saying `synchronize(cpu)` when the CPU
is stopped, instead of `synchronize(ppu)`. This will be fixed in the v104
official 7zip archives.
I'm kind of rushing here but, it's really good timing for me to push out
a new official release. The blocking issues are resolved or close to it,
and we need lots of testing of the new major changes.
I'm going to consider this a semi-stable testing release and leave links
to v103 just in case.
2017-08-12 10:53:13 +00:00
|
|
|
timer[0].run();
|
|
|
|
timer[1].run();
|
|
|
|
timer[2].run();
|
|
|
|
timer[3].run();
|
Update to v103r07 release.
byuu says:
Changelog:
- gba/cpu: massive code cleanup effort
- gba/cpu: DMA can run in between active instructions¹
- gba/cpu: added two-cycle startup delay between DMA activation and
DMA transfers²
- processor/spc700: BBC, BBC, CBNE cycle 4 is an idle cycle
- processor/spc700: ADDW, SUBW, MOVW (read) cycle 4 is an idle cycle
¹: unfortunately, this causes yet another performance penalty for the
poor GBA core =( Also, I think I may have missed disabling DMAs while
the CPU is stopped. I'll fix that in the next WIP.
²: I put the waiting counter decrement at the wrong place, so this
doesn't actually work. Needs to be more like
this:
auto CPU::step(uint clocks) -> void {
for(auto _ : range(clocks)) {
for(auto& timer : this->timer) timer.run();
for(auto& dma : this->dma) if(dma.active && dma.waiting) dma.waiting--;
context.clock++;
}
...
auto CPU::DMA::run() -> bool {
if(cpu.stopped() || !active || waiting) return false;
transfer();
if(irq) cpu.irq.flag |= CPU::Interrupt::DMA0 << id;
if(drq && id == 3) cpu.irq.flag |= CPU::Interrupt::Cartridge;
return true;
}
Of course, the real fix will be restructuring how DMA works, so that
it's always running in parallel with the CPU instead of this weird
design where it tries to run all channels in some kind of loop until no
channels are active anymore whenever one channel is activated.
Not really sure how to design that yet, however.
2017-07-05 05:29:27 +00:00
|
|
|
context.clock++;
|
|
|
|
}
|
2012-04-07 08:17:49 +00:00
|
|
|
|
Update to v100r14 release.
byuu says:
(Windows: compile with -fpermissive to silence an annoying error. I'll
fix it in the next WIP.)
I completely replaced the time management system in higan and overhauled
the scheduler.
Before, processor threads would have "int64 clock"; and there would
be a 1:1 relationship between two threads. When thread A ran for X
cycles, it'd subtract X * B.Frequency from clock; and when thread B ran
for Y cycles, it'd add Y * A.Frequency from clock. This worked well
and allowed perfect precision; but it doesn't work when you have more
complicated relationships: eg the 68K can sync to the Z80 and PSG; the
Z80 to the 68K and PSG; so the PSG needs two counters.
The new system instead uses a "uint64 clock" variable that represents
time in attoseconds. Every time the scheduler exits, it subtracts
the smallest clock count from all threads, to prevent an overflow
scenario. The only real downside is that rounding errors mean that
roughly every 20 minutes, we have a rounding error of one clock cycle
(one 20,000,000th of a second.) However, this only applies to systems
with multiple oscillators, like the SNES. And when you're in that
situation ... there's no such thing as a perfect oscillator anyway. A
real SNES will be thousands of times less out of spec than 1hz per 20
minutes.
The advantages are pretty immense. First, we obviously can now support
more complex relationships between threads. Second, we can build a
much more abstracted scheduler. All of libco is now abstracted away
completely, which may permit a state-machine / coroutine version of
Thread in the future. We've basically gone from this:
auto SMP::step(uint clocks) -> void {
clock += clocks * (uint64)cpu.frequency;
dsp.clock -= clocks;
if(dsp.clock < 0 && !scheduler.synchronizing()) co_switch(dsp.thread);
if(clock >= 0 && !scheduler.synchronizing()) co_switch(cpu.thread);
}
To this:
auto SMP::step(uint clocks) -> void {
Thread::step(clocks);
synchronize(dsp);
synchronize(cpu);
}
As you can see, we don't have to do multiple clock adjustments anymore.
This is a huge win for the SNES CPU that had to update the SMP, DSP, all
peripherals and all coprocessors. Likewise, we don't have to synchronize
all coprocessors when one runs, now we can just synchronize the active
one to the CPU.
Third, when changing the frequencies of threads (think SGB speed setting
modes, GBC double-speed mode, etc), it no longer causes the "int64
clock" value to be erroneous.
Fourth, this results in a fairly decent speedup, mostly across the
board. Aside from the GBA being mostly a wash (for unknown reasons),
it's about an 8% - 12% speedup in every other emulation core.
Now, all of this said ... this was an unbelievably massive change, so
... you know what that means >_> If anyone can help test all types of
SNES coprocessors, and some other system games, it'd be appreciated.
----
Lastly, we have a bitchin' new about screen. It unfortunately adds
~200KiB onto the binary size, because the PNG->C++ header file
transformation doesn't compress very well, and I want to keep the
original resource files in with the higan archive. I might try some
things to work around this file size increase in the future, but for now
... yeah, slightly larger archive sizes, sorry.
The logo's a bit busted on Windows (the Label control's background
transparency and alignment settings aren't working), but works well on
GTK. I'll have to fix Windows before the next official release. For now,
look on my Twitter feed if you want to see what it's supposed to look
like.
----
EDIT: forgot about ICD2::Enter. It's doing some weird inverse
run-to-save thing that I need to implement support for somehow. So, save
states on the SGB core probably won't work with this WIP.
2016-07-30 03:56:12 +00:00
|
|
|
Thread::step(clocks);
|
|
|
|
synchronize(ppu);
|
|
|
|
synchronize(apu);
|
2012-03-23 10:43:39 +00:00
|
|
|
}
|
|
|
|
|
2015-06-25 09:52:32 +00:00
|
|
|
auto CPU::power() -> void {
|
2017-08-09 11:11:59 +00:00
|
|
|
ARM7TDMI::power();
|
Update to v103r07 release.
byuu says:
Changelog:
- gba/cpu: massive code cleanup effort
- gba/cpu: DMA can run in between active instructions¹
- gba/cpu: added two-cycle startup delay between DMA activation and
DMA transfers²
- processor/spc700: BBC, BBC, CBNE cycle 4 is an idle cycle
- processor/spc700: ADDW, SUBW, MOVW (read) cycle 4 is an idle cycle
¹: unfortunately, this causes yet another performance penalty for the
poor GBA core =( Also, I think I may have missed disabling DMAs while
the CPU is stopped. I'll fix that in the next WIP.
²: I put the waiting counter decrement at the wrong place, so this
doesn't actually work. Needs to be more like
this:
auto CPU::step(uint clocks) -> void {
for(auto _ : range(clocks)) {
for(auto& timer : this->timer) timer.run();
for(auto& dma : this->dma) if(dma.active && dma.waiting) dma.waiting--;
context.clock++;
}
...
auto CPU::DMA::run() -> bool {
if(cpu.stopped() || !active || waiting) return false;
transfer();
if(irq) cpu.irq.flag |= CPU::Interrupt::DMA0 << id;
if(drq && id == 3) cpu.irq.flag |= CPU::Interrupt::Cartridge;
return true;
}
Of course, the real fix will be restructuring how DMA works, so that
it's always running in parallel with the CPU instead of this weird
design where it tries to run all channels in some kind of loop until no
channels are active anymore whenever one channel is activated.
Not really sure how to design that yet, however.
2017-07-05 05:29:27 +00:00
|
|
|
create(CPU::Enter, system.frequency());
|
|
|
|
|
|
|
|
for(auto& byte : iwram) byte = 0x00;
|
|
|
|
for(auto& byte : ewram) byte = 0x00;
|
|
|
|
|
|
|
|
for(auto n : range(4)) dma[n] = {n};
|
|
|
|
for(auto n : range(4)) timer[n] = {n};
|
|
|
|
serial = {};
|
|
|
|
keypad = {};
|
|
|
|
joybus = {};
|
|
|
|
irq = {};
|
|
|
|
wait = {};
|
|
|
|
memory = {};
|
2017-06-08 14:05:48 +00:00
|
|
|
prefetch = {};
|
Update to v103r07 release.
byuu says:
Changelog:
- gba/cpu: massive code cleanup effort
- gba/cpu: DMA can run in between active instructions¹
- gba/cpu: added two-cycle startup delay between DMA activation and
DMA transfers²
- processor/spc700: BBC, BBC, CBNE cycle 4 is an idle cycle
- processor/spc700: ADDW, SUBW, MOVW (read) cycle 4 is an idle cycle
¹: unfortunately, this causes yet another performance penalty for the
poor GBA core =( Also, I think I may have missed disabling DMAs while
the CPU is stopped. I'll fix that in the next WIP.
²: I put the waiting counter decrement at the wrong place, so this
doesn't actually work. Needs to be more like
this:
auto CPU::step(uint clocks) -> void {
for(auto _ : range(clocks)) {
for(auto& timer : this->timer) timer.run();
for(auto& dma : this->dma) if(dma.active && dma.waiting) dma.waiting--;
context.clock++;
}
...
auto CPU::DMA::run() -> bool {
if(cpu.stopped() || !active || waiting) return false;
transfer();
if(irq) cpu.irq.flag |= CPU::Interrupt::DMA0 << id;
if(drq && id == 3) cpu.irq.flag |= CPU::Interrupt::Cartridge;
return true;
}
Of course, the real fix will be restructuring how DMA works, so that
it's always running in parallel with the CPU instead of this weird
design where it tries to run all channels in some kind of loop until no
channels are active anymore whenever one channel is activated.
Not really sure how to design that yet, however.
2017-07-05 05:29:27 +00:00
|
|
|
context = {};
|
|
|
|
|
|
|
|
dma[0].source.resize(27); dma[0].latch.source.resize(27);
|
|
|
|
dma[0].target.resize(27); dma[0].latch.target.resize(27);
|
|
|
|
dma[0].length.resize(14); dma[0].latch.length.resize(14);
|
|
|
|
|
|
|
|
dma[1].source.resize(28); dma[1].latch.source.resize(28);
|
|
|
|
dma[1].target.resize(27); dma[1].latch.target.resize(27);
|
|
|
|
dma[1].length.resize(14); dma[1].latch.length.resize(14);
|
2012-04-01 01:41:15 +00:00
|
|
|
|
Update to v103r07 release.
byuu says:
Changelog:
- gba/cpu: massive code cleanup effort
- gba/cpu: DMA can run in between active instructions¹
- gba/cpu: added two-cycle startup delay between DMA activation and
DMA transfers²
- processor/spc700: BBC, BBC, CBNE cycle 4 is an idle cycle
- processor/spc700: ADDW, SUBW, MOVW (read) cycle 4 is an idle cycle
¹: unfortunately, this causes yet another performance penalty for the
poor GBA core =( Also, I think I may have missed disabling DMAs while
the CPU is stopped. I'll fix that in the next WIP.
²: I put the waiting counter decrement at the wrong place, so this
doesn't actually work. Needs to be more like
this:
auto CPU::step(uint clocks) -> void {
for(auto _ : range(clocks)) {
for(auto& timer : this->timer) timer.run();
for(auto& dma : this->dma) if(dma.active && dma.waiting) dma.waiting--;
context.clock++;
}
...
auto CPU::DMA::run() -> bool {
if(cpu.stopped() || !active || waiting) return false;
transfer();
if(irq) cpu.irq.flag |= CPU::Interrupt::DMA0 << id;
if(drq && id == 3) cpu.irq.flag |= CPU::Interrupt::Cartridge;
return true;
}
Of course, the real fix will be restructuring how DMA works, so that
it's always running in parallel with the CPU instead of this weird
design where it tries to run all channels in some kind of loop until no
channels are active anymore whenever one channel is activated.
Not really sure how to design that yet, however.
2017-07-05 05:29:27 +00:00
|
|
|
dma[2].source.resize(28); dma[2].latch.source.resize(28);
|
|
|
|
dma[2].target.resize(27); dma[2].latch.target.resize(27);
|
|
|
|
dma[2].length.resize(14); dma[2].latch.length.resize(14);
|
2012-04-03 23:50:40 +00:00
|
|
|
|
Update to v103r07 release.
byuu says:
Changelog:
- gba/cpu: massive code cleanup effort
- gba/cpu: DMA can run in between active instructions¹
- gba/cpu: added two-cycle startup delay between DMA activation and
DMA transfers²
- processor/spc700: BBC, BBC, CBNE cycle 4 is an idle cycle
- processor/spc700: ADDW, SUBW, MOVW (read) cycle 4 is an idle cycle
¹: unfortunately, this causes yet another performance penalty for the
poor GBA core =( Also, I think I may have missed disabling DMAs while
the CPU is stopped. I'll fix that in the next WIP.
²: I put the waiting counter decrement at the wrong place, so this
doesn't actually work. Needs to be more like
this:
auto CPU::step(uint clocks) -> void {
for(auto _ : range(clocks)) {
for(auto& timer : this->timer) timer.run();
for(auto& dma : this->dma) if(dma.active && dma.waiting) dma.waiting--;
context.clock++;
}
...
auto CPU::DMA::run() -> bool {
if(cpu.stopped() || !active || waiting) return false;
transfer();
if(irq) cpu.irq.flag |= CPU::Interrupt::DMA0 << id;
if(drq && id == 3) cpu.irq.flag |= CPU::Interrupt::Cartridge;
return true;
}
Of course, the real fix will be restructuring how DMA works, so that
it's always running in parallel with the CPU instead of this weird
design where it tries to run all channels in some kind of loop until no
channels are active anymore whenever one channel is activated.
Not really sure how to design that yet, however.
2017-07-05 05:29:27 +00:00
|
|
|
dma[3].source.resize(28); dma[3].latch.source.resize(28);
|
|
|
|
dma[3].target.resize(28); dma[3].latch.target.resize(28);
|
|
|
|
dma[3].length.resize(16); dma[3].latch.length.resize(16);
|
2015-07-01 10:58:42 +00:00
|
|
|
|
Update to v099r13 release.
byuu says:
Changelog:
- GB core code cleanup completed
- GBA core code cleanup completed
- some more cleanup on missed processor/arm functions/variables
- fixed FC loading icarus bug
- "Load ROM File" icarus functionality restored
- minor code unification efforts all around (not perfect yet)
- MMIO->IO
- mmio.cpp->io.cpp
- read,write->readIO,writeIO
It's been a very long work in progress ... starting all the way back with
v094r09, but the major part of the higan code cleanup is now completed! Of
course, it's very important to note that this is only for the basic style:
- under_score functions and variables are now camelCase
- return-type function-name() are now auto function-name() -> return-type
- Natural<T>/Integer<T> replace (u)intT_n types where possible
- signed/unsigned are now int/uint
- most of the x==true,x==false tests changed to x,!x
A lot of spot improvements to consistency, simplicity and quality have
gone in along the way, of course. But we'll probably never fully finishing
beautifying every last line of code in the entire codebase. Still,
this is a really great start. Going forward, WIP diffs should start
being smaller and of higher quality once again.
I know the joke is, "until my coding style changes again", but ... this
was way too stressful, way too time consuming, and way too risky. I'm
too old and tired now for extreme upheavel like this again. The only
major change I'm slowly mulling over would be renaming the using
Natural<T>/Integer<T> = (u)intT; shorthand to something that isn't as
easily confused with the (u)int_t types ... but we'll see. I'll definitely
continue to change small things all the time, but for the larger picture,
I need to just accept the style I have and live with it.
2016-06-29 11:10:28 +00:00
|
|
|
for(uint n = 0x0b0; n <= 0x0df; n++) bus.io[n] = this; //DMA
|
|
|
|
for(uint n = 0x100; n <= 0x10f; n++) bus.io[n] = this; //Timers
|
|
|
|
for(uint n = 0x120; n <= 0x12b; n++) bus.io[n] = this; //Serial
|
|
|
|
for(uint n = 0x130; n <= 0x133; n++) bus.io[n] = this; //Keypad
|
|
|
|
for(uint n = 0x134; n <= 0x159; n++) bus.io[n] = this; //Serial
|
|
|
|
for(uint n = 0x200; n <= 0x209; n++) bus.io[n] = this; //System
|
|
|
|
for(uint n = 0x300; n <= 0x301; n++) bus.io[n] = this; //System
|
Update to v103r07 release.
byuu says:
Changelog:
- gba/cpu: massive code cleanup effort
- gba/cpu: DMA can run in between active instructions¹
- gba/cpu: added two-cycle startup delay between DMA activation and
DMA transfers²
- processor/spc700: BBC, BBC, CBNE cycle 4 is an idle cycle
- processor/spc700: ADDW, SUBW, MOVW (read) cycle 4 is an idle cycle
¹: unfortunately, this causes yet another performance penalty for the
poor GBA core =( Also, I think I may have missed disabling DMAs while
the CPU is stopped. I'll fix that in the next WIP.
²: I put the waiting counter decrement at the wrong place, so this
doesn't actually work. Needs to be more like
this:
auto CPU::step(uint clocks) -> void {
for(auto _ : range(clocks)) {
for(auto& timer : this->timer) timer.run();
for(auto& dma : this->dma) if(dma.active && dma.waiting) dma.waiting--;
context.clock++;
}
...
auto CPU::DMA::run() -> bool {
if(cpu.stopped() || !active || waiting) return false;
transfer();
if(irq) cpu.irq.flag |= CPU::Interrupt::DMA0 << id;
if(drq && id == 3) cpu.irq.flag |= CPU::Interrupt::Cartridge;
return true;
}
Of course, the real fix will be restructuring how DMA works, so that
it's always running in parallel with the CPU instead of this weird
design where it tries to run all channels in some kind of loop until no
channels are active anymore whenever one channel is activated.
Not really sure how to design that yet, however.
2017-07-05 05:29:27 +00:00
|
|
|
//0x080-0x083 mirrored via gba/memory/memory.cpp //System
|
2012-03-19 11:19:53 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
}
|