In the release thread, byuu says:
The first official release of higan has been posted. higan is the
new name for bsnes, and it continues with the latter's version
numbering.
Note that as of now, bsnes still exists. It's a module distributed
inside of higan. bsnes is now specific to my SNES emulator.
Due to last minute changes to the emulator interface, and missing
support in ananke, I wasn't able to include Cydrak's Nintendo DS
emulator dasShiny in this build, but I hope to do so in the next
release.
http://code.google.com/p/higan/downloads/list
For both new and experienced users, please read the higan user guide
first:
http://byuu.org/higan/user-guide
In the v091 WIP thread, byuu says:
r15->r16:
- BS-X MaskROM handling (partial ... need to split bsx/flash away
from sfc/chip, restructure code - it requires tagging the base
cart markup for now, but it needs to parse the slotted cart
markup)
- phoenixflags / phoenixlink += -m32
- nall/sort stability
- if(input.poll(scancode[activeScancode]) == false) return;
- MSU1 / USART need to use interface->path(1)
- MSU1 needs to use Markup::Document, not XML::Document
- case-insensitive folder listings
- remove nall/emulation/system.hpp files (move to ananke)
- remove rom/ram id= checks with indexing
X have cores ask for manifest.bml (skipped for v092's release, too
big a change)
- rename compatibility profile to balanced (so people don't assume
it has better compatibility than accuracy)
byuu says:
Changelog:
- all media types always show base name in the title now (eg Super Game
Boy + Mega Man II)
- Game Boy loading via ananke has been fixed
- phoenix is dynamically linked on Windows now (needed for ananke)
- Linux port shows the higan program icon (once you install the program
to get the bitmap into /usr/local/share/pixmaps)
- paths.cfg defaults to "userpath()/Emulation/System Name/" when it is
created from scratch
[Later, after the v092 release, byuu posted this additional changelog:
- new compilation rules for win32
- OS::setName
- default to ~/Emulation/media.name for paths.cfg
]
byuu says:
higan changelog:
- generates title displayed in emulator window by asking the core
- core builds title solely from "information/title" ... if it's not
there, you don't get a title at all
- sub-system load menu is gone ... since there are multiple revisions of
the SGB, this never really worked well anyway
- to load an SGB, BS-X or ST cartridge, load the base cartridge first
- "File->Load Game" moved to "Load->Import Game" ... may cause a bit of
confusion to new users, but I don't like having a single-item menu,
we'll just have to explain it to new users
- browser window redone to look like ananke
- home button here goes to ~/Emulation rather than just ~ like ananke,
since this is the home of game folders
- game folder icon is now the executable icon for the Tango theme
(orange diamond), meant to represent a complete game rather than
a game file or archive
ananke changelog:
- outputs GBC games to "Game Boy Color/" instead of "Game Boy/"
- adds the file basename to "information/title"
Known issues:
- using ananke to load a GB game trips the Super Famicom SGB mode and
fails (need to make the full-path auto-detection ignore non-bootable
systems)
- need to dump and test some BS-X media before releasing
- ananke lacks BS-X Satellaview cartridge support
- v092 isn't going to let you retarget the ananke/higan game folder path
of ~/Emulation, you will have to wait for a future version if that
bothers you so greatly
[Later, after the v092 release, byuu posted this additional changelog:
- kill laevateinn
- add title()
- add bootable, remove load
- combine file, library
- combine [][][] paths
- fix SFC subtype handling XML->BML
- update file browser to use buttons
- update file browser keyboard handling
- update system XML->BML
- fix sufami turbo hashing
- remove Cartridge::manifest
]
byuu says:
This should be basically final now.
Works with all media types (nes, sfc, gb, gbc, gba, bs, st), strips
headers, can use internal or external firmware, imports saves on first
run.
Added a custom file dialog. It seems both GTK+ and Windows XP have
(un)intelligent file sorting, which puts eg "ActRaiser 2 (NA)" before
"ActRaiser (NA)". So, screw 'em.
byuu says (about higan):
- dropped release/ root node for individual games (still there in
ananke's database.)
- Memory export uses smarter names (vram.rwm -> video.ram, etc.)
- cheat database moved from XML to BML (3.1MB to 1.9MB file size.)
- cheat codes moved from XML to BML
- resource manifest moved from XML to BML
What can I say, I like consistency. But I'll leave the shaders alone
until I get around to shader folders.
byuu says (about ananke):
Works with higan v091r13. Only does SNES stuff so far.
byuu says:
This release refines HSU1 support as a bidirectional protocol, nests SFC
manifests as "release/cartridge" and "release/information" (but release/
is not guaranteed to be finalized just yet), removes the database
integration, and adds support for ananke.
ananke represents inevitability. It's a library that, when installed,
higan can use to load files from the command-line, and also from a new
File -> Load Game menu option.
I need to change the build rules a bit for it to work on Windows (need
to make phoenix a DLL, basically), but it works now on Linux.
Right now, it only takes *.sfc file names, looks them up in the included
database, converts them to game folders, and returns the game folder
path for higan to load.
The idea is to continue expanding it to support everything we can that
I don't want in the higan core:
- load *.sfc, *.smc, *.swc, *.fig files
- remove SNES copier headers
- split apart merged firmware files
- pull in external firmware files (eg dsp1b.rom - these are staying
merged, just as SPC7110 prg+dat are merged)
- load *.zip and *.7z archives
- prompt for selection on multi-file archives
- generate manifest files based on heuristics
- apply BPS patches
The "Load" menu option has been renamed to "Library", to represent games
in your library. I'm going to add some sort of suffix to indicate
unverified games, and use a different folder icon for those (eg
manifests built on heuristics rather than from the database.)
So basically, to future end users:
File -> Load Game will be how they play games.
Library -> (specific system) can be thought of as an infinitely-sized
recent games list.
purify will likely become a simple stub that invokes ananke's functions.
No reason to duplicate all that code.
[r07 and r08 were not posted to the WIP thread. -Ed.]
byuu says:
I'd appreciate it if you guys wouldn't mind testing out the database
functionality.
Save this file as database.bml (remove the date) inside
~/.config/higan/Super Famicom.sfc/ or %APPDATA%/higan/Super Famicom.sfc/
http://byuu.org/snes/database/database_2012-10-21.bml
Now load any of the 20 games in the database from the file dialog. They
need to be named *.sfc, have no copier header, and have firmware
appended (for Mario Kart only so far.)
If anyone actually does test it, please let me know how it goes for you
and what you think. Note that future versions of higan will have the
database.bml file included with the release.
byuu says:
This release adds initial database support.
The way it works is you can now load game folders as you always have, or
you can load a game file. If you load a game file, it tries to create
a game folder for you by looking up the file's sha256 in a database. If
it can't find it, sorry, the game won't play. I'm not hooking up the
oldschool "make up a manifest" code here. The easiest way to handle this
is to get me every game so I can dump it and add it to the database :D
The database entries are complete entries that can be copied directly.
So it describes the board, the information, file layout, etc. That'll be
what comes with higan releases in the future.
Internally, I'm separating the information and board descriptions, and
will use a tool to merge the two together.
Here's a current database copy, with one game in it. Still hammering out
some details, but it's mostly how it's going to look.
cartridge region=NTSC
board type=1CB5B-20
superfx revision=2
rom name=program.rom size=0x200000
ram name=save.rwm size=0x8000
map id=io address=00-3f,80-bf:3000-32ff
map id=rom address=00-3f:8000-ffff mask=0x8000
map id=rom address=40-5f:0000-ffff
map id=ram address=00-3f,80-bf:6000-7fff size=0x2000
map id=ram address=70-71:0000-ffff
information
name: Super Mario World 2 - Yoshi's Island (SNS) (1.1)
title: Super Mario World 2: Yoshi's Island
sha256: bd763c1a56365c244be92e6cffefd318780a2a19eda7d5baf1c6d5bd6c1b3e06
board: SHVC-1CB5B-20
rom: 0x200000
ram: 0x8000
layout
file name=program.rom size=0x200000
[No prior releases were posted to the WIP thread. -Ed.]
byuu says:
Super Famicom mapping system has been reworked as discussed with the
mask= changes. offset becomes base, mode is gone. Also added support for
comma-separated fields in the address fields, to reduce the number of
map lines needed.
<?xml version="1.0" encoding="UTF-8"?>
<cartridge region="NTSC">
<superfx revision="2">
<rom name="program.rom" size="0x200000"/>
<ram name="save.rwm" size="0x8000"/>
<map id="io" address="00-3f,80-bf:3000-32ff"/>
<map id="rom" address="00-3f:8000-ffff" mask="0x8000"/>
<map id="rom" address="40-5f:0000-ffff"/>
<map id="ram" address="00-3f,80-bf:6000-7fff" size="0x2000"/>
<map id="ram" address="70-71:0000-ffff"/>
</superfx>
</cartridge>
Or in BML:
cartridge region=NTSC
superfx revision=2
rom name=program.rom size=0x200000
ram name=save.rwm size=0x8000
map id=io address=00-3f,80-bf:3000-32ff
map id=rom address=00-3f:8000-ffff mask=0x8000
map id=rom address=40-5f:0000-ffff
map id=ram address=00-3f,80-bf:6000-7fff size=0x2000
map id=ram address=70-71:0000-ffff
As a result of the changes, old mappings will no longer work. The above
XML example will run Super Mario World 2: Yoshi's Island. Otherwise,
you'll have to write your own.
All that's left now is to work some sort of database mapping system in,
so I can start dumping carts en masse.
The NES changes that FitzRoy asked for are mostly in as well.
Also, part of the reason I haven't released a WIP ... but fuck it, I'm
not going to wait forever to post a new WIP.
I've added a skeleton driver to emulate Campus Challenge '92 and
Powerfest '94. There's no actual emulation, except for the stuff I can
glean from looking at the pictures of the board. It has a DSP-1 (so
SR/DR registers), four ROMs that map in and out, RAM, etc.
I've also added preliminary mapping to upload high scores to a website,
but obviously I need the ROMs first.
byuu says:
Basically just a project rename, with s/bsnes/higan and the new icon
from lowkee added in.
It won't compile on Windows because I forgot to update the resource.rc
file, and a path transform command isn't working on Windows.
It was really just meant as a starting point, so that v091 WIPs can flow
starting from .00 with the new name (it overshadows bsnes v091, so
publicly speaking this "shouldn't exist" and will probably be deleted
from Google Code when v092 is ready.)
byuu says:
A few issues crept up in the last release, this should take care of
them.
First, it seems that the 32-bit runtime on 64-bit versions of Windows
have 64-bit time functions; whereas true 32-bit Windows does not. This
was causing a DLL error when attempting to load bsnes v090.
Second, when there were more than 2,000 files in the same folder on
Windows, it was lagging the file browser. With OV2's help, I've fixed
that and it'll now load the list instantly.
Lastly, I've included the missing video shaders this time.
byuu says:
Most notably, this release adds Nintendo DS emulation. The Nintendo DS
module was written entirely by Cydrak, so please give him all of the
credit for it. I for one am extremely grateful to be allowed to use his
module in bsnes.
The Nintendo DS emulator's standalone name is dasShiny. You will need
the Nintendo DS firmware, which I cannot provide, in order to use it. It
also cannot (currently?) detect the save type used by NDS games. As
such, manifest.xml files must be created manually for this purpose. The
long-term plan is to create a database of save types for each game.
Also, you will need an analog input device for the touch screen for now
(joypad axes work well.)
There have also been a lot of changes from my end: a unified
manifest.xml format across all systems, major improvements to SPC7110
emulation, enhancements to RTC emulation, MSU1 enhancements, icons in
the file browser list, improvements to SNES coprocessor memory mapping,
cleanups and improvements in the libraries used to build bsnes, etc.
I've also included kaijuu (which allows launching game folders directly
with bsnes) and purify (which allows opening images that are compressed,
have copier headers, and have wrong extensions); both of which are fully
GUI-based.
This release only loads game folders, not files. Use purify to load ROM
files in bsnes.
Note that this will likely be the last release for a long time, and that
I will probably rename the emulator for the next release, due to how
many additional systems it now supports.
byuu says:
Changelog:
- fixed bsnes to let config files and system folders to be in the same
folder as the executable
- fixed RawInput driver to compile again without linear_vector
- fixed phoenix/Windows to compile again without linear_vector
- fixed old vs new name warnings on MinGW w64 (technically the warnings
were erroneous, but I worked around them anyway)
- added memory export hotkey (SNES driver only; mainly for FEoEZ
translation)
- restored WRAM randomization for v090 stability (we can discuss that
idea for v091+)
- fixed SuperFX / SA-1 "0x" prefix in the header generation (drop it
into the latest purify if you want)
- added nall/Makefile uname support for UnxUtils (was breaking
compilation with full UnxUtils in your path otherwise)
byuu says:
This update uses the latest manifest.xml mappings. It also adds a new
"Update Manifests" button that can be used to quickly regenerate all
manifests (sans Famicom games ... since I strip the iNES header, that
information is gone. We can't support Famicom manifest.xml updates until
we have a database.) This is different than the before wrapping of the
functionality on the convert games button. You can also trigger this on
the command-line with "purify synchronize"
g6672D, great catch. This was fixed, thank you.
[g6672D's bug was: "SA-1 and SuperFX are missing the "0x" for
program.rom/save.rwm size." - Ed.]
byuu says:
This implements the spec from the XML part 3 thread:
http://board.byuu.org/viewtopic.php?f=16&t=2998
It's also propagated the changes to nall and purify, so you can test
this one.
This is basically it, after years of effort I feel I finally have
a fully consistent and logical XML board format.
The only things left to change will be: modifications if emulation turns
out to be incorrect (eg we missed some MMIO mirrors, or mirrored too
much), and new additions.
And of course, I'm giving it a bit of time for good arguments against
the format.
Other than that, this release removes linear_vector and pointer_vector,
as vector is better than linear_vector and I've never used
pointer_vector.
vector also gets move(), which is a way to use move-semantics across
types. It lets you steal the underlying memory pool, effectively
destroying the vector without a copy.
This works really nicely with the move for read() functions to return
vector<uint8> instead of taking (uint8_t*&, unsigned&) parameters.
byuu says:
Changelog:
- eliminated <mmio>, <mcu> tags [they are merged to their parent nodes
now]
- added <ram name= size=> tag to EpsonRTC, SharpRTC
- added <firmware> tag to DSP-n, ST-01n, ST-018, Cx4
- interface->path(0) now returns the system folder, which can be used
for storage now
- as a fun proof-of-concept, I've simulated SNES warm power cycles by
saving and loading work RAM (same effect if you instantly swapped
carts)
- long-term, I'm not sure how I want to do this. The power menu option
makes no sense with warm RAM
- I like the idea of decaying RAM based on timestamp from last play;
and power can just force the timestamp to 0 (which will corrupt all
RAM)
- Interface::firmware is gone. The cores now load firmware inside their
boot up routines
- you now get a message on the screen if the emulator can't find
firmware, should help with "I just get a black screen" messages
I'd like to start preparing for a v090 release. I think we're almost
there now. Have to update nall/cartridge and purify to handle XML
changes first.
byuu says:
Changelog:
- SuperFX has its own ROM and RAM
- Cx4 has its own ROM
- SPC7110 has its own ProgramROM, DataROM and RAM
- OBC1 has its own RAM
- BsxCartridge has its own ROM, RAM and PSRAM
- mapping changes to accommodate the above
byuu says:
Changelog:
- NSS emulation improvement (DIP is 8-bits, not 16-bits; can be remapped
via XML now like all the other chips)
- SA-1 memory map improvements (IRAM and BWRAM can be saved; ROM, IRAM
and BWRAM are separate from Cartridge::ROM, RAM; no MCU)
- S-DD1 memory map improvements (ROM, RAM inside mapping; no MCU)
- SPC7110 memory map improvements (ROM, RAM inside mapping; no MCU; not
finished yet [have to handle 8mbit expansion somehow now)
I have tried multiple times now to get the SuperFX core to use internal
ROM and RAM (separate from Cartridge::ROM, RAM) to no avail.
Not sure what the hell is going on there. Trace logs of 430MB are not
enticing ...
So right now: SuperFX, SPC7110 and BS-X cheat by mapping stuff to
Cartridge::ROM, RAM still. They need to not do that.
[also, replace the old purify tool with the new tool by the same name.
There were some previous releases outside the WIP thread, but this is
the first one that actually works with a WIP release. -Ed.]
byuu says:
Fixes up loading issues with recent purify changes, and purify also
works on BS/ST file types now and should be a bit more crash-resistant.
byuu says:
Changelog:
- Game Boy XML uses <cartridge><board type="MBC3"/> instead of
<cartridge mapper="MBC3">
- if you run bsnes with a filename argument, it will invoke "purify
filename" and exit immediately
- this chains: purify will turn the file into a game folder, and then
invoke bsnes with the game folder name
- net result: you can drag a ZIP file onto bsnes or associate SMC
headered ROMs with bsnes and they'll just work
- new nall: unified usage of - vs _ vs nothing on filenames; fancier
lstring; fancier image (constructor for creating from filename or from
memory); etc
- new phoenix: images in ListView, GTK+ merges the check box into the
first column like the other targets do, etc
- browser list now uses icons to differentiate system folders from game
folders (the game folder icon sucks, I'm open to suggestions though,
as long as it's available on Debian Squeeze in /usr/share/icons, no
custom stuff please)
byuu says:
Changelog:
- SPC7110 $480b (and its settings in $4805-6 + $4807) is now fully
emulated
- decompressor restructured and commented accordingly
The final parts remaining for the SPC7110 core, all within the
decompression engine:
- need to detect when 15+ input bytes are read for one output byte and
simulate a crash somehow (don't have to perfectly simulate corrupted
data stream)
- need to emulate time required to decompress data (doesn't have to be
perfect, just something other than instantaneous)
- need to determine what $480c status flags d6-d0 are for, as best we
can anyway
byuu says:
Changelog:
- Cydrak merged all three SPC7110 decompression routines into one, cuts
the size in half
- fixed masking of $4803.d7 and $4813.d7
- data port out of bounds accesses emulated correctly for app SPC7110
boards
- all(?) data port $4810 reload cases now supported
- basic timing for $4805-6 seeking; reworked delay timing to work better
as well
- fixed $480c.d7 flag (1 = ready, not busy)
- AbsoluteInput returns -32768 if presentation window lacks focus and
you don't always allow input
byuu says:
Changelog:
- SPC7110 data port emulation greatly improved
- SPC7110 $480b.d1 emulated (but $4805-4806 does not work right for mode
2 decompression yet)
- MSU1 audio output will be muted when the S-DSP FLG ($6c).d6 (mute)
flag is set
- MSU1 will read filenames from manifest now (defaults to msu1.rom and
track-#.pcm if missing ... for now)
- bugfixes with MSU1 load state and track seek (and $4804 was wrapping
into $4805 to change the track#)
- Link coprocessor removed (it was meant for ST018 HLE, which never
happened)
Notes for things I forgot but need to address:
- $4813 needs to be uint7 for the set_data_offset() to not allow reading
A23 as set ever (or we can mask)
- AbsoluteInput when window doesn't have focus should return -32768, not
0
- need to support input ID lists that aren't linear (0-7), but arbitrary
(0,1,6,7 or whatever)
byuu says:
Changelog:
- Super Game Boy, BS-X Satellaview and Sufami Turbo cartridges all load
manifests that specify their file names, and they all work
- Sufami Turbo can now properly handle carts without RAM, or empty slots
entirely
- Emulator::Interface structures no longer specify any file names, ever
- exposed "capability.(cheats,states)" now. So far, this just means the
GBA doesn't show the cheat editor, since it doesn't support cheat
codes yet
- as such, state manager and cheat editor windows auto-hide (may be
a tiny bit inconvenient, but it makes not having to sync them or deal
with input when no cart is loaded easier)
- added "AbsoluteInput" type, which returns mouse coordinates from
-32767,-32767 (top left) to +32767,+32767 (bottom right) or
-32768,-32768 (offscreen)
AbsoluteInput is just something I'm toying with. Idea is to support eg
Super Scope or Justifier, or possibly some future Famicom controllers
that are absolute-indexed. The coordinates are scaled, so the bigger
your window, the more precise they are. But obviously you can't get more
precise than the emulated system, so 1x scale will behave the same
anyway. I haven't hooked it up yet, need to mess with the idea of custom
cursors via phoenix for that first. Also not sure if it will feel
smoother or not ... if you resize the window, your mouse will seem to
move slower. Still, not having to capture the mouse for SS/JS may be
nicer yet. But we'll see ... just experimenting for now.
byuu says:
Not even purify makes compatible images for this WIP.
Unless you want to figure it out yourself, I'd suggest waiting for an
updated tool before using subsequent WIPs.
Changelog:
- MSU1 initializes data port + audio track to 0
- MSU1 implements audio track error flag on $2000.d3
- manifest.xml now controls file names for cartridge folders ... mostly
Regressions:
- Super Game Boy support is broken
- Sufami Turbo support is broken
So, basically Emulator::Interface() now has:
void load(const string &manifest);
void save();
The first one will analyze the manifest, and call all the ROM + RAM
loadRequest() commands necessary to run the game.
The second one will call saveRequest() commands on all writable and
non-volatile storage (basically if it's a RAM type and has a filename
specified, it gets saved to disk.)
save() shrinks the size of Emulator::Interface() by hiding information
one is unlikely to care about. It also makes it much easier to save.
The core auto-calls this when you unload a game as well. So the only
time you ever have to worry about it is if you want to save RAM files
mid-game (in case you want to do periodic backups in case of a crash.)
[Yes, the release number is re-used. -Ed.]
byuu says:
I had some bugs in r07 that I couldn't track down, DKJM2's clock was
getting all out of sync.
So I just reverted to r05, blew away both RTCs entirely, and wrote them
cleanly from scratch (obviously looking off the old code.) A bit
extreme, but it worked.
I believe I found the error in the process, day and month were resetting
the counter to 0 instead of 1, it wasn't handling leap year, etc.
While I was at it, I fixed the day-of-week calculation. The SharpRTC
epoch is actually 1000-01-01, and not 1900-01-01.
I'm sure you guys will be really happy that if it ever becomes 1000AD
again and you're playing a ROM hack that uses the SharpRTC and relies on
its weekday value that it will show the correct day now ...
Kind of a pain to compute, but nothing compared to the seventh circle of
hell that was my IBM dBase III Julian<>Gregorian conversion functions :/
Also found a few bugs in the Epson code this way. And I moved the round
seconds actions and flag clear to +125us after flag set.
So, if you had the old r06 or r07, please delete those.
Unfortunately, this took all of my energy today, so the file names
inside manifest changes will have to be in the next WIP.
EDIT: ran a diff against old r07 and new r06.
- added if(days == 31) case twice in EpsonRTC::tick_day()
- forgot weekday = 0; in SharpRTC::load()
- need to move the cartridge+cheat objects up in sfc/Makefile again
- System::init() needs assert(interface != nullptr /* not 0 */)
byuu says:
Changelog:
- EpsonRTC emulation improved further (stop/pause blocks IRQs, verified
secondhi >= 3 triggers 30-second adjust (even on invalid BCD),
second-changed flag is mirrored to minute+hour+day+month+weekday,
improved busy timing, etc.)
- SharpRTC rewritten, works like EpsonRTC now in that it has its own
timing thread and ticks with the emulation
- won't attempt to read from an unopen file stream now (I think this is
what was crashing Sufami Turbo without SRAM?)
- added Tools -> Synchronize Time option below load/save state options.
Only appears when you play a game with an emulated RTC chip
Just realized that I used 125ms for the 30-second adjust instead of
125us, so I'll fix that in the next WIP.
Aside from that, this is as good as the emulation is going to get.
There's still a couple of absolutely psychopathic edge cases that are
just too damn difficult to simulate.
So that leaves us with data port control + decompression status
registers to investigate before SPC7110 will be finished.
byuu says:
Changelog:
- renamed SRTC -> SharpRTC
- renamed RTC4513 -> EpsonRTC (consistent with DSP naming schema)
- full emulation of invalid BCD values for EpsonRTC
- fixed EpsonRTC IRQ mask
Remaining SPC7110 tasks:
- RTC: test 30-second adjust with all values from 00-7f
- RTC: hold is supposed to tick the clock one second after being
released?
- RTC: wait times are too long (need to use >32KHz oscillation to
simulate it properly)
- Data Port: test $4818 more thoroughly (not too important)
- Decompression: test $480c more thoroughly (very important)
- Decompression: perform some tests on DMA transferring data, especially
with $4807 set
Write-offs, at least for now:
- Decompression: emulation of the crash/glitch behavior seen on the real
chip when fed invalid data
- Decompression: I can find no use of $4808
- ALU: Booth cycles for MUL/DIV (this could actually be rather important
if the game reads simpler values quickly [some shoddy games did this
with the CPU ALU])
- RTC: delay after hold release for $4841 accesses
- RTC: 125uS delay after 30-second adjust that will screw with registers
in odd ways if your read or write too soon
- RTC: psychotic behavior of reading too early returning port address
- 1
byuu says:
I split the RTC-4513 code from the SPC7110 code (and obviously in the
XML mapping as well), since they are separate chips on the FEoEZ PCB.
In this way, you can use just the RTC-4513 in homebrew now if you want.
It's a bit nicer than the Sharp RTC from Dai Kaijuu Monogatari II.
This was needed anyway, it has an internal oscillator that's not
divisible by the SNES clock used by the SPC7110; and both the RTC and
decompression code need to be running their own threads anyway.
In the process, I rewrote the way variables are stored to use named
integers rather than a block of memory. Makes the code a lot easier on
the eyes, and more importantly, will make emulating bad BCD values
a whole lot easier.
byuu says:
Changelog: (SPC7110)
- emulated $480b.d0 + $4807 deinterleave mode
- cleaned up decompression core (I'd still like to wipe out those static
variables, those are bad for save states.)
- improved emulation of data port ($481a only increments, never reads)
- improved emulation of RTC (block appropriate bits in the hour register
based on 12/24h mode select; $4840 modes != 1 all disable the chip;
added MDR; etc.)
byuu says:
Substantial improvements to SPC7110 emulation. Added all of the findings
from http://byuu.org/temp/spc7110-mmio.txt that I understood.
I also completely rewrote the RTC. We only had about ~40% of the chip
emulated before. Turns out there's cool stuff like spare RAM, calendar
disable, 12-hour mode, IRQs, IRQ masking, duty cycles, etc. So I went
ahead and emulated all of it. The upper bits on hour+ don't work as
nocash described though, not sure what doc he was reading. The Epson
RTC-4513 manual I have doesn't explain any of the registers.
The new RTC core also ticks seconds based on the emulated clock, and not
on the system clock. This is going to suck for people wanting to keep
the in-game clock synced with their computer, who also abuse fast
forward and save states. Fast forward makes the clock run faster, and
save states will jump the clock to the time it was at when you took the
save state. (It will keep track of the number of seconds between
unloading the game and loading it again, so time passes normally there.)
This is required, however, and how I'm going to rearrange all of the
RTCs for all systems. Any other method can be detected by the game, and
is thus not faithful emulation. To help with this, I'll probably make an
RTC time tool so that you can adjust the time when the emulator isn't
running, but I don't intend to bundle that into bsnes.
New state format bit-packs the RTCRAM values, and it also uses a 64-bit
timestamp. So it's 16 bytes now instead of 20 bytes. S-RTC will drop
from 16 to 12 when it's done.
The RTC busy flag timing needs to be refined with more hardware tests,
there's a slim chance of the game hanging on save at the moment.
The SPC7110 ALU delays are emulated now, too. They may not be perfectly
accurate, but they get the basic gist down.
The only hack that needs to be removed now is the decompression busy
flag. That's ... not going to be fun.
I also redid the mouse emulation. I was polling the mouse position
multiple times per latch. So it should be a bit more precise now,
I hope.
I read it regardless of latch state, dunno if that's good or not.
(r01 was not posted to the WIP thread)
byuu says:
r01 changelog:
- major improvements to SPC7110 MCU (memory controller unit)
- revised SPC7110 memory map to reflect aforementioned improvements
- added "Toggle Tracer" hotkey to target-ethos (only works for SFC so
far, I plan to use this as a lightweight laevateinn for FEoEZ)
r02 changelog:
- quick fix: SRAM is mapped to 00-3f|80-bf:6000-7fff
- quick fix: $4830.d7 is SRAM chip enable, not SRAM write enable. Reads
return 0x00 when this bit is clear
byuu says:
Changelog to v089:
- fix SA-1 Mini Yonku Shining Scorpion
- load from command-line
- remove SNES::Cartridge::NVRAM
- fix SGB save RAM
- update cheats.xml
- already mapped inputs cancel input assign
BS-X wasn't broken after all. I forgot that I ran purify on my BS-X
images, and that the BS Zelda ZIP I have has the disable ROM bit set.
Whoops.
byuu says:
Changelog:
- fixed BGnxOFS to not cache when MOSAIC is not in effect [fixes Air
Strike Patrol "Good Luck" text]
- added GameBoy::Interface::Hook for SGB bindings [SGB works again]
- do not create bsnes/ folder unless it is absolutely needed (eg you
create a save state or state manager archive)
- SuperFX works [needed to call system.init() in Interface::Interface()]
Last chance for any bug reports, at this point I pretty much consider
ethos to be finished. It's shipping without BS-X BIOS game loading
support. Sorry, I can't figure that one out.
byuu says:
Changelog:
- default placement of presentation window optimized for 1024x768
displays or larger (sorry if yours is smaller, move the window
yourself.)
- Direct3D waits until a previous Vblank ends before waiting for the
next Vblank to begin (fixes video timing analysis, and ---really---
fast computers.)
- Window::setVisible(false) clears modality, but also fixed in Browser
code as well (fixes loading images on Windows hanging)
- Browser won't consume full CPU resources (but timing analysis will,
I don't want stalls to affect the results.)
- closing settings window while analyzing stops analysis
- you can load the SGB BIOS without a game (why the hell you would want
to ...)
- escape closes the Browser window (it won't close other dialogs, it has
to be hooked up per-window)
- just for fun, joypad hat up/down moves in Browser file list, any
joypad button loads selected game [not very useful, lacks repeat, and
there aren't GUI load file open buttons]
- Super Scope and Justifier crosshairs render correctly (probably
doesn't belong in the core, but it's not something I suspect people
want to do themselves ...)
- you can load GB, SGB, GB, SGB ... without problems (not happy with how
I did this, but I don't want to add an Interface::setInterface()
function yet)
- PAL timing works as I want now (if you want 50fps on a 60hz monitor,
you must not use sync video) [needed to update the DSP frequency when
toggling video/audio sync]
- not going to save input port selection for now (lot of work), but it
will properly keep your port setting across cartridge loads at least
[just goes to controller on emulator restart]
- SFC overscan on and off both work as expected now (off centers image,
on shows entire image)
- laevateinn compiles properly now
- ethos goes to ~/.config/bsnes now that target-ui is dead [honestly,
I recommend deleting the old folder and starting over]
- Emulator::Interface callbacks converted to virtual binding structure
that GUI inherits from (simplifies binding callbacks)
- this breaks Super Game Boy for a bit, I need to rethink
system-specific bindings without direct inheritance
Timing analysis works spectacularly well on Windows, too. You won't get
your 100% perfect rate (unless maybe you leave the analysis running
overnight?), but it'll get really freaking close this way.
byuu says:
Changelog:
- added NSS DIP switch settings window (when loading NSS carts with
appropriate manifest.xml file)
- added video shader selection (they go in ~/.config/bsnes/Video
Shaders/ now)
- added driver selection
- added timing settings (not only allows video/audio settings, also has
code to dynamically compute the values for you ... and it actually
works pretty good!)
- moved "None" controller device to bottom of list (it is the least
likely to be used, after all)
- added Interface::path() to support MSU1, USART, Link
- input and hotkey mappings remember list position after assignment
- and more!
target-ethos now has all of the functionality of target-ui, and more.
Final code size for the port is 101.2KB (ethos) vs 167.6KB (ui).
A ~67% reduction in code size, yet it does even more! And you can add or
remove an entire system with only three lines of code (Makefile include,
header include, interface append.)
The only problem left is that the BS-X BIOS won't load the BS Zelda no
Densetsu file.
I can't figure out why it's not working, would appreciate any
assistance, but otherwise I'm probably just going to leave it broken for
v089, sorry.
So the show stoppers for a new release at this point are:
- fix laevateinn to compile with the new interface changes (shouldn't be
too hard, it'll still use the old, direct interface.)
- clean up Emulator::Interface as much as possible (trim down
Information, mediaRequest should use an alternate struct designed to
load firmware / slots separately)
- enhance purify to strip SNES ROM headers, and it really needs a GUI
interface
- it would be highly desirable to make a launcher that can create
a cartridge folder from an existing ROM set (* ethos will need to
accept command-line arguments for this.)
- probably need to remember which controller was selected in each port
for each system across runs
- need to fix the cursor for Super Scope / Justifier games (move from
19-bit to 32-bit colors broke it)
- have to refactor that cache.(hv)offset thing to fix ASP
byuu says:
Changelog:
- fixed Super Game Boy input
- Sufami Turbo prompts to load second slot now (you can cancel to leave
it empty)
- NEC/Hitachi/ARM DSP firmware is loaded; NEC RAM is saved
- folders are grouped properly: Sufami Turbo save RAM saves to its slot
folder, etc.
- title shows properly (SGB shows GB game name only, BS-X slotted shows
game name and optional slot name, etc.)
- above extends to saving cheats and such in their correct folders
as well
- added cheat editor and cheat database
- and hooked up the requisite SGB mode loads and can use GB cheats,
because that's kinda cool
- added state manager
- input settings, cheat editor and state manager all have erase (one)
and reset (all) buttons now
- lots of cleanup and restructuring on Emulator::Interface; *almost*
finished with it now
Remaining:
- BS-X BIOS won't show the data pack
- need XML mapping information window
- need NSS DIP switch settings window
- need video shaders
- need driver selection
- need to hide controllers that have no inputs from the input mapping
list (tempted to just remove "None" as a controller option ...)
ethos is currently 88KB of code, ui is 167KB. We're missing about 5-10KB
of code in ethos to complete it, so the rewrite nearly cut the GUI code
size in half, while support all of the same functionality and allowing
the easy addition and removal of entire systems.
byuu says:
Changelog:
- all hotkeys from target-ui now exist in target-ethos
- controller port menus now show up when you load a system (hidden if
there are no options to choose from)
- tools menu auto-hides with no game open ... not much point to it then
- since we aren't using RawInput's multi-KB/MS support anyway, input and
hotkey mappings remove KB0:: and turn MS0:: into Mouse::, makes it
a lot easier to read
- added mute audio, sync video, sync audio, mask overscan
- added video settings: saturation, gamma, luminance, overscan
horizontal, overscan vertical
- added audio settings: frequency, latency, resampler, volume
- added input settings: when focus is lost [ ] pause emulator [ ] allow
input
- pausing and autopausing works
- status messages hooked up (show a message in status bar for a few
seconds, then revert to normal status text)
- sub systems (SGB, BSX, ST) sorted below primary systems list
- added geometry settings cache
- Emulator::Interface cleanups and simplifications
- save states go into (cart foldername.extension/bsnes/state-#.bsa) now.
Idea is to put emulator-specific data in their own subfolders
Caveats / Missing:
- SGB input does not work
- Sufami Turbo second slot doesn't work yet
- BS-X BIOS won't show the data pack
- need XML mapping information window
- need cheat editor and cheat database
- need state manager
- need video shaders
- need driver selection
- need NSS DIP switch settings
- need to hide controllers that have no inputs from the input mapping
list
So for video settings, I used to have contrast/brightness/gamma.
Contrast was just a multiplier on intensity of each channel, and
brightness was an addition or subtraction against each channel. They
kind of overlapped and weren't that effective. The new setup has
saturation, gamma and luminance.
Saturation of 100% is normal. If you lower it, color information goes
away. 0% = grayscale. If you raise it, color intensity increases (and
clamps.) This is wonderful for GBA games, since they are oversaturated
to fucking death. Of course we'll want to normalize that inside the
core, so the same sat. value works on all systems, but for now it's
nice. If you raise saturation above 100%, it basically acts like
contrast used to. It's just that lowering it fades to grayscale rather
than black.
Adding doesn't really work well for brightness, it throws off the
relative distance between channels and looks like shit. So now we have
luminance, which takes over the old contrast <100% role, and just fades
the pixels toward black. Obviously, luminance > 100% would be the same
as saturation > 100%, so that isn't allowed, it caps at 100% now.
Gamma's the same old function. Gamma curve on the lower-half of the
color range.
Effects are applied in the order they appear in the GUI: color ->
saturate -> gammify -> luminate -> output.
byuu says:
Changelog:
- phoenix has added Window::setModal(bool modal = true);
- file dialog is now modal. This allows emulation cores to request data
and get it immediately before continuing the loading process
- save data is hooked up for most systems, still need to handle
subsystem slot saves (Sufami Turbo, basically.)
- toggle fullscreen key binding added (Alt+Enter for now. I think F11 is
probably better though, Enter is often mapped to game start button.)
- video scaling is in (center, scale, stretch), works the same in
windowed and fullscreen mode (stretch hides resize window option), all
in the settings menu now
- enough structure to map all saved paths for the browser and to load
BS-X slotted carts, BS-X carts, single Sufami Turbo carts
Caveats / Missing:
- Super Game Boy input doesn't work yet (due to change in callback
binding)
- doesn't load secondary Sufami Turbo slot yet
- BS-X BIOS isn't show the data pack games to load for some reason (ugh,
I hate the shit out of debugging BS-X stuff ...)
- need mute audio, sync audio+video toggle, save/load state menu and
quick keys, XML mapping information window
- need cheat editor and cheat database
- need state manager
- need to sort subsystems below main systems in load menu (basically
just see if media.slot.size() > 0)
- need video shaders (will probably leave off filters for the time being
... due to that 24/30-bit thing)
- need video adjustments (contrast etc, overscan masks)
- need audio adjustments (frequency, latency, resampler, volume,
per-system frequency)
- need driver selection and input focus policy (driver crash detection
would be nice too)
- need NSS DIP switch settings (that one will be really fun)
- need to save and load window geometry settings
- need to hook up controller selection (won't be fun), create a map to
hide controllers with no inputs to reassign
byuu says:
ethos is going to be absolutely amazing. You guys are in for a treat :D
I'm impressing the hell out of myself with how well-structured this code
is, it's allowing me to do amazing new things.
Just a small sampling of what's in store (and already implemented):
The file browser will display folders as "[ folder name ]", and
cartridge folders as "Game Name" (no extension, no /) [icons would be
nicer, but well ... phoenix.]
Folders are sorted above cartridge folders.
Cartridge folders for other systems do not show up in the list.
Not only are unique paths stored for each image type, your position in
the list is saved across runs.
Some voodoo was added to GTK+ so that all targets even scroll directly
to that item when you open the list. Load->System->Enter restarts your
last game.
That sounds really simple and obvious, but it makes an -incredible-
difference. Didn't realize it until I tried an implementation of it,
wow.
The input mapping list now lets you bind as many hotkeys as you want to
any given input.
So SFC::Port1::Joypad::B = Keyboard::Z or Joypad::Button1 ... no need to
remap everything to switch between keyboard and joypad. Either one
activates the key.
There is a separate Hotkeys tab now. This should hopefully end the
confusion about how to remap hotkeys that users experience.
Hotkeys are different, too. Instead of OR logic, they use AND logic.
So Fullscreen = Keyboard::Alt and Keyboard::Enter. Both must be pressed
to enter the key. This lets you easily implement "super" modifier keys.
The actual codebase has new features the old UI never had, and has about
~50% of the old functionality (so far, of course), yet is only ~25% as
much code.
The entire GUI no longer needs to pull in all the headers for each
emulated system. It just needs a small interface header file.
Then bind the entire system with exactly **two** lines of code.
Everything is dynamically generated for you after that.
byuu says:
Lots of work on ethos, nothing more.
Settings window is in, InputManager pulls all the inputs from all cores
and binds them to ruby inputs, main window adds menu and dynamically
maps in all systems and cartridge slots and options and such, file
browser's back in, RAM is loaded and saved, etc. It's barely usable, but
you have to set up your inputs from the config file by hand for now.
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.
byuu says:
(r05 and r06 were save points between large core modifications)
I would really appreciate extensive regression testing (especially
around SuperFX, Cx4, ST018, DSP-n, ST-01n, NES, GB) at this point.
The most critical core changes should be completed now. And it was an
unbelievable amount of restructuring.
Changelog:
- SuperFX core moved to Processor::GSU
- SNES::CPU core moved to Processor::R65816
- SNES::SMP core moved to Processor::SPC700
- NES::CPU core renamed to Processor::R6502
- use filestream to load RAM files from interface
- save states store SHA256 instead of CRC32 (CRC32 usage removed
entirely from bsnes)
- nes/ -> fc/ and NES -> FC
- snes/ -> sfc/ and SNES -> SFC
- SuperFamicom::MappedRAM::copy uses stream instead of data+size
- Linux port uses gcc-4.7 (still using only gcc-4.6 subset, so you can
make a gcc-4.6 symlink for now if you like.)
- all profiles and all targets compile and work properly
All eight instruction set cores have been moved to processor/ now.
Consistency's a wonderful thing.
The last remnants of NES/SNES are now limited to target-ui code; and the
nall/(system) folder names.
I'm building with gcc-4.7 on my Linux box now because the resultant
binaries are up to 20% faster (seriously) than gcc-4.6.
byuu says:
This will hopefully be a short-lived WIP, I just want to save
a breakpoint before I attempt something else.
NES, GB, GBC and GBA all load via const stream& now.
NES CPU core moved to Processor::RP2A03.
byuu says:
static vector<uint8_t> file::read(const string &filename); replaces:
static bool file::read(const string &filename, uint8_t *&data, unsigned
&size); This allows automatic deletion of the underlying data.
Added vectorstream, which is obviously a vector<uint8_t> wrapper for
a data stream. Plan is for all data accesses inside my emulation cores
to take stream objects, especially MSU1. This lets you feed the core
anything: memorystream, filestream, zipstream, gzipstream, httpstream,
etc. There will still be exceptions for link and serial, those need
actual library files on disk. But those aren't official hardware devices
anyway.
So to help with speed a bit, I'm rethinking the video rendering path.
Previous system:
- core outputs system-native samples (SNES = 19-bit LRGB, NES = 9-bit
emphasis+palette, DMG = 2-bit grayscale, etc.)
- interfaceSystem transforms samples to 30-bit via lookup table inside
the emulation core
- interfaceSystem masks off overscan areas, if enabled
- interfaceUI runs filter to produce new target buffer, if enabled
- interfaceUI transforms 30-bit video to native display depth (24-bit or
30-bit), and applies color-adjustments (gamma, etc) at the same time
New system:
- all cores now generate an internal palette, and call
Interface::videoColor(uint32_t source, uint16_t red, uint16_t green,
uint16_t blue) to get native display color post-adjusted (gamma, etc
applied already.)
- all cores output to uint32_t* buffer now (output video.palette[color]
instead of just color)
- interfaceUI runs filter to produce new target buffer, if enabled
- interfaceUI memcpy()'s buffer to the video card
videoColor() is pretty neat. source is the raw pixel (as per the
old-format, 19-bit SNES, 9-bit NES, etc), and you can create a color
from that if you really want to. Or return that value to get a buffer
just like v088 and below. red, green, blue are 16-bits per channel,
because why the hell not, right? Just lop off all the bits you don't
want. If you have more bits on your display than that, fuck you :P
The last step is extremely difficult to avoid. Video cards can and do
have pitches that differ from the width of the texture. Trying to make
the core account for this would be really awful. And even if we did
that, the emulation routine would need to write directly to a video card
RAM buffer. Some APIs require you to lock the video buffer while
writing, so this would leave the video buffer locked for a long time.
Probably not catastrophic, but still awful. And lastly, if the
emulation core tried writing directly to the display texture, software
filters would no longer be possible (unless you -really- jump through
hooks and divert to a memory buffer when a filter is enabled, but ...
fuck.)
Anyway, the point of all that work was to eliminate an extra video copy,
and the need for a really painful 30-bit to 24-bit conversion (three
shifts, three masks, three array indexes.) So this basically reverts us,
performance-wise, to where we were pre-30 bit support.
[...]
The downside to this is that we're going to need a filter for each
output depth. Since the array type is uint32_t*, and I don't intend to
support higher or lower depths, we really only need 24+30-bit versions
of each filter. Kinda shitty, but oh well.
byuu says:
Basically, the current implementation of nall/array is deprecated now.
The old method was for non-reference types, it acted like a vector for
POD types (raw memory allocation instead of placement new construction.)
And for reference types, it acted like an unordered set. Yeah, not good.
As of right now, nall/array is no longer used. The vector type usage was
replaced with actual vectors.
I've created nall/set, which now contains the specialization for
reference types.
nall/set basically acts much like std::unordered_set. No auto-sort, only
one of each type is allowed, automatic growth.
This will be the same both for reference and non-reference types ...
however, the non-reference type wasn't implemented just yet.
Future plans for nall/array are for it to be a statically allocated
block of memory, ala array<type, size>, which is meant for RAII memory
usage.
Have to work on the specifics, eg the size as a template parameter may
be problematic. I'd like to return allocated chunks of memory (eg
file::read) in this container so that I don't have to manually free the
data anymore.
I also removed nall/moduloarray, and moved that into the SNES DSP class,
since that's the only thing that uses it.
byuu says:
Changes to v088:
- OBJ mosaic Y fix
- Laevateinn compilation
- Remove filebrowser extra code
- Fix -march=native on Windows
- Fix purify mkdir
- GBA sound volume
- Add .gbb
- free firmware memory after file load
- Add GBA game to profile list (Yoshi's Island should work)
byuu says:
Changelog:
- DMA channel masks added (some are 27-bit source/target and some are
14-bit length -- hooray, varuint_t class.)
- No more state.pending flags. Instead, we set dma.pending flag when we
want a transfer (fixes GBA Video - Pokemon audio) [Cydrak]
- fixed OBJ Vmosaic [Cydrak, krom]
- OBJ cannot read <=0x13fff in BG modes 3-5 (fixes the garbled tile at
the top-left of some games)
- DMA timing should be much closer to hardware now, but probably not
perfect
- PPU frame blending uses blargg's bit-perfect, rounded method (slower,
but what can you do?)
- GBA carts really unload now
- added nall/gba/cartridge.hpp: used when there is no manifest. Scans
ROMs for library tags, and selects the first valid one found
- added EEPROM auto-detection when EEPROM size=0. Forces disk/save state
size to 8192 (otherwise states could crash between pre and post
detect.)
- detects first read after a set read address command when the size
is zero, and sets all subsequent bit-lengths to that value, prints
detected size to terminal
- added nall/nes/cartridge.hpp: moves iNES detection out of emulation
core.
Important to note: long-term goal is to remove all
nall/(system)/cartridge.hpp detections from the core and replace with
databases. All in good time.
Anyway, the GBA workarounds should work for ~98.5% of the library, if my
pre-scanning was correct (~40 games with odd tags. I reject ones without
numeric versions now, too.)
I think we're basically at a point where we can release a new version
now. Compatibility should be relatively high (at least for a first
release), and fixes are only going to affect one or two games at a time.
I'd like to start doing some major cleaning house internally (rename
NES->Famicom, SNES->SuperFamicom and such.) Would be much wiser to do
that on a .01 WIP to minimize regressions.
The main problems with a release now:
- speed is pretty bad, haven't really optimized much yet (not sure how
much we can improve it yet, this usually isn't easy)
- sound isn't -great-, but the GBA audio sucks anyway :P
- couple of known bugs (Sonic X video, etc.)
byuu says:
Changelog:
- revised NES XML tag nesting
- program.rom is going to refer to PRG+CHR combined. Split is going to
have to use different file names
- slot loader is gone (good riddance!)
- "Cartridge -> Load Game Boy Advance Cartridge ..." has become "Load ->
Game Boy Advance ..."
- Load Satellaview Slotted Cartridge is gone. If you load an SNES
cartridge and it sees <bsx><slot>, it asks if you want to load a BS-X
data pack
- If you load a Sufami Turbo cartridge with <cartridge linkable="true">,
it asks if you want to link in another Sufami Turbo cartridge
- if you try and load the same exact Sufami Turbo cartridge in both
slots, it yells at you for being an idiot :P
byuu says:
Be sure to run make install, and move required images to their appropriate system profile folders.
I still have no warnings in place if those images aren't present.
Changelog:
- OBJ mosaic should hopefully be emulated correctly now (thanks to krom
and Cydrak for testing the hardware behavior)
- emulated dummy serial registers, fixes Sonic Advance (you may still
need to specify 512KB FlashROM with an appropriate ID, I used
Panaonic's)
- GBA core exits scheduler (PPU thread) and calls
interface->videoRefresh() from main thread (not required, just nice)
- SRAM, FRAM, EEPROM and FlashROM initialized to 0xFF if it does not
exist (probably not needed, but FlashROM likes to reset to 0xFF
anyway)
- GBA manifest.xml for file-mode will now use "gamename.xml" instead of
"gamename.gba.xml"
- started renaming "NES" to "Famicom" and "SNES" to "Super Famicom" in
the GUI (may or may not change source code in the long-term)
- removed target-libsnes/
- added profile/
Profiles are the major new feature. So far we have:
Famicom.sys/{nothing (yet?)}
Super Famicom.sys/{ipl.rom}
Game Boy.sys/{boot.rom}
Game Boy Color.sys/{boot.rom}
Game Boy Advance.sys/{bios.rom[not included]}
Super Game Boy.sfc/{boot.rom,program.rom[not included]}
BS-X Satellaview.sfc/{program.rom,bsx.ram,bsx.pram}
Sufami Turbo.sfc/{program.rom}
The SGB, BSX and ST cartridges ask you to load GB, BS or ST cartridges
directly now. No slot loader for them. So the obvious downsides: you
can't quickly pick between different SGB BIOSes, but why would you want
to? Just use SGB2/JP. It's still possible, so I'll sacrifice a little
complexity for a rare case to make it a lot easier for the more common
case. ST cartridges currently won't let you load the secondary slot.
BS-X Town cart is the only useful game to load with nothing in the slot,
but only barely, since games are all seeded on flash and not on PSRAM
images. We can revisit a way to boot the BIOS directly if and when we
get the satellite uplink emulated and data can be downloaded onto the
PSRAM :P BS-X slotted cartridges still require the secondary slot.
My plan for BS-X slotted cartridges is to require a manifest.xml to
specify that it has the BS-X slot present. Otherwise, we have to load
the ROM into the SNES cartridge class, and parse its header before we
can find out if it has one. Screw that. If it's in the XML, I can tell
before loading the ROM if I need to present you with an optional slot
loading dialog. I will probably do something similar for Sufami Turbo.
Not all games even work with a secondary slot, so why ask you to load
a second slot for them? Let the XML request a second slot. A complete
Sufami Turbo ROM set will be trivial anyway. Not sure how I want to do
the sub dialog yet. We want basic file loading, but we don't want it to
look like the dialog 'didn't do anything' if it pops back open
immediately again. Maybe change the background color of the dialog to
a darker gray? Tacky, but it'd give you the visual cue without the need
for some subtle text changes.
byuu says:
Changelog:
- serialize processor.pc.data, not processor.pc
- call CPU processor.setMode() in ARM serialize
- serialize BIOS.mdr
- support SRAM > 32KB
- EEPROM, FlashROM serialize
- EEPROM lose nall/bitarray.hpp
- noise line feed after envelope
- space out PSR read
- ST018 needs byte reads fixed (don't align) [fixes HNMS2]
- flush sram/eeprom/flashrom to 0 on cartridge load
- APU/PPU dont sync back to CPU if syncing for state
- fixed APU sync problems in GB/GBC core that could possibly wreck save
states as well
Quite a lot of little problems there. I believe GBA save states are
fixed now.
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
byuu says:
(r24 was a point release during merging of changes.)
This release is almost entirely Cydrak's direct work:
- Added ARM::sequential() and some WAITCNT timings
- Added Bus::io(uint32 pc), intended for prefetch timing
- Added ARM::load() with data rotation (fixed Mother 3 graphics)
- Added ARM::store() for data mirroring
- LDM, STM, and instruction fetch still use read/write()
- ARM::vector() no longer unmasks FIQs
- Set THUMB shifter flags via bit(), consistent with ARM
- Replace shifter loops with conditional tests
My changes:
- fixed sprite clipping on left-edge of screen
- added first system folder, GBA.system
- sudo make install is now make install
- make install will create GBA.system for you in your home folder
Windows users, take data/GBA.system and put it in the same folder as
bsnes.exe, and give it a BIOS named bios.rom
Or place it in your home folder (%APPDATA%/bsnes)
Also note that this is highly experimental, I'll probably be changing
things a lot before release.
EDIT: I botched the cartridge timing change. Will fix in r26. It'll
still run a bit too fast for now, unfortunately.
byuu says:
Changelog:
- fixed cascading timers and readouts (speed hit from 320fps to 240fps;
would be 155fps with r20 timers) (fixes Spyro)
- OBJ mode 3 acts like OBJ mode 2 now (may not be correct, but nobody
has info on it)
- added background + object vertical+horizontal mosaic in all modes
(linear+affine+bitmap)
- object mosaic uses sprite (0,0) for start coordinates, not screen
(0,0) (again, nobody seems to have info on it)
- BIOS cannot be read by r(15)>=0x02000000; returns last BIOS read
instead (I can't believe games rely on this to work ... fixes SMA
Mario Bros.)
Mosaic is what concerns me the most, I've no idea if I'm doing it
correctly. But anything is probably better than nothing, so there's
that. I don't really notice the effect in Metroid Fusion. So either it's
broken, or it's really subtle.
byuu says:
Changelog:
- fixed below pixel green channel on color blending
- added semi-transparent objects [Exophase's method]
- added full support for windows (both inputs, OBJ windows, and output, with optional color effect disable)
- EEPROM uses nall::bitarray now to be friendlier to saving memory to disk
- removed incomplete mosaic support for now (too broken, untested)
- improved sprite priority. Hopefully it's right now.
Just about everything should look great now. It took 25 days, but we
finally have the BIOS rendering correctly.
In order to do OBJ windows, I had to drop my above/below buffers
entirely. I went with the nuclear option. There's separate layers for
all BGs and objects. I build the OBJ window table during object
rendering. So as a result, after rendering I go back and apply windows
(and the object window that now exists.) After that, I have to do
a painful Z-buffer select of the top two most important pixels. Since
I now know the layers, the blending enable tests are a lot nicer, at
least. But this obviously has quite a speed hit: 390fps to 325fps for
Mr. Driller 2 title screen.
TONC says that "bad" window coordinates do really insane things. GBAtek
says it's a simple y2 < y1 || y2 > 160 ? 160 : y2; x2 < x1 || x2 > 240
? 240 : x2; I like the GBAtek version more, so I went with that. I sure
hope it's right ... but my guess is the hardware does this with
a counter that wraps around or something. Also, say you have two OBJ
mode 2 sprites that overlap each other, but with different priorities.
The lower (more important) priority sprite has a clear pixel, but the
higher priority sprite has a set pixel. Do we set the "inside OBJ
window" flag to true here? Eg does the value OR, or does it hold the
most important sprite's pixel value? Cydrak suspects it's OR-based,
I concur from what I can see.
Mosaic, I am at a loss. I really need a lot more information in order to
implement it. For backgrounds, does it apply to the Vcounter of the
entire screen? Or does it apply post-scroll? Or does it even apply after
every adjust in affine/bitmap modes? I'm betting the hcounter
background mosaic starts at the leftmost edge of the screen, and repeats
previous pixels to apply the effect. Like SNES, very simple. For
sprites, the SNES didn't have this. Does the mosaic grid start at (0,0)
of the screen, or at (0,0) of each sprite? The latter will look a lot
nicer, but be a lot more complex. Is mosaic on affine objects any
different than mosaic of linear(tiled) objects?
With that out of the way, we still have to fix the CPU memory access
timing, add the rest of the CPU penalty cycles, the memory rotation
/ alignment / extend behavior needs to be fixed, the shifter desperately
needs to be moved from loops to single shift operations, and I need to
add flash memory support.
byuu says:
Timer speedup added. Boosts Mr. Driller 2 title from 170fps to 400fps.
Other games still benefit, but not as amazingly. I don't dip below
160fps ever here.
Reverted the memory speed to 2 for everything for now, to fix
Castlevania slowdown. We obviously need to add the N/S stuff before we
do that.
Added linear BG and linear OBJ mosaic-Y. Did not add mosaic-X, or any
mosaic to the affine/bitmap modes, because I'm not sure when to apply
the compensation.
Rewrote layer stuff. It now has two layers (above and below), and it
performs the four blending modes as needed.
Didn't add semi-transparent sprites because the docs are too confusing.
Added a blur filter directly into the PPU for now. This obviously
violates my interface, but F-Zero needed it for HUD display. We can
remove it when we have an official release with a blur filter available.
The filter still doesn't warp colors like a real GBA, because I don't
know the formula.
byuu says:
Changelog:
- HALT waits 16 cycles before testing IRQs instead of 1 (probably less
precise, but provides a massive speedup) [we will need to work on this
later]
- MMIO regs for CPU/PPU simplified by combining array accesses
- custom VRAM/PRAM/OAM read/write functions that emulate 8->16-bit
writes
- 16-bit PRAM data (decent speedup)
- emulated memory access speed (but don't handle non-sequential
penalties or PPU access penalties yet) [amazingly, doesn't help speed
at all]
- misc. code cleanups
For this WIP, FPS for Mr. Driller 2 went from 88fps to 172fps.
Compatibility should be unchanged. Timers are still an interesting
avenue to increase performance, but will be very tough to handle the
16MHz timers with eg a period of 65535 (overflow every single tick.) And
that's basically the last major speed boost we'll be able to get.
Blending and windowing is going to hurt performance, but it remains to
be seen how much.
byuu says:
Changelog:
- added FIFO buffer emulation (with DMA and all that jazz) [Cydrak]
- fixed timers and vcounter assign [Cydrak]
- emulated EEPROM (you have to change size manually for 14-bit mode, we
need a database badly now) [SMA runs now]
- removed OAM array, now decoding directly to struct Object {} [128] and
ObjectParam {} [32] (faster this way)
- check forceblank (still doesn't remove all garble between transitions,
though??)
- lots of other stuff
Delete your settings.cfg, or manually change frequencyGBA to 32768, or
bad things will happen (this may change back to 256KHz-4MHz later.)
15 of 16 games are fully playable now, and look and sound great.
The major missing detail right now is PPU blending support, and we
really need to optimize the hell out of the code.
byuu says:
Merged Cydrak's r17c changes:
- BG affine mode added
- BG bitmap mode added
- OBJ affine mode added
- fixed IRQ bug in THUMB mode (fixed almost every game)
- timers added (broke almost every game, whee.)
Cydrak is absolutely amazingly awesome and patient. This really wouldn't
be happening without him.
Also fixed some things from my end, including greatly improved sprite
priorities, and a much better priority sorter. Mr. Driller looks a lot
better now.
byuu says:
Emulated GBC sound plus the new extensions to it.
I am kind of surprised by how little developers utilized the GBC audio
portion.
Mr. Driller now has sound effects, and Pinobee no Daibouken has BGM.
I still have yet to emulate the GBA extra sound channels and PWM. Need
to emulate timers and DMA 2 refresh mode before I can do that.
Also, I moved both GBC and GBA audio to use length = data; if(++length
== 0); rather than length = 64 - data; if(--length == 0); so that
I could return literal values for register reads.
I thought there was a good reason we used the latter version, but
I can't hear any audible difference even in GBC games, so oh well.
Lastly, I think the pattern[++offset] in the wave channel was a bug in
the DMG/GBC only. I really, really hope it doesn't apply to the GBA,
because that will make bank selection a serious pain in the ass.
byuu says:
Fixed the r15 mask per Cydrak.
Added DMA support (immediate + Vblank + Hblank + HDMA) with IRQ support.
Basically only missing FIFO reload mode for the APU on channel 2.
Added background linear renderer (tilemap mode.)
Added really inefficient pixel priority selector, so that all BGs+OBJ
could be visible onscreen at the same time.
As a result of the above:
* Mr. Driller is our first fully playable game
* Bakunetsu Dodge Ball Fighters is also fully playable
* Pinobee no Daibouken is also fully playable
Most games (15 of 16 tested) are now showing *something*, many things
look really really good in fact.
Absolutely essential missing components:
- APU
- CPU timers and their interrupts
- DMA FIFO mode
- OBJ affine mode
- BG affine mode
- BG bitmap mode
- PPU windows (BG and OBJ)
- PPU mosaic
- PPU blending modes
- SRAM / EEPROM (going to rely on a database, not heuristics. Homebrew
will require a manifest file.)
byuu says:
Added linear (eg non-affine) sprite rendering, 4bpp and 8bpp with hflip
and vflip. Nothing else.
You can now see the Nintendo logo and Gameboy text at the end of the BIOS.
It's a start =)
byuu says:
Fixed aforementioned issues.
[From a previous post:
- mul was using r(d) instead of r(n) for accumulate.
- mull didn't remove c/v clear.
- APU register mask was broken, so SOUNDBIAS was reading out wrong.
- APU was only mapping 0x088 and not 0x089 as well.
- Halfword reads in CPU+PPU+APU were all reading from the low address
each time.]
All CPU+PPU registers are now hooked up (not that they do anything.)
SOUNDBIAS for APU was hooked up, got tired of working on it for the rest :P
I recall from the GB APU that you can't just assign values for the APU
MMIO regs. They do odd reload things as well.
Also, was using MMIO read code like this:
return (
(flaga << 0)
|| (flagb << 1)
|| (flagc << 2)
);
Logical or doesn't work so well with building flags :P
Bad habit from how I split multiple conditionals across several lines.
So ... r14 is basically what r13 should have been yesterday, delaying my
schedule by yet another day :(
byuu says:
Contains all of Cydrak's fixes, sans PPU.
On the PPU front, I've hooked up 100% of read and write registers.
All three DISPSTAT IRQs (Vblank, Hblank, Vcoincidence) are connected now
as well.
Super Mario Advance now runs without *appearing* to crash, although it's
hard to tell since I have no video or sound :P
ARM Wrestler is known to run, as is the BIOS.
byuu says:
Enough to get through the BIOS and into cartridge ROM.
I am a bit annoyed that I was basically told that the GBA PPU wasn't
that bad. Sprites are a clusterfuck, easily worse than Mode7, docs don't
even begin to explain them in enough detail.
This is going to be fun.
byuu says:
Added all of the above fixes and changes. [A lot of individual fixes for
the ARM core from Cydrak - Ed.] Also new is pipeline_decode() to fetch
data, and IME/IE/IF support, and an ARM::processor.irqline flag that
triggers IRQs at 0x18. Only Vblank is hooked up, which is what SWI 4 was
waiting on previously.
I'm sure my interrupt support is horribly broken and wrong. I was never
able to really figure out IE/IF on the Game Boy, so there's no question
this is even worse.
It's now going crazy and writing 0 to IE forever now after the Vblank
IRQ triggers.
byuu says:
Changelog:
- fixed THUMB hi immediate reads (immediate * 4)
- cartridge is properly mirrored to 32MB (eg 12mbit repeats as
lo8+hi4+hi4+lo8+hi4+hi4) [so it's a bit slower than a standard memcpy
fill]
- added ARM - load/store halfword register offset
- added ARM - load/store halfword immediate offset
- added ARM - load signed halfword/byte register offset
- added ARM - load signed halfword/byte immediate offset
- added decode() function to make opcode bit testing a lot clearer
(didn't apply it to the debugger yet)
All ARMv4M and all THUMBv4 instructions should now be implemented.
Although I'm not sure if my implementations of the new instructions are
correct.
byuu says:
Split apart necdsp: core is now in processor/upd96050 (wish I had
a better name for it, but there's no family name that is maskable.)
I would like to support the uPD7720 in the core as well, just for
completeness' sake, but I'll have to modify the decoder to drop one bit
from each mode.
So ... I'll do that later. Worst part is even if I do, I won't be able
to test it :(
Added all of Cydrak's changes. I also simplified LDMIA/STMIA and
PUSH/POP by merging the outer loops.
Probably infinitesimally slower, but less code is nicer. Maybe GCC
optimization will expand it, who knows.
byuu says:
Added some more ARM opcodes, hooked up MMIO. Bind it with mmio[(addr
000-3ff)] = this; inside CPU/PPU/APU, goes to read(), write().
Also moved the Hitachi HG51B core to processor/, and split it apart from
the snes/chip/hitachidsp implementation.
This one actually worked really well. Very clean split between MMIO/DMA
and the processor core. I may move a more generic DMA function inside
the core, not sure yet.
I still believe the HG51B169 to be a variant of the HG51BS family, but
given they're meant to be incredibly flexible microcontrollers, it's
possible that each variant gets its own instruction set.
So, who knows. We'll worry about it if we ever find another HG51B DSP,
I guess.
GBA BIOS is constantly reading from 04000300, but it never writes. If
I return prng()&1, I can get it to proceed until it hits a bad opcode
(stc opcode, which the GBA lacks a coprocessor so ... bad codepath.)
Without it, it just reads that register forever and keeps resetting the
system, or something ...
I guess we're going to have to try and get ARMwrestler working, because
the BIOS seems to need too much emulation code to do anything at all.
There was a "v087r07pre" release that I unfortunately missed.
byuu says (about v087r07pre):
Creates the bsnes/processor folder. This has a shared ARM core there
which both the GBA and ST018 inherit.
There are going to be separate decoders, and revision-specific checks,
to support the differences between v3+.
In the future, I also want to move the other processor cores here:
- GBZ80 (GB, GBC)
- 65816 (SNES CPU, SA-1)
- NEC uPD (7725, 96050, maybe 7720 just for fun)
- Hitachi HG51B169
- SuperFX
- SPC700
- 65(C?)02
Basically, the GBA/ST018 forces my hand to start coding a bit more like
a multi-system emulator.
Right now, the ST018 is broken. Hence the pre. Apparently the GBA core
being used now has some bugs. So this'll be a nice way to stress-test
the GBA core a bit before we make it to ARMwrestler.
byuu says (about v087r07):
Both snes/chip/armdsp and gba/cpu use processor/arm now.
Fixed THUMB to execute the BL prefix and suffix separately. I can now
get the GBA BIOS stuck in some kind of infinite loop. Hooray ...
I guess?
byuu says:
I believe I've implemented every THUMB instruction now, although I'm
sure there are dozens of bugs in the implementation.
It seems that the last jump taken is ending up being off-by-two. It's
probably due to not masking/adjusting PC correctly at certain points.
I don't know if any other bugs are being hit prior to this or not.
I don't implement any I/O registers yet, and the BIOS seems to be poking
at a few of them along the way, so ... who knows.
I could also be reading the log wrong, but it looks to me like there's
some PSR setting the mode flag register to 0, which is supposed to be an
undefined behavior mode ... perhaps mrs has no effect on the m/t bits,
and it just affects the i/f bits?
byuu says:
Implemented all of the ARMv3 instructions, and the bx rm instruction as
well. Already hit THUMB mode right at the start of the BIOS, sigh.
Implemented the first THUMB instruction to get that rolling. Also tried
to support the S flag to LDM/STM, but not sure how successful I was.
byuu says:
GBA stuff re-added. Only thing missing that was there before is the ARM
branch opcode.
Since we're going to be staring at it for a very long time, I added
a more interesting test video pattern.
Went from 6fps to 912fps. Amazing what being able to divide can do for
a frame rate.
byuu says:
Fixing the PPU stepping increased FPS to 250. Promising, at least, since
the ARM core is still severely overclocked.
However, I reverted back to r02. This one patches gameboy/ and GameBoy::
to gb/ and GB:: and that's it.
Sorry, I just couldn't shake this bad feeling about the code. There were
some poorly hacked-together constructs. I'd rather just redo two days of
work than feel bad about the codebase for the next several years. Going
to attempt the GBA bridge again. Third time's a charm, I suppose (there
was a pre-r03 WIP I abandoned as well.)
This isn't unprecedented, GB core took a few attempts like this as well.
byuu says:
Changelog:
- gameboy/ -> gb/
- GameBoy -> GB
- basic memory map for GBA
- enough code to execute the first BIOS instruction (b 0x68)
I have the code resetting r(15) to 0 on an exception just as a test.
Since that flushes the pipeline, that means we're basically executing "b
0x68" at 8MHz, and nothing else.
... and I am getting __6 motherfucking FPS__ at 4.4GHz on an i7.
Something is seriously, horribly, unfuckingbelievably wrong here, and
I can't figure out what it is.
My *fully complete* ARM core on the ST018 is even less efficient and
runs at 21.47MHz, and yet I get 60fps even after emulating the SNES
CPU+PPU @ 10+MHz each as well.
... I'm stuck. I can't proceed until we figure out what in the holy fuck
is going on here. So ... if anyone can help, please do. If we can't fix
this, the GBA emulation is dead.
I was able to profile on Windows, and I've included that in this WIP
under out/log.txt.
But it looks normal to me. But yeah, there's NO. FUCKING. WAY. This code
should be running this slowly.
byuu says:
I wanted to keep this a secret, but unlike other recent additions, this
will easily take several weeks, maybe months, to show anything.
Assuming I can even pull it off. Nothing technically overwhelming here,
I'm more worried about the near-impossibility of debugging the CPU.
byuu says:
Changelog:
- extended USART with quit(), readable(), writable() [both emulation and
hardware]
- quit() returns true on hardware when Ctrl+C (SIGINT) is generated
(breaks main loop); no effect under emulation yet (hard to
simulate)
- readable() returns true when data is ready to be read
(non-blocking support for read())
- writable() returns true when data can be written (non-blocking
support for write()) [always true under emulation, since we have
no buffer size limit]
byuu says:
Changelog:
- fixes ARM core unaligned memory reads (fixes HNMS2 AI, hopefully completely,
we'll see though) [Cydrak]
- ARM 40000010 writes are now connected to d2 rather than the timer
- ARM bus_readbyte() removed (would love to do the same for writebyte if
we can ... then we can drop back to bus_read + bus_write only)
- USART with IObit set acts as a regular gamepad now (don't have this
hooked up with real hardware, but oh well, it's technically possible
so there's that)
- OpenGL/GLX will use 30-bit when you have a 30-bit display; no need for
config file video.depth anymore
byuu says:
This release adds ST018 emulation. As this was the final unsupported
SNES coprocessor, this means that bsnes v087 is the first SNES emulator
to be able to claim 100% known compatibility with all officially
released games. And it does this with absolutely no hacks.
Again, I really have to stress the word known. No emulator is perfect.
No emulator ever really can be perfect for a system of this complexity.
The concept doesn't even really exist, since every SNES behaves subtly
different. What I mean by this, is that every single game ever
officially sold has been tested, and zero bugs (of any severity level)
are currently known.
It is of course extremely likely that bugs will be found in this
release, as well as in future releases. But this will always be
a problem for every emulator ever made: there is no way to test every
possible codepath of every single game to guarantee perfection. I will,
of course, continue to do my best to fix newfound bugs so long as I'm
around.
I'd really like to thank Cydrak and LostTemplar for their assistance in
emulating the ST018. I could not have done it without their help.
The ST018 ROM, like the other coprocessor ROMs, is copyrighted. This
means I am unable to distribute the image.
Changelog (since v086):
- emulated the 21.47MHz ST018 (ARMv3) coprocessor used by Hayazashi
Nidan Morita Shougi 2
- fixed PPU TM/TS edge case; fixes bottom scanline of text boxes in
Moryo Senki Madara 2
- fixed saving and loading of Super Game Boy save RAM
- NEC uPD7725,96050 ROMs now stored in little-endian format for
consistency
- cartridge folder concept has been reworked to use fixed file names
- added emulation of serial USART interface (replaces asynchronous UART
support previously)
byuu says:
Cydrak, I moved the step from the opcode decoder and opcodes themselves
into bus_(read,write)(byte,word), to minimize code.
If that's not feasible for some reason, please let me know and I'll
change it back to your latest WIP.
This has your carry flag fix, the timer skeleton (doesn't really work
yet), the Booth two-bit steps, and the carry flag clear thing inside
multiply ops.
Also added the aforementioned reset delay and reset bit stuff, and fixed
the steps to 21MHz for instructions and 64KHz for reset pulse.
I wasn't sure about the shifter extra cycles. I only saw it inside one
of the four (or was it three?) opcodes that have shifter functions.
Shouldn't it be in all of them?
The game does indeed appear to be fully playable now, but the AI doesn't
exactly match my real cartridge.
This could be for any number of reasons: ARM CPU bug, timer behavior
bug, oscillator differences between my real hardware and the emulator,
etc.
However ... the AI is 100% predictable every time, both under emulation
and on real hardware.
- For the first step, move 九-1 to 八-1.
- The opponent moves 三-3 to 四-3.
- Now move 七-1 to 六-1.
- The opponent moves 二-2 to 八-8.
However, on my real SNES, the opponent moves 一-3 to 二-4.
byuu says:
Most importantly ... I'm now using "st018.rom" which is the program ROM
+ data ROM in one "firmware" file. Since all three Seta DSPs have the
ST01N stamp, unlike some of the arcade variants, I'm just going to go
with ST01N from now on instead of ST-001N. I was using the latter as
that's what Overload called them.
Moving on ...
The memory map should match real hardware now, and I even match the open
bus read results.
I also return the funky 0x40404001 for 60000000-7fffffff, for whatever
that's worth.
The CPU-side registers are also mirrored correctly, as they were in the
last WIP, so we should be good there.
I also simulate the reset pulse now, and a 0->!0 transition of $3804
will destroy the ARM CPU thread.
It will wait until the value is set back to zero to resume execution.
At startup, the ARM CPU will sleep for a while, thus simulating the
reset delay behavior.
Still need to figure out the exact cycle length, but that's really not
important for emulation.
Note in registers.hpp, the |4 in status() is basically what allows the
CPU program to keep going, and hit the checkmate condition.
If we remove that, the CPU deadlocks. Still need to figure out how and
when d4 is set on $3804 reads.
I can run any test program on both real hardware and in my emulator and
compare results, so by all means ... if you can come up with a test,
I'll run it.
byuu says:
Attempted to fix the bugs pointed out by Cydrak for the shifter carry
and subtraction flags. No way to know if I was successful.
The memory map should exactly match real hardware now.
Also simplified bus reading/writing: we can get fancy when it works,
I suppose.
Reduced some of the code repetition to try and minimize the chances for
bugs.
I hopefully fixed up register-based ror shifting to what the docs were
saying.
And lastly, the disassembler should handle every opcode in every mode
now.
ldr rn,[pc,n] adds (pc,n) [absolute address] after opcode. I didn't want
to actually read from ROM here (in case it ever touches I/O or
something), but I suppose we could try anyway.
At startup, it will write out "disassembly.txt" which is a disassembly
of the entire program ROM.
If anyone wants to look for disassembly errors, I'll go ahead and fix
them. Just note that I won't do common substitutions like mov pc,lr ==
ret.
At this point, we can make two moves and then the game tells us that
we've won.
So ... I'm back to thinking the problem is with bugs in the ARM core,
and that our bidirectional communication is strong enough to play the
game.
Although that's not perfect. The game definitely looks at d4 (and
possibly others later), but my hardware tests can't get anything but
d0/d3 set.
byuu says:
That's my best implementation of the shifter carry. It's horribly
inefficient and possibly wrong (especially on ROR by register, but that
doesn't ever appear to be used in this program), but oh well. It's the
best I can do.
Game is basically getting stuck after a board upload and issuing another
command. It's sitting in a loop waiting on $3804.d0 to be set, meaning
the ARM is never writing anything for the CPU to read. There's some
chance that my $3804/r40000000 flags are wrong. Short of guessing
though, I'm not sure how we can get more info on how those work.
... I really can't debug this any better than I have. If no one else
sees anything, then we're going to have to give up and wait for MESS to
create opcode logs for us to compare against.
byuu says:
More ARM work. Can get in-game, and upload the board (0xaa) successfully.
Bug in checkmate command makes the CPU really difficult to defeat :P
byuu says:
Contains the fledgling beginnings of an ARM CPU core, which can execute
the first three and a half instructions of the ST-0018.
It's a start, I guess.
byuu says:
USART improvements. The clock pulse from reading data() drives both
reading and writing.
Also added a usart_init() to bind the initializer functions, so all you
need now is:
extern "C" usartproc void usart_main() { ... }
And inside, you use usart_read(), usart_write(), etc.
So we can add all the new functions we want (eg I'd like to have
usart_readable() to check if data is available) without changing the
entry point signature.
blargg enhanced his Teensy driver to ignore frame error reads, as well.
byuu says:
It is done. bsnes can now emulate sending and receiving data via USART.
As such, the UART code has been removed.
The final UART code can be downloaded here: http://byuu.org/snes/uart/
I won't maintain it going forward, because nobody ever used it, and
USART is superior in every way.
I've also verified both sending and receiving on the real SNES now :D
It's so easy ... a caveman with electrical engineering and computer
programming experience can do it.
byuu says:
USART implements reading and writing, but I don't yet have code to test
SNES reading yet.
So ... obviously I need to do that next.
Went ahead and required nall::function, so the modules will have to be
C++11. I don't see anyone else making these, and it avoids the annoyance
of deducing the correct controller port based on dynamic casting the
active thread.
Apparently a library can have a main() function to no ill effect, so
there's no need for USART_HARDWARE. Same exact code with different flags
will make the binary and the library.
byuu says:
There will probably be a series of small WIPs as I experiment here.
snes/controller/serial is now snes/controller/uart. Asynchronous serial
communications, typically capped at 57,600 baud.
snes/controller/usart is new. It aims to emulate the SNES connected to
a Teensy++ board, and can easily handle 524,288 baud.
And much more importantly, it's synchronous, so there are no timing
issues anymore. Just bit-bang as fast as you can.
Right now, the USART code is just enough for SNES->PC to transfer data
to ... well, nothing yet.
Unless anyone is actually using the UART stuff, I'll be removing it once
the USART is totally up and running.
No sense maintaining code that is 10x slower, more error prone, and used
by nobody.
Note: this is all thanks to blargg being absolutely amazing.
byuu says:
Cart unload save path was using the new game rather than the old game.
Caused by trying to allow a failed cartridge load to not unload the
current game.
But that's so uncommon that it's not worth worrying about. It'll always
unload before trying to load a new game now.
Removed the TM/TS disable speedup, to fix Madara 2's text boxes.
This actually did cause a slight performance penalty on games that
disable layers via TM/TS. Zelda 3 inside Link's house is a good example.
It knocked the FPS from 98.5 to 94.5. So to counter that, I removed
conditionals from tiledata loading and decoding, and used fall through
switches.
This boosted us back to 97.0. The -march=native flag apparently works
better with SB now, so that was added, putting us up to 99.0fps.
So it should be the same speed in the worst case, and slightly faster in
the best case.
Bumped the pre-render time to 68 clocks from 60 clocks. Adjusted sprite
tile fetch time from 22 to 14 to compensate.
This should give us perfectly stable Dai Kaijuu Monogatari 2 battles.
byuu says:
Fixed Super Game Boy RAM saving and loading. It plainly wasn't hooked up
at all. Was apparently hard-coded before it became a multi-emulator.
I also fixed a crashing issue when loading Satellaview-slotted or
Satellaview games without specifying the sub-cart, wasn't setting
has_bsx_slot = true, so the raw memory wasn't being allocated internally
when it wasn't mapped in. Of course a better fix would be to just not
physically map the ranges if the things aren't present. Kind of a lazy
hack to map blank cartridges there, but oh well. Oh, fixed title
displays as well; and did the best I could for now with regards to
multi-file path saving.
byuu says:
The goals for v087 are to have a unified cartridge-folder concept, as
well as a more functional SNES debugger.
Starting with the cartridge folders. What I have so far:
Code:
NES:
- program.rom
- character.rom
- program.ram
- …
SNES:
- program.rom
- program.rtc
- data.rom (SPC7110)
- { dsp1.rom, dsp1b.rom, cx4.rom, … }
- msu1.rom
- track-#.pcm
Game Boy, Game Boy Color:
- program.rom
- program.ram
- program.rtc
Sub-cartridges (BS-X, Sufami Turbo, …) are stored as separate folders
Folder names must be UTF-8 based, with all-lowercase extensions
File names must be all-lowercase
SNES:
- "program.ram" (.srm, .sts)
- "msu1.rom" (name.msu)
- "track-#.pcm" (name-#.pcm)
- "upd96050.ram" -> "name.ram"
- "bsx.ram" (.bss)
- "bsx.psram" (.bsp)
- "serial.so" -> "libserial.so" (broken)
Need:
- Super Game Boy (not even sure how this loads and saves memory, it's
obviously broken)
And I need to think of some way of handling multi-cart loaded games.
Eg Satellaview-slotted and Sufami Turbo. It was { base + slot ( + slot
... } }, but this gets trickier with folders and fixed names.
Actual markup for the NES needs to change as well.
byuu says:
The main focus of this release is Laevateinn, which is the new bsnes
debugger. Unlike previous debuggers, Laevateinn is a standalone
application with its own GUI entirely focused on debugging.
Changelog:
- created ui-debugger target (Laevateinn)
- fixed multitap ports 2-4 [quequotion]
- fixed ui-libsnes target compilation
- fixed a crashing issue with NSS XML markup
- improved cartridge-folder loading support
- NES can now load .fc (headerless NES) or .prg+.chr (split NES) images
- fixed cursor being visible in fullscreen mode when using
Linux/Metacity window manager [ncbncb]
- show normal cursor when using Linux/SDL video driver [ncbncb]
- added menu accelerators
- fixed a bug in performance profile SMP incw/decw instructions
- SNES core can now optionally be built without Game Boy emulation core
- added 2012-02-04 cheats.xml database [mightymo]
byuu says:
Added VRAM viewer (mouse over to get tile# and VRAM address), CPU+SMP
register editors, settings.cfg to cache path+sync audio+mute audio
settings (Windows Vista+ ignore my request for the default folder
because they are fucking stupid, so they always default to your home
folder. I'm going to have to recommend using a batch file to start
laevateinn there. Sorry, blame Microsoft for being fuck-ups),
geometry.cfg to remember where you placed windows and what size you made
them (a bug in Qt prevents me from making some windows fixed-size for
now, but that'll change when I can work around the Qt issue), usage map
invalidation if the ROM was modified after the usage files, that empty
line insertion thing creaothceann wanted on emulation resume, all chips
now synchronize immediately rather than just-in-time, which is important
for a debugger.
Going to postpone the properties viewer until after v086.
So this is pretty much ready for release. Please bug-test. I don't care
so much about little frills like "oh the memory editor window should
default to a little bigger", you can work around that by resizing it.
I care about things like, "VRAM write breakpoints don't work at all."
If we miss any bugs and it gets released, not the end of the world, but
you'll be waiting a while for the next release to address any missed
bugs now.
byuu says:
Changelog:
- follow the Laevateinn topic to get most of it
- also added NMI, IRQ step buttons to CPU debugger
- also added trace masking + trace mask reset
- also added memory export
- cartridge loading is entirely folder-based now
FitzRoy, I'll go ahead and make a second compromise with you for v086:
I'll match the following:
/path/to/SNES.sfc/*.sfc
/path/to/NES.fc/*.prg, *.chr (split format)
/path/to/NES.fc/*.fc (merged format)
/path/to/GB.gb/*.gb
/path/to/GBC.gbc/*.gbc
Condition will be that there can only be one of each file. If there's
more than one, it'll abort. That lets me name my ROMs as
"Game.fc/Game.fc", and you can name yours as "Game.fc/cartridge.prg,
cartridge.chr". Or whatever you want.
We'll just go with that, see what fares out as the most popular, and
then restrict it back to that method.
The folder must have the .fc, etc extension though. That will be how we
avoid false-positive folder matches.
[Editor's note - the Laevateinn topic mentions these changes for
v085r08:
Added SMP/PPU breakpoints, SMP debugger, SMP stepping / tracing,
memory editing on APU-bus / VRAM / OAM / CGRAM, save state menu,
WRAM mirroring on breakpoints, protected MMIO memory regions
(otherwise, viewing $002100 could crash your game.)
Major missing components:
- trace mask
- trace mask clear / usage map clear
- window geometry caching / sizing improvements
- VRAM viewer
- properties viewer
- working memory export button
The rest will most likely appear after v086 is released.
]
byuu says:
Lots of debugger enhancements. Memory editor works for CPU-bus only,
breakpoint editor does nothing yet.
Tracing works, writes to 001-999 files sequentially. Stepping works,
too. But only on the CPU.
Added "privileged", which becomes "public" if DEBUGGER is defined,
"private" otherwise.
Meant so the debugger can stab deeply into the cores for state
manipulation. Interface is guaranteed to be unstable and dependent upon
the accuracy core.
The about screen logo adds 100KB onto the source download (won't affect
regular bsnes binaries), but too bad. I want some visual flair this
time.
byuu says:
Changelog:
- added base/ folder
- base/base.hpp defines the version number for all UI targets, all the
varint-types, and a hook() class for debugger functions (see below)
- fixed compatibility profile compilation
- removed within<> template from the SNES target
- the SNES core can be built without Game Boy support now, if you so
choose (my SNES debugger is not going to support debugging the GBZ80,
sorry.)
- added ui-debugger; not at all useful right now, will be a long while
to get something usable ready
So hook is a class wrapper around nall::function. It allows you to
invoke potentially empty functions (and as such, the return type must
have a trivial constructor.)
It also doesn't actually perform the test+invocation when DEBUGGER
(options=debugger) is not defined. So you should have no overhead in
regular builds.
The core classes now have a subclass with all the debugging hooks, so
you'll see eg:
void CPU::op_step() {
debugger.op_exec(regs.pc);
(this->*opcode_table[op_read()])();
}
Clear what it's doing, clear what it's for. A whole lot less work than
inheriting the whole CPU core and virtualizing the functions we want to
hook.
All the logic for what to do inside these callbacks will be handled by
individual debuggers, so they can have all the functionality they want.
byuu says:
Changelog:
- fixed cursor being visible under Metacity window manager (hopefully
doesn't cause regression with other WMs)
- show normal cursor when using SDL video driver
- added menu accelerators (meh, why not?)
- removed debugvirtual, ChipDebugger and chip/debugger functionality
entirely
- alt/smp disassembler moved up
- fixed alt/smp incw/decw instructions (unsigned->uint16 for internal
variables)
My plan going forward for a debugger is not to hardcode functionality
that causes the 10-15% slowdown right into the emulator itself.
Instead, I'm going to make a callback class, which will be a specialized
version of nall::function:
- can call function even if not assigned (results in no-op, return type
must have a trivial default constructor)
- if compiled without #define DEBUGGER, the entire thing turns into
a huge no-op; and will be eliminated entirely when compiled
- strategically place the functions: cb_step, cb_read, cb_write, etc.
From here, the ui-debugger GUI will bind the callbacks, implement
breakpoint checking, usage table generation, etc itself.
I'll probably have to add some breakout commands to exit the emulation
core prior to a frame event in some cases as well.
I didn't initially want any debugger-related stuff in the base cores,
but the #if debugger sCPUDebugger #else sCPU #endif stuff was already
more of a burden than this will be.
byuu says:
Fixed NSS XML crashing issue.
Improved folder-loading support.
NES can now load game.fc/game.fc, or game.fc/game.prg+game.chr.
Both types should have no iNES header at all.
And both types require an XML file (until we have a built-in database.)
byuu says:
Changelog:
- updated bsnes to use the newest versions of nall and phoenix
- fixed ui-libsnes compilation (testing would be a good idea, especially
the cheat codes. I just copy-pasted that from the regular UI.)
- fixed multitap controllers 2-4 [quequotion]
byuu says:
A new release for the new year.
Changelog:
fixed auto joypad polling edge case; fixes Ys 5 controls
fixed Justifier polling code; Lethal Enforcers should be fully
responsive once again
rewrote SNES S-SMP processor core (~20% code reduction)
fixed Game Boy 8x16 sprite mode; fixed some sprites in Zelda: Link's
Awakening
treat Game Boy HuC1 RAM enable flag as writable flag instead; fixes
Pokemon Card GB
created far faster XML parser; bsnes can now load XML files once again
updated to mightymo's most recent cheat code database
internal color calculations now performed at 30-bits per pixel
gamma slider now acts as fine-tuned gamma ramp option
Linux OpenGL driver will output at 30bpp on capable displays
Linux port defaults to GTK+ now instead of Qt (both are still available)
byuu says:
Okay, everything can now load XML again, including board layouts for all
three systems. New is the ability to load external Game Boy layouts (not
really that useful, but it's there.)
I'd like to aim for a v085 release soon. I've included a binary, so I'd
appreciate testing. I had to redo all of the XML mappings for every
system (I like consistency), so basically the following things need to
be tested:
* load one of every type of game for every system (every NES board type,
* every Game Boy MBC type, every SNES chip and layout type.)
* test cheat codes and the cheat database
* test pixel shaders for OpenGL and Direct3D (sepia for the win)
* test anything else for v085 release
byuu says:
Added the new super-fast XML parser. So far, the shaders, cheat files,
and cheat database have been updated to allow XML mode once again. Which
is sure to please Screwtape =)
So it's down to just the cartridge mapping files now, which are always
a major pain.
I still think BML is better for parsing simplicity, memory usage, disk
size, lack of red tape and speed (but horrendously bad for ease of
creating files manually), but since the base API is identical, there's
no reason not to support both. Especially since the pixel shaders have
kind of taken on a life of their own.
byuu says:
Changelog:
- fixed sprite tile masking for 8x16 mode (fixes Zelda: DX sprites)
- HuC1 flag sets RAM writable, not RAM enable (fixes Pokemon Card)
- removed within<> template, didn't turn out to be all that useful
I would be almost certain no games would break by allowing reads when it
is disabled, no game would rely on that behavior.
I prefer to be overly restrictive. Better to not allow valid behavior
than to allow invalid behavior. The latter is what gives us a dozen
broken SNES translations.
(note: before the post announcing this release, there had been
a discussion of a performance optimisation that made the Super Scope
emulation a lot faster, but caused problems for the Justifier perpheral)
byuu says:
Spent a good two hours trying things to no avail.
I was trying to allow the CPU to run ahead, and sync on accesses to
$4016/4017/4201/4213, but that doesn't work because the controllers have
access to strobe IObit at will.
The codebase is really starting to get difficult to work with. I am
guessing because the days of massive development are long over, and the
code is starting to age.
Jonas' fix works 98% of the time, but there's still a few missed shots
here and there. So that's not going to work either.
So ... I give up. I've disabled the speed hack, so that it works 100% of
the time.
Did the same for the Super Scope: it may not have the same problem, but
I like consistency and don't feel like taking the chance.
This doesn't affect the mouse, since the mouse does not latch the
counters to indicate its X/Y position.
Speed hit is 92->82fps (accuracy profile), but only for Super Scope and
Justifier games.
But ... at least it works now. Slow and working is better than fast and
broken.
I appreciate the help in researching the issue, Jonas and krom.
Also pulled in phoenix/Makefile, which simplifies ui/Makefile.
Linux port defaults to GTK+ now. I can't get QGtkStyle to look good on
Debian.
byuu says:
Fixed the Ys 5 input bug in the auto joypad polling code. Can't
guarantee it's hardware-accurate (I have no way to extensively test it),
but I can guarantee it is closer to being correct now.
Also uses updated version of phoenix.
The justifier input is indeed all fucked up now. Seems like it stops
updating input after firing for a few frames.
I really don't want to debug that code anymore ... anyone want to make
$10 by fixing it? :P
(r02 was not posted to the WIP thread)
byuu says:
Internally, all color is processed with 30-bit precision. The filters
also operate at 30-bit depth.
There's a new config file setting, video.depth, which defaults to 24.
This causes the final output to downsample to 24-bit, as most will
require.
If you set it to 30-bit, the downsampling will not occur, and bsnes will
ask ruby for a 30-bit surface. If you don't have one available, you're
going to get bad colors. Or maybe even a crash with OpenGL.
I don't yet have detection code to make sure you have an appropriate
visual in place.
30-bit mode will really only work if you are running Linux, running Xorg
at Depth 30, use the OpenGL or XShm driver, have an nVidia Quadro or AMD
FireGL card with the official drivers, and have a 30-bit capable
monitor.
Lots of planning and work for very little gain here, but it's nice that
it's finally finished.
Oh, I had to change the contrast/brightness formulas a tiny bit, but
they still work and look nice.
I rewrote the S-SMP processor core (implementation of the 256 opcodes),
utilizing my new 6502-like syntax. It matches what bass v05r01 uses.
Took 10 hours.
Due to being able to group the "mov reg,mem" opcodes together with
"adc/sbc/ora/and/eor/cmp" sets, the total code size was reduced from
55.7KB to 42.5KB for identical accuracy and speed.
I also dropped the trick I was using to pass register variables as
template arguments, and instead just use a switch table to pass them as
function arguments. Makes the table a lot easier to read.
Passes all of my S-SMP tests, and all of blargg's
arithmetic/cycle-timing S-SMP tests. Runs Zelda 3 great as well. Didn't
test further.
This does have the potential to cause some regressions if I've messed
anything up, and none of the above tests caught it, so as always,
testing would be appreciated.
Anyway, yeah. By writing the actual processor with this new mnemonic
set, it confirms the parallels I've made.
My guess is that Sony really did clone the 6502, but was worried about
legal implications or something and changed the mnemonics last-minute.
(Note to self: need to re-enable snes.random before v085 official.)
EDIT: oh yeah, I also commented out the ALSA snd_pcm_drain() inside
term(). Without it, there is a tiny pop when the driver is
re-initialized. But with it, the entire emulator would lock up for five
whole seconds waiting on that call to complete. I'll take the pop any
day over that.
byuu says:
Hiding the viewport is necessary on Windows to prevent it from
overlapping the status bar. I've changed it to set the size to 1,1 when
nothing is loaded.
That still puts a 1x1 pixel over the status bar when you resize the
window to 1xHeight, but ... you know, don't do that.
Also corrected the mask overscan option for NES/SNES.
Silently updated the bsnes_v084-source.tar.bz2 archive with those fixes,
there were only 48 downloads.
byuu says:
This release adds preliminary Game Boy Color emulation. Due to lack of
technical information, this is undoubtedly the least stable module
I provide at this time; but improvements should continue as it is
developed.
This release also polishes the NES emulation and user interface code.
Changelog (since v083):
- added preliminary Game Boy Color emulation
- NES: added MMC6, VRC1, VRC2, VRC3 emulation
- NES: fixed MMC5 banking and added split-screen support [Cydrak]
- NES: pass all of blargg's ppu_vbl_nmi tests, pass more sprite tests
- NES: palette is now generated algorithmically [Bisqwit]
- SNES: fixed SA-1 IRQ regression caused by code refactoring
- Game Boy: rewrote audio channel mixing code; sound output is greatly
improved as a result
- Game Boy: uses DMG boot ROM instead of SGB boot ROM
- Game Boy: fixed potential bug when loading save states
- phoenix: fixed ListView focus issue [X-Fi6]
- phoenix: fixed dialog message parsing [X-Fi6]
- ui: video output is truly 24-bit now; SNES luma=0 edge case emulated
- ui: audio frequency, latency, resampler are now user configurable
- ui: gamma ramp is dynamically adjustable
- ui: all filters ported to 24-bit mode (speed hit to HQ2x)
- ui: added turbo button mappings for all generic controllers
- ui: fixed audio volume on unmute via menu [Ver Greeneyes]
- ui: shrink window option does nothing when no cartridge is loaded
- ui: re-added compositor disable, driver verification from v082
byuu says:
Changelog:
- NES: added VRC1, VRC2, VRC3, MMC6 emulation
- shrink window doesn't do anything when no cartridge is loaded
- phoenix Horizontal,VerticalLayout use const Size& instead of unsigned
width,height [for consistency]
So, all official NES ASICs are supported now. Just need sound output for
MMC5+VRC7 to complete them; and then some board re-arrangement stuff for
VRC2+MMC3.
Note that MMC6 uses the same mapper ID as MMC3, and VRC2 uses the same
ID as VRC4, so you have to make a BML board mapping or toggle which type
is chosen in the source file to use these two chips.
Side note: NES overscan clamping is obviously still assuming 16-bit, as
only half the lines are erased. Need to fix that.
byuu says:
Added frequency, latency, resampler selection to the audio settings
panel (I really only wanted it there for resampler selection ... having
three options matches the driver selection style though, so whatever.)
The linear/hermite sampler will double the framerate when running Game
Boy games, and sounds the same. Same framerate and sound quality on
SNES. But it will cause buzzing in many NES titles.
Also re-added the composition { never, fullscreen, always } modes.
I think that option is clutter, but it's just impossible to get good
audio+video on Windows 7 without it ...
Lastly, HQ2x was ported over, but not very well. I just convert source
pixels from RGB888 to RGB555, and output pixels in the opposite
direction.
Need someone good to port the diff() and blend functions over to RGB888
in a way that's not terribly slow.
byuu says:
Fixed SA-1 IRQ regression for Super Mario RPG
Added turbo B,A to NES+GB; B,A,X,Y to SNES (please don't ask for turbo
L,R; you never use those keys rapidly.)
Re-added video color adjustments, which are now done in full 8-bit
colorspace for more precision
Gamma ramp option is gone. It's now the gamma option, which now only
affects the lower-half of the colors.
A value of 1.0 gives you the original, washed out colors. 1.75 is what
the gamma ramp checkbox used to do (roughly).
The new default is 1.5, which still prevents color washout, but isn't as
overly dark as before.
I wanted to make the core/interface stuff abstract the complexity of
setting up a new C++ class, but it really didn't make anything easier.
It was all one-line stubs to internal functions, and there was just too
many platform-specific things that needed to be captured, so I did away
with that. Made a base class for the ui/interface stuff to get rid of
a lot of switch(mode()) stuff, still a work in progress.
byuu says:
Game Boy: audio should sound a lot better, eg Zelda: DX first opening
scene
Game Boy Color: now uses cothread Processor::frequency to dynamically
clock GB-CPU to 8MHz. Proper OAM DMA and timer speed. Fixes SMT: DC - WB
audio.
Added the break; statements to phoenix/windows/platform message loop
Added audio latency/frequency to config file only
byuu says:
All cores: Video classes have internal->{RGB30,24,16,15} palette
generation support
All cores: video output is now RGB24, all filters except HQ2x were
updated to reflect this (HQ2x will be very hard)
NES: MMC5 CHR mapping fixes (Bandit Kings, RTK2, Uchuu Keibitai SDF)
[Cydrak]
NES: MMC5 vertical split screen support (Uchuu Keibitai SDF) [Cydrak]
Game Boy + Game Boy Color: fixed a potential freezing bug when loading
save states (re-create cothreads on state load; was implied when using
SGB mode.)
Game Boy Color: fixed freezing bug with Zelda: LA opening (SVBK is
readable.)
Game Boy Color: more accurate colors (better than GiiBii, probably worse
than KiGB)
SNES: luminance of zero is no longer pure black, as on real hardware.
This is possible thanks to using RGB888 output now.
The current major problems I'd like to solve:
- Zelda: Link's Awakening music when Link first wakes up in the house is
atrociously bad
- Shin Megami Tensei: Devil Children - White Book (Shiro no Sho) plays
music at 50% speed; yet Black Book (Kuro no Sho) does not ... one of
my favorite games, so it'd be great to fix it
(r04 was not posted to the WIP thread)
byuu says:
NES: passes ppu_sprite_overflow tests 01, 02, 05.
Game Boy: uses DMG BIOS (the one with the slow title scroll) or SGB
BIOS, based upon how you load the game.
Game Boy Color: Everything except the IR port is emulated. I don't have
any plans to allow linking two instances of bsnes. And that's frankly
never going to happen over netplay anyway, due to latency requirements
of the serial/IR ports.
The new DMA stuff is possibly incorrect, my test games don't seem to use
it.
Zelda: DX usually resets or crashes on the intro right before the beach
scene. I'm not sure why. Skip the intro and the game plays fine.
This is the best I can do when the most up-to-date GB/C reference
document is over ten years old and half-assed (pandocs.)
I could really use some help from anyone who understands the system.
Probably the worst part of my emulation at the moment is the interrupt
system.
Lots of things real hardware doesn't allow (DMA outside HRAM, CGB DMA to
invalid addresses, etc) isn't blocked yet.
LCD renderer is still scanline-based, which is just terrible. Doesn't
seem to be any good docs on cycle-level operation. I only know that it's
incredibly pathological and variable.
byuu says:
Lots of phoenix issues fixed, especially for Windows and GTK+.
NES emulation passes all ten ppu_vbl_nmi tests from blargg.
Sprite timing is nowhere near accurate yet (always consumes four clocks
per sprite), but oh well.
byuu says:
This adds Bisqwit's NES palette generation code:
http://nesdev.parodius.com/bbs/viewtopic.php?p=85060#85060
I set the saturation to 2.0 to closer match the existing "bright"
palette, although it still has a greater contrast range (some colors are
darker.) The gamma ramp option works now. Like SNES, best to also set
gamma to 0.8 afterward. Once I think of a good way to expose the
saturation/hue settings, I'll do so.
I've also merged in the updated nall. Adds Cygwin uname check, and
replaces linear_vector with vector in lstring and the GUI.
byuu says:
This release adds preliminary Nintendo / Famicom emulation. It's only
a week or two old, so a lot of work still needs to be done before it can
compete with the most popular NES emulators.
It's important to clarify: bsnes is primarily an SNES emulator. That
will always be its forte and my core focus. I have added Game Boy
support previously for Super Game Boy emulation, and I've added NES
support mostly for something fun to work on to break up the monotony of
working on one system for seven years now. Obviously, I'd like the
emulation to be accurate and highly compatible, but I simply cannot
afford to invest the same amount of time and money into any other
systems.
Still, either way the NES and GB emulation serve as fun side-diversions,
and allow for a unified emulator interface with all of bsnes' unique
features applied to all systems. My personal favorite feature is
mightymo's extended built-in cheat code database that now also includes
NES and Game Boy codes. And it even works in Super Game Boy mode now,
too!
I'm also not worried about speed at all: so long as NES/GB are faster
than SNES/compatibility, it's fine by me. Note that due to the NES audio
running at 1.78MHz, and Game Boy audio at 4MHz stereo, a more
sophisticated audio resampler was needed: Ryphecha (Mednafen author) has
graciously written a first-rate resampler: it is a band-limited
Kaiser-windowed polyphase sinc resampler. It is combined with two
highpass filters to remove DC bias. The filter itself is SSE optimized,
but even still, approximately 50% of CPU usage for NES/GB emulation goes
to the audio filtering alone. However, you now have the best sound
possible for NES and Game Boy emulation as a result.
The GUI has also been heavily re-structured to accommodate multiple
emulators from the same interface. As such, it's quite likely a few bugs
are still lurking here and there. Please report them and I'll iron them
out for the next release.
Changelog:
- license is now GPLv3
- re-structured GUI as a multi-system emulator
- added NES emulation [byuu, Ryphecha]
- added NES ICs: MMC1, MMC2, MMC3, MMC4, MMC5, VRC4, VRC6+audio, VRC7,
Sunsoft-5B+audio, Bandai-LZ93D50
- added NES boards: AxROM, BNROM, CNROM, ExROM, FxROM, GxROM, NROM,
PxROM, SxROM, TxROM, UxROM
- Game Boy emulation improvements [Jonas Quinn]
- SNES core outputs full 19-bit color (4-bit luma included) for more
accurate color reproduction (~5% speed hit)
- audio resampler is now a band-limited polyphase resampler [Ryphecha]
- cheat database includes NES+GB codes as well [mightymo, tukuyomi]
- lots of other changes
byuu says:
Added MMC2, MMC4, VRC4, VRC7 (no audio.)
Split NES audio code up into individual modules.
Fixed libsnes to compile: Themaister, can you please test to make sure
it works? I don't have a libsnes client on my work PC to test it.
Added about / license information to bottom of advanced settings screen
for now (better than nothing, I guess.)
Blocked PPU reads/writes while rendering for now, easier than coming up
with a bus address locking thing :/
I can't seem to fix MMC5 graphics during the intro to Uchuu Keibitai.
Without that, trying to implement vertical-split screen mode doesn't
make sense.
So as far as special audio chips go ...
* VRC6 is completed
* Sunsoft 5B has everything the only game to use it uses, but there are
more unused channels I'd like to support anyway (they aren't
documented, though.)
* MMC5 audio unsupported for now
* VRC7 audio unsupported, probably for a long time (hardest audio driver
of all. More complex than core NES APU.)
* audio PCM games (Moero Pro Yakyuu!) I probably won't ever support
(they require external WAV packs.)
byuu says:
Added delay to MMC1 register writes, to fix Bill & Ted's Godawful
Adventure.
Fixed up MMC5 RAM+fill mode, and added EXRAM mode support (8x8
tiles/attributes.)
Just Breed is fully playable now.
MMC5 is a total pain in the ass, the documentation on it is just
terrible. I basically just tried seven hundred variations until
something worked.
I still need to add MMC5 vertical split screen (for one single game's
attract screen, ugh), and the extra sound channels.
Would like to rework the NES APU first. Since the pulse channels are
identical sans sweep, it'd be nice to just inherit those and mask out
the sweep register bit writes.
So that probably won't make it into the first release, at least.
Still, overall I think it'll be an impressive showing of complex mappers
for a first release: MMC3, MMC5, VRC6 and 5B. The latter two with full
audio. The only other really, really hard bit is the VRC7 audio,
supposedly.
byuu says:
Enable Overscan->Mask Overscan [best I'm doing]
Video settings -> Overscan mask: (horizontal, vertical: 0-16 on each
side) [only works on NES+SNES]
BPS patching works for NES+SNES+GB; note that long-term I want BPS to
only patch headerless PRG+CHR files, but we'll need a database
/ completed board mapping system first.
MMC1 splits the board/chip markups a bit better. My attempts to emulate
the extra CHR bits per hardware fail repeatedly. Docs do not explain how
it works at all.
Emulated enough of the MMC5 to play Castlevania 3.
The MMC5 is easily the most complicated mapper the NES has to offer, and
of course, has the most pitifully vague and difficult documentation of
any mapper around.
It seems the only way anyone is able to emulate this chip is
empirically.
Everyone else apparently hooks the MMC5 right into the PPU core, which
I of course cannot do. So I had to come up with my own (probably wrong)
way to synchronize the PPU simply by observing CHR bus accesses.
I must say, I over-estimated how well fleshed out the NES hardware
documentation was. Shit hits the fan right after MMC3.
It's miles beyond the GB scene, but I find myself wanting for someone
with the technical writing ability of anomie.
I can't find anything at all on how we're supposed to support the $2007
port reads/writes without it extra-clocking the PPU's bus, which could
throw off mapper timing.
Absolutely nothing at all on the subject anywhere, something everybody
is required to do for all cycle-based emulators and ... nada.
Anyway, I'd like to refine the MMC5 a bit, getting Just Breed playable
even without sound would be really nice (it's a fun game.)
Then we need to get libsnes building again (ugh, getting worn out in
backporting changes to it.)
Once v083 is public, we can start discussing a new API for multiple
emulators.
byuu says:
cheats.xml -> cheats.bml, includes NES+SNES+GB codes now. Absolutely
awesome, thanks to mightymo and tukuyomi.
I also added Sunsoft-FME7/5B (with sound) emulation. Really only useful
for playing the Japanese release of Gimmick!
Fun game, but balls to the wall hard.
byuu says:
I doubt anyone is going to like these changes, but oh well.
The base height output for NES+SNES is now always 256x240. The Enable
Overscan option blanks out borders around the screen. This eliminates
the need for an overscan software filter. For NES, it's 16px from the
top and bottom, and 8px from the left and right. Anything less and you
get scrolling artifacts in countless games. For the SNES, it's only 16px
from the top and bottom. Main point is that most NTSC SNES games are
224-height games, so you'll have black borders. Oh well, hack the source
if you want. Game Boy overscan option does nothing.
Everything except for the cheats.xml file now uses BML markup. I need to
write a converter for cheats.xml still. Cut the SNES board parsing code
in half, 30KB->16KB. Much cleaner now.
Took the opportunity to fix a mistake I made back with the XML spec: all
numbers are integers, but can be prefixed with 0x to become hexadecimal.
Before, offset/size values defaulted to hex-mode even without a prefix,
unlike frequency/etc values.
The XML shaders have gone in their own direction anyway, with most being
multi-pass and incompatible with bsnes. So that said, please don't
extend the BML functionality from your end. But f eel free to add to the
XML spec, since other emulators now use that as well. And don't
misunderstand, I love the work that's being done there. It's pretty
awesome to see multi-pass shader capabilities, and the RAM watching
stuff is just amazing.
If there are any really awesome single-pass shaders that people would
like, I can convert it from XML and include it with future releases.
On that topic, I removed the watercolor/hdr-tv ones from the binary
packages (still in the source archive) ... they are neat, but not very
useful for actual gaming.
If we had more than one, I'd remove the Direct3D sepia one. Not going to
use shaders from a certain bipolar manic, because I'd never hear the end
of it if I did :/
Oh, one change I think people will like: MSU1 no longer requires
a memory map specification, so MSU1 authors won't have to keep updating
to my newer revisions of board markups. Basically, if there's not
a board with an msu1 section, it'll check if "gamename.msu" exists. If
it does, MSU1 gets mapped to 00-3f,80-bf:2000-2007. If all you want is
music, make a blank, zero-byte gamename.msu file.
byuu says:
Was mostly working on BML. Still working on the spec.
Added NES-BNROM, NES-GNROM/NES-MHROM boards. I don't even know why. The
latter games do not work very well without Zapper support.
byuu says:
Finished porting over all mappers to board/chip disambiguations. Had to
nearly rewrite the MMC1 code to do it, but all variants should be
supported.
iNES1 is too stupid to express them all, so you'll need a board markup
if you want to play the >8KB PRG RAM games.
For whatever reason, they call VRC6's memory WRAM, and MMC1's PRG RAM.
I am calling them all PRG RAM, since it's the same damn thing.
Board spec is not going to be stable until I have a hell of a lot more
mappers implemented, so be wary of that.
Anyway, at this time, all games can be loaded sans iNES header, if you
have the board markup. I'd also like to have a board database for all
commercial titles.
I'm treating *.fc as PRG-ROM(+CHR-ROM). Will work on loading the split
files later possibly.
byuu says:
.cht files now use BML-formatted data. I'm still going to request the
cheats.xml file as-is, and will write my own converter for embedding
during releases.
This is where parsing 2MB markup files in 10ms is really going to be
nice. Had to use an evil hack before for actually searching for games.
This has the start of the board/chip separation from mappers for NES,
and it has a barebones iNES->board markup converter.
You can specify your own board markup and bypass the need for an iNES
header, so in other words it will load No-Intro style games with
a proper board file.
Long-term, we'll have an internal database for commercial boards, and
probably folder.fc/prg.rom{,chr.rom} loading support.
Since they can't co-exist, the mappers are currently disabled, and I've
only ported the easy ones. So no MMC1/MMC3/VRC6 in this release. I need
to make them into chips first.
byuu says:
Ryphecha fixed Gun Nac, it was some sort of problem with blank sprite
address fetching messing with the MMC3
I've started on an XML parser for iNES-free loading, but it's pretty
barebones right now. Only NROM-256 loads, and you have to make it
a compile-time thing (so other games work for now.)
Updated nall with nullptr stuff.
nall/detect is now nall/intrinsic and has both #defines + static
constants that can be used to detect the platform (allows for run-time
platform checks where practical.)
ruby has a Makefile now, that makes using it in other projects a lot
easier
byuu says:
Upgraded to GCC 4.6.1.
Removed nall/foreach and nall/concept, upgraded iterator support on all
of my containers, and replaced everything with range-for.
Fixed up Qt geometry a good bit, should at least create windows now without bouncing around.
Added some initial nullptr / constexpr changes.
Some other minor cleanups ... removing foreach() took about 6-8 hours
alone.
byuu says:
Ryphecha fixed the FF1 glitch, added two highpass filters to NES audio
output (still working on a lowpass), and fixed VRC6 audio issues.
I reduced the complexity of all eight supported mapping modes, and
standardized them; and added in an overscan filter (not in archive) for
chopping off all the NES edge garbage (8 pixels on the left and right,
16 on the top and bottom.)
It's extreme, but anything less shows junk. I may make this part of the
menu option, just clip off more on NES mode than SNES mode.
byuu says:
Mappers are now optionally threaded.
Fixed up MMC3 emulation, SMB3 and MM3-6 are all fully playable. However,
many unusual variants of this chip are not supported still.
Added UNROM+UOROM for Contra and MM1, allowing all six MM games to play
now.
Added VRC6 with sound emulation, because I wanted to get audio mixing in
place.
Chose VRC6 because it has Esper Dream 2, which is an absolutely amazing
game that everyone should play :D
The game didn't use sawtooth, and I didn't test any other VRC6 games, so
hopefully that is emulated passably well enough.
byuu says:
2-6% speed hit in SNES core for outputting 19-bit (rounded to 32-bit ...
sigh) video, so that luma non-linearity can eventually be emulated
properly.
Now using sinc audio resampler, massive speed hit of course to NES+GB
only, but it's required to get rid of aliasing (buzzing) present in
many, many games otherwise.
Fixed fast forward and none/blur select.
Finally fixed texture clearing for changing pixel shaders and video
filters.
Some realllly basic NES MMC3, extremely broken so don't bug me about it.
Other stuff, probably.
byuu says:
NES now has save state support.
NES A/B buttons were indeed swapped, so that's fixed now.
nall/dsp now puts resamplers into separate classes, so that each can
have their own state information.
opengl.hpp uses GL_RGBA internal format and doesn't regenerate textures
on resize. No speedup, no fix to junk on resize, so I will be very
unhappy if this breaks things for anyone.
GLSL shaders use <fragment filter="nearest/point"> as you guys wanted.
ui-snes was removed.
This was released beside bsnes v082r19. byuu didn't mention it in the
v082r19 release notes, but in a previous post mentioned that a number of
filters stopped working when bsnes switched to using RGB555 for all its
internal data.
byuu says:
This will be the last release with the ui-snes folder (it's broken now
anyway.)
Re-added cheat code database searching + add window. It hashes
NES+SNES+GB images now and will look them up in the database.
Re-added filter support, all filters now output at RGB555. Stacking is
possible, but I don't currently allow it.
Removed mouse capture + test options from tools menu.
Removed smooth video output from settings menu.
There are now two built-in "shaders": "None" (point filtering) and
"Blur" (linear filtering).
OpenGL shaders can now use <shader language="GLSL" filter="point"> (or
"linear") to specify their filtering mode.
Individual emulator versions are gone, and names are hidden from the
GUI: you just see bsnes v082.19 now. A new release bumps all core
versions.
I cannot for the life of me get the video to clear properly when
toggling the shaders. Say you set pixellate2x filter, then turn on
curvature shader, then turn off the filter, you get junk at the bottom
right.
I have tried clearing and flipping the OpenGL surface 64x in a row ...
I don't know where the hell it's getting the data from. If anyone can
make a small patch to fix that, I'd greatly appreciate it.
byuu says:
There we go, the GUI is nearly feature-complete once again.
All cores now output their native video format (NES={emphasis}{palette},
SNES=BGR555, GameBoy={ bright, normal, darker, darkest }), and are
transformed to RGB555 data that is passed to the video renderer.
The video renderer then uses its internal palette to apply
brightness/contrast/gamma/ramp adjustments and outputs in RGB888 color
space.
This does add in another rendering pass, unfortunately, but it's
a necessary one for universal support.
The plan is to adapt all filters to take RGB555 input, and output RGB555
data as well. By doing this, it will be possible to stack filters.
However, it's a bit complicated: I need to plan how the stacking should
occur (eg we never want to apply scanlines before HQ2x, etc.)
Added input frequency adjustments for all three systems. I can easily
get perfect video/audio sync on all three now, hooray.
Long-term, it seems like we only really need one, and we can do
a video/audio delta to get an adjusted value. But for now, this gets the
job done.
Added audio volume adjust. I left out the balance for now, since it's
obviously impossible to balance the NES' single channel audio (I can
duplicate the channel, and do twice the filtering work, but ... why?)
I replaced NTSC/PAL TV mode selection with an "Enable Overscan"
checkbox. On, you get 240 lines on NES+SNES. Off, you get 224 lines on
NES+SNES.
Also added aspect correction box back. I don't do that gross PAL
distortion shit anymore, sorry PAL people. I just scale up the
54/47*(240/224) aspect correction for overscan off mode.
All memory is loaded and saved now, for all three systems (hooray, now
you can actually play Zelda 1&2.)
Added all of the old bsnes hotkeys, with the exception of capture
screenshot. May add again later. May come up with something a bit
different for extra features.
Re-added the NSS DIP switch setting window. Since geometry is saved,
I didn't want to auto-hide rows, so now you'll see all eight possible
DIPs, and the ones not used are grayed out.
Ultimately, nobody will notice since we only have DIPs for ActRaiser
NSS, and nobody's probably even using the XML file for that anyway.
Whatever, it's nice to have anyway.
Took FitzRoy's advice and single-item combo boxes on the input selection
are disabled, so the user doesn't waste time checking them.
I wanted to leave text so that you know there's not a problem. Qt
disabled radio box items look almost exactly like enabled ones.
Fixed lots of issues in phoenix and extended it a bit. But I was still
having trouble with radio box grouping, so I said fuck it and made the
panels show/hide based instead of append/remove based.
That's all for stuff off the checklist, I did a bunch of other things
I don't recall.
So yeah, I'd say the GUI is 100% usable now. This is my opinion on how
multi-platform GUIs should be done =)
Oh, I figure I should mention, but the NES core is GPLv3, and all future
SNES+GB releases will be as well. It's a move against Microsoft's Metro
store.
byuu says:
Adds BS-X/Slotted/SufamiTurbo/SGB cartridge loading. Calling it
Satellaview as I'm more partial to that at the moment.
FileBrowser now remembers your folders per filter type like before, and
will keep your place in the list if you don't switch away.
I wanted there to be ONE slot loader, so the loader will show a grayed
out secondary slot on non-ST loading, but it's more consistent to only
have one window instead of two for geometry placement.
Removed help menu. Will try and work it in somewhere unobtrusive later
on I suppose.
Added timed messages and the usual "no cart loaded / paused" messages
and such.
byuu says:
Binary output is once again called bsnes. No versioning on the title
without a system cartridge loaded. Still saving config files to
.config/batch for now.
Finally fixed NES APU frame IRQ clearing on $4015 reads.
Added mouse button/axis binding through buttons on the input capture
window.
Added advanced settings window with driver selection and focus policy
settings. Will show your default driver properly if none are selected
now, unlike old bsnes.
That exposed a small bug where phoenix isn't removing widgets on
Layout::remove, worked around it for now by hiding the panels. Damn,
sick of working on phoenix.
Added all missing input controllers, which can all now be mapped, and
bound them to the main menu, and added NES support for selecting "no
connected controller."
Added mouse capture and the requisite tools menu option for it.
Added WindowManager class that keeps track of both position and size now
(eg full geometry), so now you can resize your windows and save the
settings, unlike old bsnes.
WindowManager has more stringent geometry checks. The *client area* (not
the window border) can't be below 0,0 or above the width/height of three
30" monitors. If you have 4+ 30" monitors, then fuck you :P
settings.cfg is now also saved, captures all currently available
settings. Right now, there's only one path for the file browser to
remember. I will probably make this per-system later.
FileBrowser has been made a bit more friendly. The bottom left tells you
what type of files the list is filtered by (so you see "*.sfc" for
SNES), and the bottom right has an open button that can enter folders or
load files.
Added video shader support.
Fixed nall/dsp variadic-channel support, was only outputting the left
channel.
byuu says:
7.5 hours of power coding. Das Keyboard definitely helped (but didn't
eliminate) RSI, neato.
Okay, the NES resampler was using 315 / 88.8 by mistake, so the output
rate was wrong, causing way more video/audio stuttering than necessary.
STILL forgot the NES APU frame IRQ clear thing on $4015 reads, blah. Why
do I always remember things right after uploading the WIPs?
Recreated the input manager with a new design, works much nicer than the
old one, a whole lot less duplicated code.
Recreated the input settings window to work with the new multi-system
emulation.
All input settings are saved to their own configuration file, input.cfg.
Going to batch folder for now.
Okay, so the new input settings window ... basically there are now three
drop-downs, and I'm not even trying to label them anymore.
They are primary, secondary, tertiary selectors for the listed group
below. Examples:
"NES -> Controller Port 1 -> Gamepad"
"SNES -> Controller Port 2 -> Super Scope"
"User Interface -> Hotkeys -> Save States"
I am aware that "Clear" gets disabled when assigning. I will work on
that later, being lazy for now and disabling the entire window. Have to
add the mouse binders back, too.
Escape and modifiers are both mappable as individual keys now. If you
want to clear, click the damn clear button :P
Oh, and all input goes to all windows for now. That'll be fixed too when
input focus stuff is re-added.
byuu says:
Emulates DMC channel (sound effect when Link gets hit in Zelda 1, for
instance), fixes up bugs in rectangle/sweep and triangle channels, adds
DMC/frame APU IRQs, adds proper stalling for DMC ROM reads (should even
be cycle accurate, but has one extra cycle when triggered during OAM
DMA, I think), but forgets the frame IRQ acknowledge clear on $4015 read
(will fix next WIP.) All sound courtesy of Ryphecha.
Made template configuration settings window (empty for now.) Simplified
SNES cheat.cpp code. Some other stuff.
Further developed RSI.
byuu says:
I've updated the {System}::Interface classes to encapsulate all common
functionality, so they are C++ equivalents of libsnes now.
The idea being, use the interface class and you'll never have to reach
into core objects (unless you really want to.)
Not guaranteeing as stable an API as I do with libsnes for that, though.
C++ doesn't make for nice dynamic libraries, anyway.
Added back the state manager, and it now works for both SNES and Game
Boy. NES save states aren't in yet.
Anyway, this should give you a pretty good feel for what the combined UI
is going to be like: same as before, everything works the same. Only
difference is the dynamic system menu and cartridge menu with more load
options. The settings window will be mostly the same as well, but will
obviously have options that only apply to some systems.
byuu says:
Merged Ryphecha's APU emulation, so NES has sound output now. We are
still missing the DMC memory fetch, so there will be missing sound
effects here and there.
byuu says:
Emulated the Game Genie for the NES and Game Boy, and wrote a new cheat
editor that doesn't reach into specific emulation cores so that it would
work.
Before you ask: yes, long-term I'd like Super Game Boy mode to accept
Game Boy codes. But that's not high on the priority list.
Renamed the mappers toward board names, LZ...->BandaiFCG,
LS161...->AOROM, added CNROM emulation (Adventure Island, Gradius, etc.)
Added the tools menu load/save state stuff, but note that the NES
doesn't have save state support yet (waiting for the interface to
stabilize a bit more first.)
Note: this will be the last release to have the ui-gameboy folder, it's
been deleted locally from my end, as the new multi-GUI does all that it
does and more now.
byuu says:
Fixed up the PPU to be as close to cycle-perfect as possible. Fixed RMW
to write twice instead of read twice. Ryphecha added AOROM and fixed up
MMC1. Have CNROM too, but I need to rethink the mapper/board
distinction. Apparently the same logic IC is used in both AOROM and
CNROM, and it's just a matter of routing the pins to it. I need to
consider how crazy it'd be to emulate the logic IC and have boards
simply reroute pins to it. If it's too much work, we'll just treat
mappers as board + logic IC combinations. We'll see.
byuu says:
Emulated MMC1, currently defaults to B2 configuration. Fixed a whole
bunch of timing things, render things, nametable mirroring things, etc.
Zelda and Mega Man II are fully playable, but they have odd vertical
scrolling issues that make it a not so fun experience.
Not sure what the problem is there, yet. The Y scroll register writes
seem to be wonky ... I don't know.
Keeping the Cartridge menu always visible now, so it's faster to load
carts, but I am still hiding the non-loaded system menus.
byuu says:
Okay, I fixed up many outstanding phoenix issues.
* Windows/GTK+ fixed by using processEvents instead of main(); Windows can run unthrottled, and GTK+ shows the window contents now
* fixed keyboard beeping once and for all on Windows: I now whitelist tabbable controls
* fixed main menubar setVisible calls
* Qt and GTK+ now allow you to resize windows smaller than they initially were
Both Qt and GTK+ still fuck up the geometry a bit when toggling fullscreen mode. I have tried, and tried, and tried and tried and tried to fix it all. Nothing works. I give up.
Easier to destroy and recreate the fucking window than figure out how to resize it on Linux (and no, I can't do that. ruby would not like the handle changing.)
As for the GUI:
* file browser is back in, still need remember place and open folder code; that needs to be extended to handle multiple systems now
* shrink window command added to tools menu.
byuu says:
So, here's the deal. I now have three emulators. I don't think the
NES/GB ones are at all useful, but I do want them to be eventually. And
having them have those pathetic little GUIs like ui-gameboy, and keeping
everything in separate project folders, just doesn't work well for me.
I kind of "got around" the issue with the Game Boy, by only allowing SGB
mode emulation. But there is no "Super Nintendo" ... er ... wait ...
uhmm ... well, you know what I mean anyway.
So, my idea is to write a multi-emulator GUI, and keep the projects
together. The GUI is not going to change much. The way I envision this
working:
At startup, you have a menubar with: "Cartridge, Settings, Tools, Help".
Cartridge has "Load NES Cartridge", "Load SNES Cartridge", etc.
When you load something, Cartridge is replaced with the appropriate
system menu, eg "SNES". Here you have all your regular items: "power,
reset, controller port selection, etc." There is also a new "Unload
Cartridge" option, which is how you restore the "Cartridge" menu again.
I have no plans to emulate any other systems, but if I ever do emulate
something that doesn't take cartridges, I'll change the name to just
"Load" or something.
The cheat editor / state manager will look and act exactly the same. The
settings panel will look exactly the same. I'll simply show/hide
system-specific options as needed, like NES/SNES aspect ratio
correction, etc. The input mapping window will just have settings for
the currently loaded system. Video and audio tweaking will apply
cross-system, as will hotkey mapping.
The GUI stuff is mostly copy-paste, so it should only take me a week to
get it 95% back to where it was, so don't worry, this isn't total GUI
rewrite #80.
I am, however, making all the objects pointers, so that I can destruct
them all prior to main() returning, which is certainly one way of fixing
that annoying Windows/Qt crash.
Please only test on Linux. The Windows port is broken to hell, and will
give you a bad impression of the idea:
- menu groups are not hiding for some reason (all groups are showing, it
looks hideous)
- Timer interval(0) is taking 16ms per call, capping the FPS to ~64 tops
[FWIW, bsnes/accuracy gets 130fps, bgameboy gets 450fps, bnes gets
800fps; all run at lowest possible granularity]
- the OS keeps beeping when you press keys (AGAIN)
Of course, Qt and GTK+ don't let you shrink a window from the requested
geometry size, because they suck. So the video scaling stuff doesn't
work all that great yet.
Man, a metric fuckton of things need to be fixed in phoenix, and
I really don't know how to fix any of them :/
byuu says:
Couple more fixes to audio from Jonas, and I converted all types from
"unsigned" to the smallest sizes possible, which simplified a bit of the
code. Love variable-length integers.
Audio core should be really good now. Not perfect, but pretty close for
99% of games. Also fixed the window stuff for Cool World and such.
byuu says:
Has Jonas Quinn's many Game Boy APU fixes, and two more from blargg's
notes that I added.
It also has the new dynamic phoenix. So yeah, it'll crash on bsnes/Qt
exit. If anyone can fix it *properly* and wants the money, I'll pay them
$20 for the trouble =)
byuu says:
Changelog:
- if config file window coordinates are >= 30000, it snaps them back to
128,128; should end the "why aren't windows visible?" posts
- updated GUI code to match new phoenix changes
- phoenix: Layout and Widget inherit from Sizable; directional layouts
make no distinction between widgets and layouts
- phoenix: individual widgets / layout can maintain visible/hidden
status in spite of their parents' visibility
byuu says:
This release features many substantial Game Boy emulation improvements
(all courtesy of Jonas Quinn), a new audio DSP class, and BPS patching
support.
Changelog (since v081):
- added new DSP audio engine; supports sample-averaging for the Game
Boy's high frequency rate
- GB: MMM01 images with boot loader at bottom of ROM can now be loaded
- GB: EI is delayed one cycle; fixes Bubble Bobble [Jonas Quinn]
- GB: fixed window -7 offset behavior; fixes Contra 3 first boss [Jonas
Quinn]
- GB: disable LCD interrupts when rendering is off; fixes Super Mario
Land 2 [Jonas Quinn]
- GB: fixed noise channel LFSR; fixes Zelda: LA lightning sound [Jonas
Quinn]
- GB: square channels use initial_length like the noise channel [Jonas
Quinn]
- UI: added BPS patching support; removed UPS patching support
- UI: when loading BS-X/Sufami Turbo/Game Boy games; display game title
instead of BIOS title
- UI: modified timestamps on screenshots for Windows/NTFS (which
disallows use of ':')
byuu says:
- GB: square channels cache initial_length and invert the length value
on writes [Jonas Quinn]
- GB: updated LCD disable to just ignore interrupts and pixel writes,
fixes Contra
- BPS patch information and cartridge sections are now copied from the
patch metadata, if it is present
- fixed bpslinear out-of-bounds issue, which will be in snespurify v11
official [Danish]
- simplified Makefile again since command-line trumps manual assignments
byuu says:
- GameBoy: fixed window behavior for Contra 3 first boss [Jonas Quinn]
- GameBoy: fixed noise channel for Zelda: LA intro [Jonas Quinn]
- GameBoy: completely disable LCD when turned off, no interrupts; fixes
Super Mario Land 2 [thanks to Jonas Quinn]
- GameBoy: keep track of where pixels come from for OBJ priority mode
[Jonas Quinn]
- updated mode+slot-dependent name handling: simplifies Path class,
allows SGB/BSX/ST games to show the slot title (instead of BIOS name)
on the title bar
- Makefile allows command-line definitions for ui and profile now (make
profile=compatibility ui=ui-libsnes)
- Makefile now allows (make pgo=instrument) and (make pgo=optimize)
- added BPS patching support, removed UPS patching support
byuu says:
This release adds nall/dsp, which is a new framework for audio DSP
effects. It currently supports the usual fractional hermite resampling
and volume adjustments from ruby; but it also adds balance, and
arbitrary precision input and output (still limited to two channels, and
still signed audio [just subtract 1<<(bits-1) from an unsigned value.])
Internally, all samples are converted to doubles in the range of -1.0 to
+1.0, to allow for far greater precision with the hermite resampler and
volume/balance/etc adjustments.
As a result of this, all of the extra resampling/volume code from
ruby::audio has been removed. bsnes pulls in a copy of nall::dsp to
handle that stuff now.
byuu says:
- EI takes an extra cycle to raise IME; fixes Bubble Bobble [for the
Gameboy], and likely many more games [Jonas Quinn]
- nall/gameboy/cartridge.hpp descrambles MMM01 images (header can be at
top or bottom of image now)
- screenshot timestamps use filename-yyyy-mm-dd hh.mm.ss.bmp format; so
that they can save on Windows
- closing the emulator will switch to windowed mode first, so that
geometry is preserved
byuu says:
This release polishes up the GUI, adds some more features, and fixes
a few minor issues.
Changelog (since v080):
- rewrote S-DD1 module to decompress individual bytes at a time
- simplified SPC7110 deinterleaving code
- OBC1 should not clear RAM on reset [Jonas Quinn]
- fixed enum-cast compilation errors with the latest GCC 4.6.x releases
- added bsnes logo to about screen
- make phoenix=gtk will now build the GTK+ port on Linux
- added settings.startFullScreen to the config file for front-end users
- added advanced settings option to disable window compositor (only
works on Windows and Xfce)
- merged settings windows into the panel approach used by bsnes/Qt in
the past
- fixed a crashing bug on input settings window
- fixed GTK+ auto-geometry sizing
- added screenshot capture capability
- added exit emulator hotkey (defaults to being unmapped)
- Xorg keyboard polling now uses cached Display variable [Bisqwit]
- cheat code database updated [mightymo]
byuu says, in a post between the v080r07 release and the v080r08
release:
phoenix/Windows:
The slider and scrollbar setParent calls setLength+setPosition, but
setLength sets position = 0 (due to new length possibly invalidating
previous position.)
Cache position first to fix this, can now reparent widgets with proper
slider/scroll positions.
ListView had a workaround where the horizontal scrollbar was always
appearing on single-column lists. The workaround was forcing the config
settings list in bsnes to only select the text portions of each item in
the list, instead of the entire lines. The workaround was needed because
without setting a single header text, the header text count was equal to
zero, causing autoSizeColumns to have no effect. Made the constructor
call setHeaderText("") to guarantee size() >= 1 always. Removes the need
for the workaround, and gives a good file browser and configuration
setting window.
phoenix/Qt:
Worked around Qt bugs #258,674+258,675: if you click a list item with
your mouse, currentItem()->isSelected() returns false. It does not
return true until you select an item with a keyboard key. I forced it to
set the selected item upon currentItemChanged() message. It was also not
sending a changed message upon clearing the selection and then selecting
the same item again. I had to do something undocumented:
setCurrentItem(nullptr) so that currentItemChanged works again.
phoenix/All:
Fonts are now initialized to the platform default settings, Tahoma or
Sans 8-point. This lets geometry on widgets not attached to windows work
better. Makes the ../... buttons smaller pretty much everywhere.
byuu says, announcing the v080r08 release:
Fixed all of the above phoenix issues, and improved the auto-disabling
of buttons on the input setting and state manager windows.
Also manually initiailized lastConfigure for Valgrind in GTK+. Windows
and GTK+ ports look a lot nicer now.
byuu says:
- fixed a long-standing crash: when you have a device index above the
range permitted by another port, the app would crash (eg Controller
Port 2 -> Mouse, then switch to Hotkeys)
- Qt bug workaround: have to use currentItemChanged signal instead of
itemSelectionChanged signal for QTreeWidget, otherwise scrolling with
mouse gives you the previous item with currentItem() ...
- added support for toggling the Xfce compositor
- added support for detecting if the compositor is enabled in the first
place on Windows, so that it won't get turned on when you had it off
permanently
- added advanced setting to toggle behavior (never disable, disable only
in fullscreen mode, disable whenever emulator is open)
- worked around GTK+ ../... button height issue
- worked around Windows slider position issue when attaching to a new
window (need to research this one more)
- fixed up input settings window more: closing window ends assignment,
custom mapping buttons hidden by default
Some of those bugs have been there since the phoenix port began, good
times.
byuu says:
Ran out of time, so this is incomplete, but ...
Windows will disable the compositor in fullscreen mode, and enable it
when switching back to windowed mode. Should help with Vsync issues, but
of course only in fullscreen mode.
I've also merged the four settings windows back into a panel with a list
view (since I have no tab control widget.) The input settings window is
a bit incomplete, need to break assignment on window close, hide the
capture buttons on first showing, etc. Will probably try and finish that
up tonight.
byuu says:
Includes updated versions of nall and phoenix, which mostly improves the
GTK+ version. However, it appears to be crashing at the moment after
loading a game. Unfortunately it works when gdb is used, so I can't
easily debug it :/
You can now build with make phoenix=gtk if you want the GTK+ version on
Linux (the Qt version is leagues better even on Gnome, please use it if
at all possible.)
There's also settings.startFullScreen, config-file only, to allow for
front-end use. Forgot to add the reset/power hotkeys.
I also fixed compilation of ui-gameboy on GCC 4.6. I hope that's the
last switch(enum) error, those are damn annoying. Can't wait to switch
to GCC 4.6 on Windows.
byuu says:
Adds nall/inflate.hpp and nall/unzip.hpp. Updates nall/resource.hpp to
encode and decode using ZIP/deflate files, rather than a much simpler
(and less powerful) LZSS implementation. Cuts the bsnes-logo.hpp file
from 270KB to 130KB, and the binary overhead from 80KB to 35KB.
byuu says:
Wow, nothing in 19 days. Anyway, I wanted to get Nick's logo back in on
the about screen. Adds 80kb to both the binary and source archive, but
eh. Gotta have some style. Nothing else new.
byuu says:
- added qstrlower and qstrupper; mainly for the sake of others wanting
to patch bass
- added: string sha256(const uint8_t *data, unsigned size); for easier
hash generation
- cleaned up the NEC DSP and Hitachi DSP XML mapping code; they are
consistent now as well
- "necdsp" in paths.cfg is now "firmware", since it also affects the
Hitachi DSP
- XML mapping was using program= for DSP-n/ST-001n and data= for Cx4;
they both use firmware= now instead
- fixed icd2/interface casting issue for GCC 4.6.0 (thanks for the
reminder, vEX)
- removed the last parts of code that used string << foo; and removed
that from nall/string entirely
- I need to do this for the debugger as well, I'll make sure that it
compiles before v081 though
- converted all string(...) syntax to { ... } syntax that I could
(obviously it won't cast to a function that takes const char* instead
of const string&)
Probably some other tiny things. Just basic maintenance here.
byuu says:
There was one unfortunate aspect of the S-DD1 module: you had to give it
the DMA length and a target buffer, and it would do the entire
decompression at once. Real hardware would work by streaming the data
byte by byte. So with that, I went ahead and rewrote the code to handle
byte-based streaming.
This WIP is an important milestone for me personally. Up until now,
bsnes has always had code that was directly copy-pasted from other
authors. With all of the DSP and Cx4 chips rewritten in LLE, and the
SPC7110 algorithm already ported over from C, and archive decompression
code removed for a long time, the S-DD1 was the only module left like
this. It's obviously not that big of a deal. The code is basically still
a copy of the original. S-DD1 decomp from Andreas Naive, SPC7110 decomp
from neviksti, and S-DSP from blargg. And the rest of the emulator is of
course only possible because of code and research before it, although
everything else has no resemblance at all to code before it. The main
advantage, really, is absolute code consistency. I always use the same
variant of K&R, for instance. I dunno, I guess I just never really liked
the "Build-a-Bear Workshop" style of emulators, like is so prominent in
the Genesis scene: "My new Genesis emu (uses Starscream/Musashi 68K
core, Marat Fayzullin's Z80 core, YM2612 core from Game_Music_Emu, VDP
core from Gens, SVP core from picodrive)", sorry, but you wrote
a front-end, not an emulator :/
I also updated the SPC7110 decompression module: I merged the class
inside the SPC7110 class (not sure why it was separate before), and
replaced the morton lookup tables with for-loops. The morton tables were
added to be a tiny bit faster when I was more interested in speed than
code clarity. It may be a tiny bit slower (or faster due to less L2
cache usage), but you won't even notice an FPS drop, and it cuts out
a good chunk of code and some tables. Lastly, I added pinput_poll() to
video_refresh(). Forgot to remove Interface::input_poll() from the C++
side, will have to do that later.
byuu says:
This release adds low-level emulation of the Hitachi HG51B169 DSP, which
was used in Mega Man X2 and Mega Man X3 as the Cx4 chip. It also fixes
a regression in both the sound core and cheat engine.
You will now need the HG51B169 data ROM to play MMX2/MMX3.
Once again, Cx4 LLE could not have been possible without the help of Dr.
Decapitator, Jonas Quinn, Overload and Segher. Be sure to thank them,
please!
Changelog:
* added Cx4 low-level emulation; removed Cx4 high-level emulation code
* fixed S-SMP synchronization to S-CPU on CPUIO writes
* controllers now have their own threads and classes
* serial controller is now emulated as an actual controller, rather than
as a coprocessor
* added link coprocessor module for special chip research and homebrew
* fixed cheat codes that target mask ROM addresses [Cydrak]
* fixed compilation error with the latest GCC 4.6.0 beta releases
* added flexibility to XML memory mapping file format
* updated to mightymo's latest cheat pack (2011-06-20)
byuu says:
It does add some more code to the CPU::step() function, so performance
probably went down actually, by about 1%. Removing the input.tick() call
didn't compensate as much as I'd hoped.
Hooked up Super Scope and Justifier support. The good news is that the
Justifier alignment doesn't get fucked up anymore when you go
off-screen. Never could fix that in the old version.
The bad news is that it takes a major speed hit for the time being.
I need to figure out how to run the CPU and input threads out of order.
Every time I try, the input gets thrown off by most of a scanline.
Right now, I'm forced to sync constantly to get the latching position
really accurate. But worst case, I can cut the syncs down by skipping
large chunks around the cursor position, +/-40 clock cycles. So it's
only temporarily slow.
Lastly, killed the old Input class, merged Controllers class into it.
I actually like Controllers as a name better, but it doesn't jive with
video/audio/input, so oh well.
byuu says:
- Fixed GCC-4.6 casting errors in ui/input/input.cpp.
- Fixed some of the opcode mnemonics specified in the HG51B169 core (was
unable to speed up the code)
- Started on a new core input system: snes/controller. More on that
here:
http://board.byuu.org/viewtopic.php?f=16&t=1761
- Have not yet attempted to add threading support to the controllers, so
serial is still there as a coprocessor.
- I'm going to move the Controllers {} class back to Input {} once all
individual controllers have been ported over.
Note: Super Scope and Justifier do not have counter latching support
yet, so you can't really use them. The gamepad, multitap and mouse all
work great; and the SS/Justifier cursors work at least. I also colored
the SS cursor red, so that all three (SS, Justifier, chained secondary
Justifier) all have unique R/G/B colors now. Should prevent confusion
between the SS and one Justifier.
byuu says:
Back from vacation. We were successful in emulating the Cx4 using LLE
during my vacation. We finished on June 15th. And now that I'm back,
I've rewritten the code and merged it into bsnes official. With that,
the very last HLE emulation code in bsnes has now been purged.
[...]
The emulation is as minimal as possible. If I don't see an opcode or
feature actually used, I don't implement it. The one exception being
that I do support the vector override functionality. And there are also
dummy handlers for ld ?,$2e + loop, so that the chip won't stall out.
But things like "byte 4" on rdram/wrram, the two-bit destination
selections for all but ld, etc are treated as invalid opcodes, since we
aren't 100% sure if they are there and work as we hypothesize. I also
only map in known registers into the 256-entry register list. This
leaves 90% of the map empty.
The chip runs at 20MHz, and it will disable the ROM while running. DMA
does transfer one byte at a time against the clock and also locks out
the ROM. rdbus won't fetch from IRAM, only from ROM. DMA transfer only
reads from ROM, and only writes to RAM. Unless someone verifies that
they can do more, I'll leave it that way. I don't yet actually buffer
the program ROM into the internal program RAM just yet, but that is on
the to-do list. We aren't entirely sure how that works either, but my
plan is to just lock the Cx4 CPU and load in 512-bytes.
There's still a few unknown registers in $7f40-5f that I don't do
anything with yet. The secondary chip disable is going to be the
weirdest one, since MMX3 only has one chip. I'd really rather not have
to specify the ROM mapping as two separate chips on MMX2 and as one on
MMX3 just to support this, so I don't know yet.
Save state support is of course there already.
Speed hit is 118fps HLE -> 109fps LLE in most scenes. Not bad, honestly.
byuu says:
This fixes the S-SMP synchronization on CPUIO writes that was broken by
improvements in v078.01. Terranigma will work now. Also adds the 'link'
coprocessor module that was added in v079.01, and improved in v079.02.
byuu says:
Added "unsigned link_run();" which acts as its own thread synchronized
against the S-CPU. Specify the frequency in the configuration file.
I intend to prototype the Cx4 LLE openly using the link module, and that
required timing support, so there we go.
It's very basic, and it synchronizes the CPU to the coprocessors and
vice versa after every call to link_run(). Meaning performance won't be
super exceptional at full 21MHz or higher, but then this is for
prototyping only. I didn't want to expose cothreading, yielding, calls
back into bsnes' core, calls to sync up the S-CPU, etc.
This version adds a "link" SNES coprocessor module, which just loads
a shared library. It was posted outside the v079 WIP thread, in this
thread:
http://board.byuu.org/viewtopic.php?f=16&t=1700
byuu says:
This release includes Nintendo Super System DIP switch emulation and
improved PPU rendering accuracy, among other things.
Changelog:
- added Nintendo Super System DIP switch emulation [requires XML setting
maps]
- emulated Super Game Boy $6001 VRAM offset selection port [ikari_01]
- fixed randomness initialization of S-SMP port registers [fixes
DBZ:Hyper Dimension and Ninja Warriors]
- mosaic V-countdown caches BGOFS registers (fixes Super Turrican
2 effect) [reported by zal16]
- non-mosaic BGOFS registers are always cached at H=60 (fixes NHL '94
and Super Mario World flickering)
- fixed 2xSaI family of renderers on 64-bit systems
- cleaned up SMP source code
- phoenix: fixed a bug when closing bsnes while minimized
Please note that the mosaic BGOFS fix is only for the accuracy profile.
Unfortunately the older scanline-based compatibility renderer's code is
nearly unmaintainable at this point, so I haven't yet been able to
backport the fixes.
Also, I have written a new cycle-accurate SMP core that does not use
libco. The aim is to implement it into Snes9X v1.54. But it would of
course be prudent to test the new core first.
[...then in the next post...]
Decided to keep that Super Mario World part a surprise, so ... surprise!
Realized while working on the Super Turrican 2 mosaic fix, and from
looking at NHL '94 and Dai Kaijuu Monogatari 2's behavior, that BGOFS
registers must be cached between H=0 and H=88 for the entire scanline
... they can't work otherwise, and it'd be stupid for the PPU to re-add
the offset to the position on every pixel anyway. I chose H=60 for now.
Once I am set up with the RGB monitor and the North American cartridge
dumping is completed, I'll set it on getting exact timings for all these
things. It'll probably require a smallish speed hit to allow exact-cycle
timing events for everything in the PPU.
byuu says:
Would appreciate testing on any games with mosaic, especially Mode7
mosaic.I have tested Super Turrican 2, Sim Earth, Contra III and SNES
Test Program.
This only applies to BG modes 0-6, and technically should not affect
Mode7 at all. I am not sure if Mode7 needs the same change made or not,
but given the way it fetches that could prove quite challenging. I also
simplified the background renderer a good bit. See eg the pixel copy
stuff in Background::run().
I've only fixed this in the accuracy renderer. I'm sorry, but the
compatibility renderer is a fucking mess. I haven't really touched it in
four or five years now.
Will probably just revert to the accuracy/SMP in the performance profile
for the next release since it's not being used otherwise. People can
toggle it on if they want to try it out.
byuu says:
This adds ikari_01's emulation of the ICD2 (Super Game Boy) $6001 register.
It basically removes a really ugly hack where I was intercepting the DMA
transfer destination address to determine while Game Boy tile row to
transfer. This should make implementing SGB emulation in other
emulators easier, as said hooks were very emulator-specific.
byuu says:
This WIP adds Nintendo Super System emulation, at least of its DIP
switches. This is done via XML mapping, like so:
<?xml version="1.0" encoding="UTF-8"?>
<cartridge region="NTSC">
<name>ActRaiser</name>
<rom>
<map mode="linear" address="00-7f:8000-ffff"/>
<map mode="linear" address="80-ff:8000-ffff"/>
</rom>
<nss>
<setting name="Difficulty">
<option value="0000" name="Easy"/>
<option value="0001" name="Normal"/>
<option value="0002" name="Hard"/>
<option value="0003" name="Expert"/>
</setting>
<setting name="Lives">
<option value="0000" name="5 lives"/>
<option value="0004" name="4 lives"/>
<option value="0008" name="3 lives"/>
<option value="000c" name="2 lives"/>
</setting>
</nss>
</cartridge>
The value field is a 16-bit value. All selected options are ORed
together to produce the final DIP switch values. The number of options
per setting is unlimited, but there are only sixteen settings allowed
(you can't have more settings than you have switches, that's just
stupid.)
In the example above, d0-d1 controls difficulty, and d2-d3 controls # of
lives. d4-d15 appear to be unused, as far as I can tell.
byuu says:
Changelog:
- file and slot load dialogs should now have perfectly square buttons
that are based on the platform's default button height.
- cleaned up bsnes/Accuracy SMP source code (removed old !! stuff, stage
3 timer is now uint4, memory access switch/case cleaned up,
sSMPTimer->Timer, etc.)
- cleaned up bsnes/Accuracy memory access functions (read/writestack ->
read/writesp, read/writeaddr -> read/write)
- minor optimization to bsnes/Performance SMP core in cycle-mode
byuu says:
I apparently wasted two days writing that SMP core for nothing. I had
a perfectly well-written and well-tested core in bsnes v045. The old
opcode.b files that were a cycle-based markup language.
So I took that core, and wrote new parsers to generate both opcode-based
(one switch) and cycle-based (two switch) cores. Throw in a
little #define magic around CYCLE_ACCURATE, and it is compile-time
toggleable.
EWJ2's bug was due to not resetting the timer variables, and Bahamut
Lagoon's was due to dividing timer frequencies by 3, but failing to
remove the 0->1 transition phase (should have done the latter and
divided by two.)
Anyway, all fixed up.
byuu says:
New S-SMP core is feature-complete, but still buggy. It's good enough
for perfect audio in Zelda 3 and Super Mario World, but there are plenty
of issues. No audio in Bahamut Lagoon, deadlock in Earthworm Jim 2,
etc.
With this core, bsnes/Performance runs about 3-5% faster than with the
old one. That won't seem like much, because the S-SMP is the least
demanding portion of the SNES. blargg's SMP core netted me a 5-8%
speedup the last time I tried it, so I'm sure there's still room to
speed things up.
The core is opcode-based, but has dummy op_io() calls (they compile to
nothing), so it is trivial to make it cycle-based if desired. I'm not
convinced that is necessary, but we shall see once we get the opcode
bugs ironed out.
byuu says:
Started on a new SMP core for bsnes/Performance. I wanted to start
clean, and only copied over the debugger+disassembler portions from the
existing version. I figured that if I took the existing one and tried
trimming it down, that it'd end up with too much old baggage. But so
far, the opcodes are looking mostly the same anyway, only I'm
using #defines and a switch table in place of the template function
trickery.
I have enough written now that I can run Zelda 3 at least (although it
gets stuck in a loop immediately after.) No real point in comparing
speed yet, because it'll definitely go down as it becomes more complete.
byuu says:
Finally, a new release. I have been very busy finishing up SNES box,
cartridge and PCB scanning plus cataloguing the data, however this
release still has some significant improvements.
Most notably would be randomization on startup. This will help match the
behavior of real hardware and uninitialized memory + registers. It
should help catch homebrew software that forgets to initialize things
properly. Of course, I was not able to test the complete library, so it
is possible that if I've randomized anything that should be constant,
that this could cause a regression. You can disable this randomization
for netplay or to work around any incompatibilities by editing bsnes.cfg
and setting snes.random to false.
The GUI also received some updates. Widget sizes are now computed based
on font sizes, giving it a perfectly native look (because it is native.)
I've also added a hotkey remapping screen to the input settings. Not
only can you remap inputs to controllers now, but those who did not know
the hotkey bindings can now quickly see which ones exist and what they
are mapped to.
Changelog (since v077):
- memory and most registers are now randomly initialized on power-up
- fixed auto joypad polling issue in Super Star Wars
- fixed .nec and .rtc file extensions (they were missing the dot) [krom]
- PPU/accuracy now clears overscan region on any frame when it is
disabled
- PPU/compatibility no longer auto-blends hires pixels (use NTSC filter
for this)
- added hotkey remapping dialog to input settings window
- added a few new hotkeys, including quick-reset
- phoenix API now auto-sizes widgets based on font sizes
- file dialog once again remembers previously selected file when
possible
byuu says:
Changelog:
- fixed .nec and both .rtc file extensions (thanks krom)
- randomized most S-PPU registers, should trip up some broken homebrew
that does not initialize all registers
- randomization is now seeded with time(0) rather than 'byuu'
- SNES::interface.video_refresh() now always receives
{256,512}x{240,480}
- PPU/accuracy scanline 0 does not render the screen back color anymore,
fixes strange coloring look on first scanline in PAL TV mode in
non-overscan games
- disabled hires blending in PPU/compatibility; all three cores act the
same now
byuu says:
Changelog:
- setGeometry is called after append(layout) now. This fixes the window
sizing on Qt.
- removed enum Style {} code, as it's no longer necessary.
- removed Filter, Shader path selection code from the file load dialog,
since that is menu-driven now.
- improved the file load dialog to remember last selected file when mode
doesn't change (had to split a switch statement into two switches.)
- added Hotkeys port onto input settings window, allowing one to
dynamically see and remap GUI shortcuts
- added power cycle / reset shortcuts
Still very minimal with the hotkeys, so I packed them all into one group
for now. A few more I'd like to add, but I don't want to get ridiculous
like with the Qt GUI.
byuu says:
Fixed up the geometry calculation code. There is now minimumGeometry()
[returns minimum size needed to display a layout, treats MaximumSize as
MinimumSize], and minimumLayoutGeometry() [like minimumGeometry(), but
it will return MaximumSize if a single container item has that
attribute. Used mostly internally for layout sizing.]
It looks great on Windows, but it looks visually off on Qt. Not exactly
sure what's up there. When I make a test application, everything looks
great. Going to have to clone a bsnes window that's having a problem (eg
bsnes main debugger checkbox window), and see what's up.
byuu says:
Wouldn't recommend using this, but it has bsnes ported to the new auto-size calculating phoenix API.
Known issues:
- minimumWidth/Height on layouts isn't working right, windows that use
it are usually too small
- Windows gives 0,0 size for empty text string sizes, which messes up
a lot of default sizes for LineEdit controls
byuu says:
Changelog:
- fixed auto joypad polling bug (fixes Super Star Wars start button
input)
- added pseudo-random class; so far it is RAM only [WRAM, APURAM, VRAM,
OAM, CGRAM]
- added new system configuration options to bsnes.cfg
The pseudo-random class is optional. For right now, I am defaulting it
to enabled. bsnes.cfg::snes.random = true.
You can of course turn it off if you want. This will break Death Brade
and Unnamed Euro Racer, no questions about it.
So I don't know if I want to leave this on or off by default. Leaving it
on will thwart emulator detection code and help to keep code that relies
on uninitialized memory from working, but leaving it off will increase
compatibility.
byuu says:
Changelog (since v076):
- video filters and shaders now populate inside main menu; no longer
have to select them as files
- fixed 2xSaI, Super 2xSaI and Super Eagle on 32-bit platforms; still
buggy on 64-bit Windows
- fixed linear mirroring issues (fixes Mega Man X dash bug)
- fixed RAM memory mapping bug in Sufami Turbo games
- home folder is now %APPDATA%/bsnes or ~/.config/bsnes
- added paths.cfg file, which will allow you to specify custom paths for
any file types
- save states and cheat files for multi-slot games are based on slot
names instead of BIOS names
- fixed compilation warning on OS X with nall::decimal
- fixed calculation bug in nall::fp
- Makefile now has options variable, example: make options=debugger
- configuration files and cheat database can now reside in the same
folder as the binary itself
- updated to 2011-03-11 release of mightymo's cheat database
byuu says:
Rather than make the libsnes API incompatible with previous versions,
I just implemented path as return { basename, hint };
So you will still use the set basename function already there as before.
So either DSP/MSU1/Serial all go in the ROM folder, or they all go
somewhere else. You can be fancy and detect the gametype and override
the basename as you like, if you really want.
Bumped the API to 1.3, and added const char* snes_library_id(void); it
will return "bsnes v076.07" at the moment. The internal string is
static, but don't try caching it or modifying it anyway. You'll have to
split the name and version yourself if you want them separately. API is
backward-compatible to 1.0 still.
Also improved string::assign and string::append to take a variadic
number of arguments. To make this happen, I had to make to_string return
const char* so that infinite recursion did not happen.
byuu says:
Changelog:
- path code finished for ui/, just need to expose for ui-libsnes/ now
- filters and shaders use radio items now, so you know which is active
- smooth video was placed inside video mode (list is getting too long)
- .bsnes -> .config/bsnes in make install
- pixelshaders -> snesshader, added Makefile with make install target
- snesfilter, added Makefile with make install and make clean targets
- maybe other stuff
byuu says:
Changelog:
- QMenu::setVisible() does nothing, have to use
QMenu::menuAction::setVisible()
- improved path system, especially for ST games (states will be
/path/to/slotA+notdir(slotB).ext, saves are per-game and per-path)
- paths are now valid when you load just the BS-X/ST/SGB BIOSes with no
carts inserted; maybe useful for BS-X I guess
- removed video filter and pixel shader code from video settings dialog
- added Settings->Video Filter and Settings->Video Shader menu lists
- fixed the SaI family of filters in lores-mode only; although I don't
really know how or why the change fixed them, the code is too vague
The menu list for the video filters and shaders are populated from
either base/filters and base/shaders, or user/.config/bsnes/filters and
user/.config/bsnes/shaders. It tries the first, and if it does not find
anything it tries the second, just like the configuration files.
That meant doing away with multiple folders for the shaders, so now the
shaders have a suffix to indicate what driver uses them, eg
"Curvature.OpenGL.shader" and "Sepia.Direct3D.shader" -- probably nicer
to use GLSL/HLSL, but using the driver name lets me sub in the currently
loaded video driver with no special casing. So the filter if you have eg
OpenGL loaded is "*.OpenGL.shader"; and for SDL you get "*.SDL.shader",
which will obviously not be there as the non-GL-based SDL driver doesn't
support shaders.
If there are no filters or no shaders available, the menu options do not
show up. The lists are not radio items with active item ticked states
just yet, but they will be.
byuu says:
Changelog:
- fixed Sufami Turbo ROM and RAM mapping bugs
- more paths work, definitely need to clean up parameter names and enum
typenames now
I had to cheat just a bit on the ST SRAM. For now, I am specifying the
RAM size in the XML file.
The base XML isn't supposed to know about the slots though. What I need
to do is write an ST header parser to get actual RAM sizes, and then
from there generate an ST-specific XML file (like I do for the Game Boy)
to specify this info. Would also be nice for some BS-X info.
Added NECDSP, MSU1 and Serial paths. This eliminates
SNES::Cartridge::basename.
byuu says:
Changelog:
- paths.cfg work completed
- save states/archives and cheat files for multi-slot games are more
intelligent now
For paths.cfg, there are three types of entries. Each have different
special prefixes.
Folder paths: sfc, bs, st, gb, filter, shader
By default, bsnes will remember the last path you loaded a file of said
type from. It will be prefixed with "recent/" in the file. Specify an
explicit hard-coded path to override this.
BIOS paths: satellaviewBios, sufamiTurboBios, superGameBoyBios
Remembers an explicit hard-coded path to the BIOS you selected last.
I was thinking that a nice feature would be for the "Load Special"
windows to pop open the slot A load dialog if a BIOS was selected.
Select a game from this popup and it loads directly, cancel it to get
the regular window to override the BIOS.
Save paths: srm, rtc, bsa, bst, cht, log
Paths to write various files that the emulator generates. Note: srm
groups bsp, bss and sav for now. Was being lazy.
There are four special prefixes for these:
"base/" -- gets replaced with the executable path
"user/" -- gets replaced with the same folder where bsnes.cfg goes
(%APPDATA%/bsnes or ~/.config/bsnes) -- good for hiding
files
"./" -- gets replaced with the current ROM path
"../" -- gets replaced with the folder above the current ROM path
If you want to go up two folders or more, then use a hard-coded path. If
that's not good enough, kill yourself because God hates you.
byuu says:
Changelog:
- fixed a crashing bug when you toggle a cheat code and then load a save state
- added paths.cfg
- bsnes now remembers the most recent path per file-type, like bsnes/Qt
used to do
- re-added -s to Linux linker flags
- fixed crash with libsnes/SGB XML parsing
byuu says:
Changelog:
- fixed linear mirroring issue in memory map (fixes dash in Mega Man X)
- home path for Windows is now %APPDATA%/bsnes (not %APPDATA%/.bsnes)
- home path for OS X and Linux is now ~/.config/bsnes (not ~/.bsnes)
- bsnes-geometry.cfg is now geometry.cfg; and it stores width,height
- I do not yet restore width, height; because the GTK+ and Qt APIs treat window
resize as implying setMinimumSize
- added bsnes/ui/path; which I have some significant plans for
- fixed a bug in realpath (specified path is not always a folder, so we should
not always append / as with userpath)
- bsnes.cfg, geometry.cfg and cheats.xml may now optionally exist in the same
folder as the binary itself
- ruby only imports the nall namespace after including system headers (should
fix OS X 'decimal' issue)
- nall::fp now uses atof (fixes nall::fp("0.05"))
- I split the CheatDatabase to a separate cheat-database.cpp file; it was
pretty ugly packed into cheat-editor.cpp
- Makefile now has "options := " line; where you can add "debugger" if you
like, and in the future maybe more options
- also works via command-line: make options=debugger
byuu says:
Most notable in this release is that sound support has been added to my
own Super Game Boy emulation. The GUI toolkit, phoenix, has also
received a complete rewrite; with the most visible change there being
that windows are now resizable.
Changelog (since v075):
* added sound emulation to Game Boy core
* fixed Super Game Boy save state
* support added HexEdit widget to Windows and Qt targets; debugger can
now be compiled on all platforms
* entering fullscreen now auto-hides mouse; and mouse capture is toggled
otherwise by F12 key
* fullscreen command and geometry caching works much better on GTK+ and
Qt targets
* phoenix rewritten from scratch; now supports resizable layout
containers
* phoenix/Windows no longer relies on buggy SetParent API to reparent
widgets
byuu says:
This has my latest API enhancements, but there are some known issues:
- resize on Windows seems to not repaint the buttons properly in rare
cases. I may just need to revert to flickering resize.
- GTK+ reports the wrong menu height, off by two pixels, prior to the
window being realized (made visible)
- this results in the main window moving up two pixels after each run
of bsnes
The menu height bug was actually there previously, it was just that Qt
and GTK+ were computing the frame margins incorrectly (ignoring the menu
bar) before.
On the bright side, ui/settings/input.cpp has been improved by way of
the new multi-layout support. The window is no longer forced to an
awkward 640 pixels wide, as the mouse axes/buttons can overlap now. The
code is also simpler since I am using the Layout::setVisible command to
toggle groups on and off instead of doing it for each and every control.
byuu says (in the thread about rewriting Phoenix):
- added phoenix/reference; a dummy implementation that contains the 22KB
of static boilerplate code needed to start a new target
- OS::setDefaultFont removed; problem is that objects in the global
scope are constructed before you can call that function
- added Window::setWidgetFont, which is applied if your widgets have no
custom font set already upon attaching them to the window with
Window::setLayout, more understandable behavior
- renamed ListBox to ListView
byuu says (in the v075 WIP thread):
Found the source of lag on cartridge load. ListView::modify() was not
locking Qt messages, so it was causing a CheatEditor::refresh (copies
16MB of memory each call) for all 128 cheat items.
Final issue now is that nested submenus (menus inside of menus) are not
applying Window::setMenuFont yet.
byuu says:
phoenix has been completely rewritten from scratch, and bsnes/ui + bsnes/ui-gameboy have been updated to use the new API. Debugger works too. Currently, only phoenix/Qt is completed, and there are two known issues:
1: font sizes of menu items are wrong, I can fix this easily enough
2: there's some sort of multi-second lag when loading games, not sure
what's happening there yet
The new phoenix isn't exactly complete yet, still making some key
changes, and then I'll start on phoenix/Windows and phoenix/GTK+.
The most noticeable difference is that you don't have to give all of the
header paths and PHOENIX_PLATFORM defines when compiling individual GUI
object files. It's only needed for phoenix.cpp itself. The overall
structure of the phoenix source folder is much saner as well for
sync.sh.
I'm really surprised things are working as well as they are for
a two-day power rewrite of an entire phoenix target. The other targets
won't be as bad insofar as the core stuff is completed this time. And
thank god for that, I was about ready to kill myself after writing
dozens of lines like this:
HorizontalSlider::HorizontalSlider() : state(*new State),
base_from_member<pHorizontalSlider&>(*new pHorizontalSlider(*this)),
Widget(base_from_member<pHorizontalSlider&>::value),
p(base_from_member<pHorizontalSlider&>::value) {}
But each platform does have some new, unique problems. phoenix/GTK+ was
acting screwy prior to the rewrite, and will most likely still have
issues. Even more important, one of the major points of this rewrite was
having the new phoenix/core cache widget settings/data, so that I can
destroy and recreate widgets rather than relying on SetParent. This
means that simple copying of the old phoenix/Windows won't work, and
this new method is significantly more involved.
byuu says:
Rewrote the way menus are attached, they act like layouts/widgets now.
All three phoenix targets once again work with both radio menu items and
radio widgets. Both GTK+ and Qt have built-in group controls right
inside the widgets, so I don't have to keep my own groups around
anymore. They do act screwy at widget creation though, have to jump
through some hoops to get it to work right. All I can say is, definitely
set all child widgets to the parent before trying to check any of them.
My long-term goal for the main window is to honor the fullscreen video
setting as a generic setting, and let the window scale auto-fit the best
possible size that matches your scale preference into the output window,
centered just like fullscreen. For now, I've just set it to a fixed
window size until I finish working on phoenix. The scale X settings will
just be to snap the window to an exact size in case you don't want any
black borders, they won't be radio items and the bsnes-geometry.cfg file
will save width/height information as well.
Simplified the sizing requirements for creating layouts and updated all
bsnes windows to support the new system. Layouts also expose their
minimum width/height values, which I use to create perfectly sized
windows on all three platforms. This will fix cut-off heights on the
last Windows WIP. Qt is being annoying though and forcing a minimum
window size of 300,100 despite me telling it to use a smaller window
size. Always have to fight with Qt, I swear to god.
byuu says:
phoenix/Windows and phoenix/Qt are mostly fully operational now. All
platforms support dynamic layout resizing. I tried WM_GETMINMAXINFO
(thanks, OV2), but it was acting kind of choppy on resize, and it would
get confused and go crazy if you snapped one direction to the minimum
height but not another, so for now I'm leaving it off.
phoenix/GTK+ will be missing some functionality in regards to window
geometry. The other two have a more coherent strategy now: geometry() is
the client area, and setGeometry moves the client area to where you ask
for. This makes truly centering your client area trivial.
frameGeometry() includes the borders, menu and status. There is no
setFrameGeometry(), not sure if I really even want that, but it could be
useful so who knows. All targets also support non-resizable windows.
X11 is of course horrendously poor with frame sizes, Qt and GTK+ don't
even pretend to simulate them, so they say the frame is 0x0 pixels in
size until your widget is fully realized and visible to the end user. So
for now, to get window positioning right, I have to wait until the
window appears and then reposition the window again, causing a slight
jump. My plan is to build some persistent caching support directly into
phoenix. From here, I can just have the window snap the very first time
you run your very first phoenix app. I'll then determine the frame size
information, and use that to create future windows. Once they spawn,
I'll recheck and update the frame size info in case it has changed (eg
user changed themes.) Saving settings into .config/phoenix will allow me
to avoid having to snap the window every time on first startup. If the
config file is missing or unwritable, too bad, happens every time then.
I'm thinking about renaming onResize to onSize, and getting rid of
Window::create(). Rather make it spawn like every other control in its
constructor.
byuu says:
Ported phoenix/Windows and phoenix/GTK+ over to the new system. There
are some problems that need to be addressed:
- Windows ComboBox height setting needs widget creation height to
properly scale itself (make Widget::setGeometry virtual and override
ComboBox::setGeometry)
- Windows Canvas is completely broken
- GTK+ Canvas is slow as shit compared to Qt Canvas, probably nothing
I can do about it, have to do a very costly conversion because GTK+ is
stupid and uses BGR like Nintendo
- GTK+ listboxes are fucking insanely complicated to set up. Currently
I just split the second-half of creation to the setHeaderText call,
but when you don't call that, things explode
- I'm probably going to have to completely destroy and recreate
listboxes when changing the header text / column count
- Qt resize code is still impossible to get right, it's not letting me
size a window > 2/3rds of the screen size (it's in their docs)
- I swear, Qt is the most painful API in the world to move/size
windows with
- now that Window is separate, it really needs geometry() and
frameGeometry() as the two are quite different
- I need a way to toggle window resizability for fixed layouts, Qt is
once again going to be a nightmare as it lacks a way to do this other
than fixed layouts
- GTK+ currently explodes on bsnes, millions of console messages,
wonderful
- plenty more I'm forgetting
One bit of really cool/good news though: I made
Fixed/Horizontal/Vertical layouts external to phoenix itself. The code
is included for all targets so that it's always there and compiled into
one object, but the great news is that you can easily write your own
layout widgets and they'll work on all toolkits instantly.
That resize issue with bsnes was so simple it's annoying: my FixedLayout
container was repositioning on geometry updates. Made it only do it once
at creation like it should.
bsnes now has a fancy resize, grow the window and get black borders,
shrink it and the video shrinks with it. I plan to make it fancier with
constraint settings (center, scale, stretch). Basically I want to turn
the fullscreen setting into a general setting that also applies to
windowed scaling. I will probably turn the video scale X sizes into
regular items instead of radio boxes, so you can easily reset to a fixed
size whenever you want. Update bsnes to remember width,height geometry
as well and it should be quite nice.
byuu says:
Eleven hours of work. Window is now a base type (inherits from Object,
not Widget), same for Layout. FixedLayout still inherits from Layout.
Added HorizontalLayout and VerticalLayout types, that can append each
other to themselves to create box layouts. Layout margins are supported,
spacing is specified inline (I find this a much better way to fine-grain
spacing than Qt's single setSpacing function), and alignment is handled
strictly via padding widgets (insert a zero-sized label and it will
automatically grow to consume all extra space.)
Overall, my box packing model is slightly less powerful than Qt's, but
it is a good deal simpler and and easier to use in 90% of cases. The one
limitation I hit was with my input settings window, I'm not currently
able to embed two different layouts and toggle one on and the other off
to show only either { mouse x-axis, y-axis } or { mouse left, middle,
right }, so they instead just space out differently and I had to grow
the input window width a bit to compensate.
Resizing works great, pretty cool seeing that this is the first time
I've ever written my own resizer. I had to fight with Qt for several
hours to the point of potentially developing an aneurysm, but I finally
got it to properly handle geometry and sizing stuff. Some weird issue
with the bsnes viewport widget, I tell it to resize and for some reason
it doesn't. Cheap hack, I just make it constantly resize every video
refresh and it eventually takes. Wish I knew what was up with that.
All of bsnes now uses dynamic layouts sans the main window, so you can
resize them however you like.
This is still all Qt-only, I'm afraid. The other two ports are
in-progress.
byuu says:
This has the phoenix changes applied. Instead of widgets attaching
directly to windows, you now attach them to layouts, which can then be
attached to windows. Layouts are widgets themselves, so adding layouts
to layouts is trivial. It also allows for multi-widget show/hide, etc.
Right now there is only FixedLayout, but of course the plan is to
support a BoxLayout, that lets you add HorizontalLayout and
VerticalLayout containers to it, thus enabling auto-resize and simpler
form layout.
So far only phoenix/Qt is 100% moved over. phoenix/GTK+ has about 1/3rd
ported, and phoenix/Windows only has one control ported over as
a proof-of-concept.
On the user side, bsnes, bgameboy, snespurify and curse have been moved
to this new layout system. All of bsnes works great with it, as far as
I can tell. Fullscreen, debugger, etc are good.
byuu says:
Removed the floating-point volume adjustments from the wave channel and
the left/right speaker mixers. Also, against my better judgment I'm
backing out of left/right computation when they are both turned off.
This basically makes non-stereo games run faster, but will make stereo
games appear to run slower. I don't like it when end-users experience
mystery slowdowns.
Anyway, it appears that the audio calculation is really fucking
demanding. Knocks FPS from 800 down to 300. I thought it might be libco,
so I took it out and it only went up to 305fps o.O
There is also some sort of problem with bsnes/Super Game Boy audio. The
latency is really great when you first start, but it seems to drift
apart over time until it is well over 500ms, and then it either pops or
fades back to very low, sub-50ms latency again. The way I handle mixing
is that the coprocessor audio samples go into a resampler to the native
SNES rate, and fed to an output buffer. SNES audio samples go there
untouched. When there is a sample in each, I add them together and
average the result (I still don't understand why we divide by two since
these are signed integers), and output it immediately. It's just-in-time
sampling, so as long as DSP v Coprocessor do not drift very far, it
should have very low latency. And I make the CPU sync DSP and
Coprocessor once per scanline, which is something like 15 samples or so.
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.
byuu says:
Changelog:
- hooked up everything necessary for Game Boy sound emulation ...
- bgameboy and bsnes/SGB input 4MHz frequency, and output 44.1KHz
frequency (produces soft static for now, to verify it is working)
- rewrote all of gameboy/apu, it now has a 4MHz worker thread, and
separate classes/folders for each channel+master, and serializes
So it's basically all I can do without actual emulation code or
human-readable documentation/example code.
byuu says:
Changelog:
- added full HexEditor widget to phoenix/Qt (has dynamic scrollbar like
phoenix/GTK, but does not yet support page up/down scrolling)
- optimized debugger to look great with either phoenix/GTK or phoenix/Qt
- fixed phoenix/Qt fullscreen mode (had to allow resizing of the layout,
and resize the container)
- fixed phoenix/Qt Window::setBackgroundColor() bug that was making
statusbar invisible
- entering fullscreen now captures mouse, leaving fullscreen releases it
- so by default, no cursor in fullscreen mode now
- F12 key was assigned the task of toggling mouse capture,
Tools->Capture Mouse was removed
- above change allows toggling mouse capture in fullscreen if you like
It wasn't my idea, but toggling the mouse capture in fullscreen also hiding the mouse cursor is what I call genius design. Two birds with one stone, and very intuitive.
Also, the default GUI on Linux for bsnes and bgameboy is now Qt, instead
of GTK+. I did this because Qt's fullscreen is far more stable, and
I fixed up the remaining bugs anyway.
byuu says:
Changelog:
- added ui-libsnes directory back into source archive; make archive-all
includes it now
- added basic HexEditor widget to phoenix/Windows
byuu says:
Changelog:
- fixed Super Game Boy save state support
- both SNES and GameBoy only initialize serialize size on cartridge load
once now, just like I've already done with memory mapping
- added nall/public_cast.hpp for fun ... don't worry, I'm never actually
going to use it in production code :D
byuu says:
This release brings improved Super Game Boy emulation, the final SHA256
hashes for the DSP-(1,1B,2,3,4) and ST-(0010,0011) coprocessors, user
interface improvements, and major internal code restructuring.
Changelog (since v074):
- completely rewrote memory sub-system to support 1-byte granularity in
XML mapping
- removed Memory inheritance and MMIO class completely, any address can
be mapped to any function now
- SuperFX: removed SuperFXBus : Bus, now implemented manually
- SA-1: removed SA1Bus : Bus, now implemented manually
- entire bus mapping is now static, happens once on cartridge load
- as a result, read/write handlers now handle MMC mapping; slower
average case, far faster worst case
- namespace memory is no more, RAM arrays are stored inside the chips
they are owned by now
- GameBoy: improved CPU HALT emulation, fixes Zelda: Link's Awakening
scrolling
- GameBoy: added serial emulation (cannot connect to another GB yet),
fixes Shin Megami Tensei - Devichil
- GameBoy: improved LCD STAT emulation, fixes Sagaia
- ui: added fullscreen support (F11 key), video settings allows for
three scale settings
- ui: fixed brightness, contrast, gamma, audio volume, input frequency
values on program startup
- ui: since Qt is dead, config file becomes bsnes.cfg once again
- Super Game Boy: you can now load the BIOS without a game inserted to
see a pretty white box
- ui-gameboy: can be built without SNES components now
- libsnes: now a UI target, compile with 'make ui=ui-libsnes'
- libsnes: added WRAM, APURAM, VRAM, OAM, CGRAM access (cheat search,
etc)
- source: removed launcher/, as the Qt port is now gone
- source: Makefile restructuring to better support new ui targets
- source: lots of other internal code cleanup work
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
byuu says:
Major WIP, countless changes. I really went to town on cleaning up the
source today with all kinds of new ideas. I'll post the ones I remember,
use diff -ru to get the rest.
What I like the most is my new within template:
template<unsigned lo, unsigned hi>
alwaysinline bool within(unsigned addr) {
static const unsigned mask = ~(hi ^ lo);
return (addr & mask) == lo;
}
Before, you would see code like this:
if((addr & 0xe0e000) == 0x206000) { //$20-3f:6000-7fff
The comment is basically necessary, and you have to trust that the mask
is right, or do the math yourself.
Now, it looks like this:
if(within<0x20, 0x3f, 0x6000, 0x7fff>(addr)) {
That's the same as within<0x206000, 0x3f7fff>, I just made an
SNES-variant to more closely simulate my XML mapping style:
20-3f:6000-7fff.
Now obviously this has limitations, it only works in base-2 and it can't
manage some tricky edge cases like (addr & 0x408000) == 0x008000 for
00-3f|80-bf:8000-ffff. But for the most part, I'll be using this where
I can. The Game Boy is fully ported over to it (via the MBCs), but the
SNES only has the BS-X town cartridge moved over so far. SuperFX and
SA-1 at the very least could benefit.
Next up, since the memory map is now static, there's really no reason to
remap the entire thing at power-on and reset. So it is now set up at
cartridge load and that's it. I moved the CPU/PPU/WRAM mapping out of
memory.cpp and into their respective processors. A bit of duplication
only because there are multiple processor cores for the different
profiles, but I'm not worried about that. This is also going to be
necessary to fix the debugger.
Next, Coprocessor::enable() actually does what I initially intended it
to now: it is called once to turn a chip on after cartridge load. It's
not called on power cycle anymore. This should help fix power-cycle on
my serial simulation code, and was needed to map the bus exactly one
time. Although most stuff is mapped through XML, some chips still need
some manual hooks for monitoring and such (eg S-DD1.)
Next, I've started killing off memory::, it was initially an
over-reaction to the question of where to put APURAM (in the SMP or
DSP?). The idea was to have this namespace that contained all memory for
everything. But it was very annoying and tedious, and various chips
ignored the convention anyway like ST-0011 RAM, which couldn't work
anyway since it is natively uint16 and not uint8. Cx4 will need 24-bit
RAM eventually, too. There's 8->24-bit functions in there now, because
the HLE code is hideous.
So far, all the cartridge.cpp memory:: types have been destroyed.
memory::cartrom, memory::cartram become cartridge.rom and cartridge.ram.
memory::cartrtc was moved into the SRTC and SPC7110 classes directly.
memory::bsxflash was moved into BSXFlash. memory::bsxram and
memory::bsxpram were moved into BSXCartridge (the town cartridge).
memory::st[AB](rom|ram) were moved into a new area,
snes/chip/sufamiturbo. The snes/chip moniker really doesn't work so
well, since it also has base units, and the serial communications stuff
which is through the controller port, but oh well, now it also has the
base structure for the Sufami Turbo cartridge too. So now we have
sufamiturbo.slotA.rom, sufamiturbo.slotB.ram, etc.
Next, the ST-0010/ST-0011 actually save the data RAM to disk. This
wasn't at all compatible with my old system, and I didn't want to keep
adding memory types to check inside the main UI cartridge RAM loading
and saving routines.
So I built a NonVolatileRAM vector inside SNES::Cartridge, and any chip
that has memory it wants to save and load from disk can append onto it
: data, size, id ("srm", "rtc", "nec", etc) and slot (0 = cartridge,
1 = slot A, 2 = slot B)
To load and save memory, we just do a simple: foreach(memory,
SNES::cartridge.nvram) load/saveMemory(memory).
As a result, you can now keep your save games in F1 Race of Champions II
and Hayazashi Nidan Morita Shougi. Technically I think Metal Combat
should work this way as well, having the RAM being part of the chip
itself, but for now that chip just writes directly into cartridge.ram,
so it also technically saves to disk for now.
To avoid a potential conflict with a manipulated memory map, BS-X SRAM
and PSRAM are now .bss and .bsp, and not .srm and .psr. Honestly I don't
like .srm as an extension either, but it doesn't bother me enough to
break save RAM compatibility with other emulators, so don't worry about
that changing.
I finally killed off MappedRAM initializing size to ~0 (-1U). A size of
zero means there is no memory there just the same. This was an old
holdover for handling MMIO mapping, if I recall correctly. Something
about a size of zero on MMIO-Memory objects causing it to wrap the
address, so ~0 would let it map direct addresses ... or something.
Whatever, that's not needed at all anymore.
BSXBase becomes BSXSatellaview, and I've defaulted the device to being
attached since it won't affect non-BSX games anyway. Eventually the GUI
needs to make that an option. BSXCart becomes BSXCartridge. BSXFlash
remains unchanged.
I probably need to make Coprocessor::disable() functions now to free up
memory on unload, but it shouldn't hurt anything the way it is.
libsnes is most definitely broken to all hell and back now, and the
debugger is still shot. I suppose we'll need some tricky code to work
with the old ID system, and we'll need to add some more IDs for the new
memory types.
byuu says:
This WIP fixes up the last bit from the old memory mapping system, the
BS-X Satellaview town cartridge now has a static memory mapper that is
dynamically decoded based on register settings. Tested with BS Town + BS
Zelda, and I can get in-game just fine. The mapping code is actually
a lot more readable this way, too.
byuu says:
The nall::function binding for the memory map apparently breaks when the
debugger is enabled, as PPU:: becomes PPUdebugger::, etc; and C++ isn't
smart enough to upconvert for us.
Not sure how I am going to work around that yet ...
Changelog:
- improved GameBoy::CPU::Halt emulation, fixes Legend of Zelda intro
water+world-map scrolling at the same time
- added GameBoy::APU skeleton, and hooked up MMIO read/write for all
registers
- modified nall integer->string functions
byuu says:
Fullscreen works on all ports, but Qt is in general pretty wonky at the
moment. Don't really care right now.
F11 toggles fullscreen, there is no menu or status in fullscreen, and it
auto-scales to the highest even multiple that it can.
It copies all other settings (filter, shader, aspect correction, video
region, vsync, async) from your windowed mode settings.
You cannot enable the menu or status bars, because those are a major
pain in the ass to support with both GTK+ and Qt returning nonsense
geometries.
Combine with each platform treating whether or not to handle menus
and/or statuses as part of the geometry or not, and it's a recipe for
pain.
It is pseudo-fullscreen for now, but if we have some spiffy code in the
future to set a true fullscreen that works on Linux (and hopefully OS
X), I'll add a true-FS option to ruby later.
byuu says:
This WIP uses the 16MB+64MB memory tables for 1:1 mapping of the S-CPU
bus.
Minimum RAM requirement goes up to 128MB, dare I be bold here and
recommend you have 256MB.
I also hooked up the basic bindings for making pseudo-fullscreen windows
in phoenix/Windows and phoenix/GTK+, but both have some serious issues.
- GTK+ won't resize my form container, even though it's the same code
I used successfully in bsnes v039 and prior with hiro
- Windows scale selection breaks the faux-fullscreen effects
- I am intending to write off the menu/status bars and just auto-size
the video to fill the screen, nice and simple
byuu says:
Oh good, that turned out to be a lot easier than I expected.
Almost all of the work was already done yesterday in porting the SA-1
over to a static map.
byuu says:
SuperFXBus was inheriting from Bus, in other words using a copy of the
same memory mapping subsystem.
I've removed that and made it a simple mask, since only ROM+RAM are
mapped there.
byuu says:
You guys are going to hate the hell out of this one. It's twenty hours
of non-stop work, no exaggeration at all. Started at 4AM, just wrapped
up now at 8PM.
I rewrote the entire memory subsystem.
Old system:
65536 pages that map 256 bytes each
Mapping a new page overwrites old page
Granularity capped at 256 bytes minimum, requiring ST-001x to map
60:0000-00ff instead of 60:0000,0001
Classes inherit from MMIO and Memory, forcing only one mappable function
per class, and fixed names
MMIO sub-mapper inside memory: 00-3f:2000-5fff for one-byte granularity
Can dynamically change the map at run-time, MMC register settings
perform dynamic remapping
New system:
XML mapping is still based around banklo-bankhi:addrlo-addrhi, as that
shapes almost everything on the SNES very well
Internally, 2048 pages that map 8192 bytes each
Pages are vectors, scans O(n) from last to first (O(log n) would not
help, n is never > 3)
Can multi-cast writes, but not reads [for the obvious reason of: which
read do you return?]
Can map reads and writes separately
Granularity of one for entire 24-bit address range, no need for MMIO
- whatever is in XML is exactly what you get
Read/Write tables bind function callbacks, so I can have any number of
functions with any names from any classes with no inheritance (no
more uPD7725DR, uPD7725SR helpers, etc)
Less memory usage overall due to less tables [ I tried 16 million tables
and it used 2GB of RAM >_o ]
Cannot dynamically change the map at run-time, MMC read/write functions
perform address translation [worse average case speed, better worst
case speed]
Now the hate me part, functors can't beat virtual functions for speed.
There are speed penalties involved:
-4.5% on average games
-11% on SuperFX games (SFX has its own bus)
-15% on SA-1 games (SA-1 has two buses)
Of course the two that need the speed the most get the biggest hits.
I'm afraid there's really not a lot of wiggle room to boost speed back
up.
I suppose one bright spot is that we can much more easily try out
entirely new mapping systems now, since the dynamic portions have been
eliminated.
byuu says:
Changelog:
- updated/fixed st0011.bin SHA256 sum
- removed launcher/
- building ui-gameboy only builds the Game Boy core, not the SNES core
- binary name output is bgameboy for ui-gameboy
- make install/make uninstall work as expected with the extra data files
[Editor's note - those last three changes seem to have been made in
v074r01]
byuu says:
Changelog:
- fixed libsnes to compile again, the GB RTC constant is there but
doesn't do anything just yet (no serialize support in GameBoy core)
- libsnes: added SNES_MEMORY_(WRAM,APURAM,VRAM,OAM,CGRAM) -- really only
for the first one, it allows libsnes users to implement their own
cheat search
- you can now load the SGB BIOS without a game!! please be sure to enjoy
the blinking cartridge icon emulation :D
- necdsp (uPD7725,96050) - simplified code a bit: removed persistent
regs.idb, simplified jumps, merged exec() with main loop, etc.
- nall::function - fixed an initialization bug when copy-constructing
objects
- nall::vector - use calloc instead of malloc to help safeguard against
uninitialized class data (potentially hides errors, but better than
crashing in production)
byuu says (since v073):
This release adds full low-level emulation of the NEC uPD96050
coprocessor, used by the ST-0010 (F1 Race of Champions II) and the
ST-0011 (Hayazashi Nidan Morita Shougi). The former was already playable
with HLE, but lacked timing emulation. The latter has never been
playable through emulation before now. But as with SD Gundam GX before,
you really weren't missing much.
[...]
Also new in this release is my own Game Boy emulator. It is being used
to provide native Super Game Boy support, built directly into bsnes.
This core is released under the GPLv2, but I am willing to grant a more
permissive license for other SNES emulators, if anyone is interested.
Of course I cannot compete with the quality of gambatte, and certainly
not from only a weeks' worth of work. Currently, there is no Game
Boy-side sound output and there are quite a few bugs remaining in its
emulation core. I would appreciate any help on this, the Game Boy is not
my forte. So yes, we are taking a step back today, so that we may take
two steps forward in the future.
[...]
Lastly, the debugger is still Linux-only, but it is now stable enough to
be considered usable. Check it out if you like, compile with -DDEBUGGER
to enable it.
byuu says:
I give up for now. This WIP doesn't really improve uPD any, but it does
have major fixes to the debugger.
Debugger is still Linux-only for want of a HexEditor widget, but the
Linux one is now usable.
Before it'd trace and search for breakpoint at sub-1fps. Fixed it to not
break out of core for simple things and it'll run at near-fullspeed for
BPs, half-speed for tracing to file (lots of I/O.)
byuu says:
Above WIP will automatically map in the ST-001x chips, no need for an
XML file.
F1 Race of Champions II (J) is fully playable, at least. It's forced to
15MHz like the ST-0011 for now.
The core (snes/chip/necdsp/core) is somewhat unstable at the moment,
some debugging hooks commented out and some hacks / ideas floating
around in there. Disassembler can't handle long jumps yet.
Added uPD96050 emulation, but it's not working right now. I'm totally
stumped. The ST-0010 player cars aren't moving right, and it crashes
sometimes on exit like it's going out of bounds.
I had decided to try and avoid duplicating the 20KB uPD7725 core, so
I made a new folder:
snes/chip/necdsp
snes/chip/necdsp/upd7725
snes/chip/necdsp/upd96050
The latter two derive from the former, and they specify the PC, RP and
DP sizes, which allocates appropriate memory.
I use simple runtime-masked registers (to avoid template hell on every
uPDcore function), and then I derive from that to complete each actual
DSP. The uPD7725 seems to work great, but the uPD96050 is fucked and
I don't know why :(
Help would be appreciated, it must be something simple because I am
certain the cars were working before.
Kinda wish I didn't scrap the old code now :(
I've merged the bgameboy GUI into the bsnes project, as it's only ~3KB
and it means I don't have to keep manually editing and copying two
projects around. You can set ui := ui-gameboy to build bgameboy as
a standalone, and ui := ui to build the bsnes you are used to. I will be
polishing it to allow changing the binary output name, not building the
SNES portions when not needed, etc in time.
So that'll end bgameboy standalone releases, at least for now. If it
ever gets important enough to split back out again I can, but I prefer
it this way. bgameboy was never meant to be mainstream anyway, just
a component for bsnes.
byuu says:
Changelog:
- much tighter SGB integration, but this is still a work-in-progress
- memory::gb(rom,ram,rtc) is gone, uses GameBoy:: memory structures
directly (a big gain, no need to copy memory to save and load)
- UI-based cartridge loading works with GameBoy:: directly as well
- libsnes will need to be updated internally to reflect this
- games can save and load (even before bgameboy can, hah)
- save states hooked up, but they crash the DMG. I don't know why, as
if it was hard enough saving states with libco, try doing it for an
emulator inside an emulator >_<
- last remnants of old SGB stuff removed, <sueprgameboy> XML converted
to <icd2>
- looks like the XML list idea is looking pretty useless for
SNES::Cartridge now that bgameboy handles its own XML mapping
byuu says:
Changelog:
- removed bsnes/supergameboy (libgameboy -> libgambatte binding)
- added direct ICD2-R coprocessor emulation
- linked in bgameboy to the ICD2-R module
- Makefile removes -Isnes, all files adjusted from <name.hpp> to
<snes/name.hpp> [relic from asnes split]
You can now play Super Game Boy games with the core bsnes library.
byuu says:
Changelog:
- adds XML memory mapping to cartridge loading;
nall/gameboy/cartridge.hpp will bullshit one for now
- still need to add proper MMM01 detection (menu code goes at end of ROM
apparently)
- added save state support, which works here (but not inside bsnes, go
figure), to aid in debugging. Expect constant changes for now a long
while, it's way too early to add states
byuu says:
Changelog:
- fixed LYC interrupt at LY=0 (fixes Makai Toushi SaGa)
- fixed MBC3 ROM bank mapping (fixes Harvest Moon GBC)
- added Super Game Boy MLT_REQ support to JOYP, needed for ICD2-R emulation
- temporarily changed System::run() to execute only four cycles before
exiting for bsnes, will make two versions later
- uses actual boot ROMs, has DMG+SGB1 for now. Need SGB2, don't care
about CGB. Defaults to SGB1, no way to select just yet. DMG 4-second
wait is annoying. Does not force games to act like SGB on bgameboy
itself, because that has no ICD2 and fails the required MLT_REQ check
byuu says:
Changelog:
- added skeleton HuC1 (gets to a menu)
- added skeleton HuC3 (gets to a menu, this one is supposedly a lot more
complex (IR, RTC, etc.))
- added MMM01 emulation
byuu says:
Changelog:
- rewrote sprite rendering, grabs first ten sprites, draws them in
revere order of a: X-index, b: OAM appearance order
- simplified tile decoding to use less variables
- added MBC3 emulation (for now, RTC is always enabled)
- STOP can be broken via joypad IF, this may not be correct though (it
may trigger even without P10-13 being modified)
- cleaned up all MBC emulation to use masks instead of ranges
- MBC2 uses 512-byte table now, ignores high 4-bits. Easier this way I guess
- tools menu temporarily has a console tracer enable option
- some other stuff
No real visible improvements :(
byuu says:
Changelog:
- fixed sprite Vflip check
- fixed up window rendering (well, mostly, works great in Megaman II but
not so great in Makaitoushi SaGa)
- added MBC2, MBC5 (already had MBC0, MBC1)
- removed reset, hooked up power cycle and Vsync toggle
- some other stuff
Makaitoushi SaGa locks on the main menu after some graphical glitches on
the title screen, damn.
Shin Megami Tensei - Devichil Black Book locks up immediately, hitting
HALT opcodes all the time, damn again.
Megaman II should be fully playable now.
Contra 3 is really close, but goes crazy on the turtle boss fight.
byuu says:
Added MBC1 emulation, although battery RAM doesn't save or load to disk
yet.
Made up a fake MBC0 which is really just saying 'no MBC', for consistent
handling of all MBCs.
Added bumpers to stop ROM/RAM out of bounds accesses.
Added STAT interrupts for LY coincidence, Vblank and Hblank (not for OAM
access yet, I don't know the timings.)
Fixed timer interrupt [Jonas Quinn]
Made all interrupts call a CPU function instead of just setting a flag
for better control (to allow below addition.)
Added HALT and STOP emulation, the latter permanently locks the Game Boy
for now. The former breaks on interrupts.
Rewrote all the rendering code to suck 50% less, though it's still
absolutely miserable and scanline-based.
Added pixel-level horizontal scrolling to BGs.
Fixed OBJ rendering error that was making them render upside down (I was
flipping to compensate before.)
Added OBJ 8x16 mode.
Added OBJ priority support.
Added window (but it's broken to all hell on Mega Man II.)
byuu says:
Fixed all of the previously mentioned problems by myself and Jonas
Quinn.
Fixed up JOYP and hooked up JOYP interrupts, they work on JOYP writes as
well if your selection makes the low four bits change to != 0xF.
Added basic sprite emulation, very very very lousy but it works for
Tetris.
Fixed DAA, fuck that opcode. Fixes blargg's CPU tests 1 and 11 (for some
odd reason.) Only test 2 is failing, on the "EI" test. Maybe it relies
on STAT interrupts?
Did some other stuff.
Tetris is now 100% fully playable. But that renderer is an abomination.
Soooooo simplistic and missing so many edge cases.
But holy shit, a fully playable commercial game in three days. I would
have killed to have made that progress when I started on bsnes.
byuu says:
All 512 instructions implemented. To make debugging flags easier and to
reduce the code size, I made parent routines for all the bit-logic that
sets flags. This bumped up the speed to 3,045fps. So about 51x faster
than a real Game Boy.
I suspect the frame rate to plummet rapidly as I emulate more stuff and
try and get timings more accurate. Wild ballpark, I'd guess 300fps or
so. Not based on anything, just a made up number. I have no idea what it
will end up being.
So I still need:
* decode MMIO reads/writes
* add CPU interrupt support
* add LCD emulation (probably the hardest part)
* add PCM emulation (well, this would likely be the hardest; but it's
not essential right now)
* debug the holy living shit out of the CPU core. Anyone want to help
now by looking it over? :D
byuu says:
314 of 512 opcodes implemented, can execute the first 67,450
instructions of Tetris.
I also added an MMIO bus, ala bsnes, so that I can map and access
individual registers with a single indirection.
byuu says:
Hooked up a scheduler to enter/exit the CPU core wherever I want. Added
basic 4*1024*1024hz clock, and about eleven or so opcodes. Creating the
disassembler as I encounter each new opcode, not skipping ahead to do
all 'like other' opcodes, eg if I add 'dec b', I don't then add 'dec c'
until I encounter it.
The source tarball also included empty obj/ and out/ directories which
git does not support.
byuu says:
Project started, so basically everything is new.
It's basically a rough skeleton that mimics bsnes project structure.
Eventually the src/gameboy folder will be copied into bsnes-official and
used by the chip/supergameboy core.
The middleware layer (supergameboy/interface) will be merged into a new
chip/icd2 folder that will represent direct Super Game Boy emulation in
the future.
At least, if all goes according to plan.
There is a simple GUI that can load ROMs, but do nothing after it. It's
not hooked up to ruby yet.
There is a basic system class and interface to expose the
video/audio/input functions.
There is a basic memory bus that doesn't support any MBCs yet.
There is a CPU skeleton that only handles easy read/write access to the
CPU registers (AF is a really fucked up register.)
The core is not hooked up to libco yet, but I intend for it to be, so
that I can run the CPU + LCD how I like.
If it turns out the LCD+audio is easily enslavable, then I'll probably
drop libco and just run it like a regular emulator, using a thread
wrapper around it in bsnes only. We'll see.
The CPU doesn't actually support any opcodes, and loading a ROM won't
actually execute anything.
byuu says:
While perhaps not perfect, pretty good is better than nothing ... I've
added emulation of auto-joypad poll timing.
Going off ikari_01's confirmation of what we suspected, that the strobe
happens every 256 clocks, I've set up emulation as follows:
Upon reset, our clock counter is reset to zero.
At the start of each frame, our poll counter is reset to zero.
Every 256 clocks, we call the step_auto_joypad_poll() function.
If we are at V=225/240+ (based on overscan setting), we check the poll
counter.
At zero, we poll the actual controller and set the joypad polling flag
in $4212.d0 to 1.
From zero through fifteen, we read in one bit for each controller and
shift it into the register.
At sixteen, we turn off the joypad polling flag.
The 256-clock divider allows the start point of polling for each frame
to fluctuate wildly like real hardware.
I count regardless of auto joypad enable, as per $4212.d0's behavior;
but only poll when it's actually enabled.
I do not consume any actual time from this polling. I honestly don't
know if I even should, or if it manages to do it in the background.
If it should consume time, then this most likely happens between opcode
edges and we'll have to adjust the code a good bit.
All commercial games should continue to work fine, but this will likely
break some hacks/translations not tested on hardware.
Without the timing emulation, reading $4218-421f before V=~228 would
basically give you the valid input controller values of the previous
frame.
Now, like hardware, it should give you a state that is part previous
frame, part current frame shifted into it. Button positions won't be
reliable and will shift every 256 clocks.
I've also removed the Qt GUI, and renamed ui-phoenix to just ui. This
removes 400kb of source code (phoenix is a lean 130kb), and drops the
archive size from 564KB to 475KB. Combined with the DSP HLE, and we've
knocked off ~570KB of source cruft from the entire project. I am looking
forward to not having to specify which GUI is included anymore.
byuu says:
This release marks a major step forward, offering full low-level
emulation of all four DSP coprocessors based on the NEC uPD77C25
processor core. Many people were responsible for this milestone: Dr.
Decapitator for the actual decapping and extraction; Lord Nightmare for
the cartridges and some special analysis tools; myself, Jonas Quinn and
Cydrak for the uPD77C25 emulation; and all of the donors who raised the
necessary $1,000 for the necessary hardware and equipment needed to pull
this all off. To say thanks to the donors, I am releasing the uPD77C25
emulation core to the public domain, so that everyone can benefit from
it.
All four DSP emulations will be improved by this by way of having
realistic timing; the DSP-4 will benefit further as the high-level
emulation was incomplete and somewhat buggy; and the DSP-3 will benefit
the most as the high-levle emulation there was not complete enough to be
playable. As a result, most notably, this means bsnes v073 is the first
emulator to fully be able to play SD Gundam GX (J)!
As bsnes' primary goal is accuracy, the LLE DSP support renders the old
HLE DSP support obsolete. Ergo, I have removed the 166KB of HLE source
code, and replaced it with the uPD77C25 core, which comprises a mere
20KB of source code. As this LLE module supports save states, this also
means that for the first time, DSP-3 and DSP-4 games have save state
support.
On the other hand, this also means that to run any DSP game, you will
need the appropriate program ROM. As these are copyrighted, I cannot
distribute them nor tell you where to get them. All I can do is provide
you with the necessary filenames and hashes.
Changelog (since v072 release):
* added NEC uPD77C25 emulation core
* added low-level emulation of the DSP-1, DSP-1B, DSP-2, DSP-3, DSP-4
coprocessors
* removed high-level emulation of the DSP-n coprocessors
* added blargg's libco::ppc.c module, which is far more portable, even
running on the PS3
* added software filter support via binary plugins
* added debugger (currently Linux-only); but it is as yet unstable
* added pause shortcut
* updated mightymo's cheat code database
byuu says:
Changelog:
* added SNES::interface.message(const string&) so that the core can send
messages for the GUI to display
* failing to load a DSP-n ROM, or failing the DSP-n SHA256 hash (if
there is one) will result in a warning message
* all DSP-1 games by default once again use the DSP-1B program, now that
it has been redumped and reverified
* fixed bugs in uPD77C25 SHL2 and SHL4 opcodes; fixes DSP-2 and DSP-4
emulation
* removed all DSP HLE (DSP-1, DSP-2, DSP-3, DSP-4)
* as a result of LLE, DSP-3 and DSP-4 games can now load and save states
byuu says:
The DSP-1 and DSP-3 emulation appears to be great.
However, there are bugs in the other two.
DSP-2, Dungeon Master: the graphics in-game appear corrupt. It looks
like the first two pixels have the right color, the next six have the
wrong color, resulting in vertical stripes.
DSP-4, Top Gear 3000: the car sprites appear to be showing 8x8 tiles
instead of 16x16 files, resulting in 3/4ths of the cars being invisible,
but only up close.
Dr. Decapitator and Lord Nightmare are supremely confident that our
dumps are 100% accurate, there was no bus wavering at all this time.
We believe they are bugs in the uPD77C25 emulation.
I desperately need help! I have spent the past several hours trying to
ascertain what the problem is, to no avail.
I've tried messing with just about every flag, every register, checking
for use of OV1, S1, custom opcodes, etc ... I am having no luck.
I'm going to keep trying with even more sophisticated cross-analysis.
But Cydrak, if you would please rework that magic of yours, I'd be
eternally grateful :D
byuu says:
This release defaults DSP-3 loading to use the uPD77C25 core. It also
pre-emptively does the same for the DSP-2 and DSP-4. v072r11 did this
for the DSP-1.
I've also renamed my string<>integer conversion function names:
strhex -> hex
strsigned -> integer
strunsigned -> decimal
strbin -> binary
strdouble -> fp (this one will no doubt be trouble since 'file fp' is
a common idiom. floatingpoint is too long, float and double are
already reserved.)
A number of changes in this release were contributed by Cydrak in the
WIP thread, who described his changes from r09/r10 thusly:
- Call cpu.synchronize_coprocessor() on external R/W to avoid missing data
- Sign-extend K, L before multiplying
- Load IDB before ALU. Supports the MOV A, d; XOR A, A idiom which is
all over the place
- Use 16-bit types in flag checks (notably Z)
- Flags mostly unified; hopefully at least OV0 and SGN work
- Carry-in comes from the *other* accumulator's flags, this is used for
long arithmetic
- CMP is ~q (see the many CMP A; INC A where values get negated)
- SHR1 is arithmetic shift and retains the sign bit (Mario Kart sprites
and physics are broken without it)
- SHL1 has carry-in per the datasheet, it doesn't seem to be used though
- XCHG probably byteswaps, but it's not used either
- Reversed DR external R/W order again, big-endian seems to break it
byuu described the remaining changes:
You do not need the XML files anymore, bsnes will automatically choose
the new uPD module, and look for dsp1b.bin.
If you make your own XML file, you can force the old HLE mode, or use
a differently-named PROM.
If and when we get the DSP-2,3,4 modules, bsnes v072.11 and above should
already be able to run them, assuming no more emulation core bugs.
Unfortunately, I missed the v072r08 release; it was taken down before
I saw the announcement.
byuu says (about v072r08):
This WIP adds NEC uPD77C25 emulation. Unfortunately it's not at all functional yet, there are way too many things I don't understand about the chip.
I'm absolutely going to need help to complete this.
[...]
For now, you need the included PCB XML to manually map the program/data ROM in, which are included with the archive. You'll have to rewrite the map yourself to run other DSP-1 games, unless they have the same layout as Mario Kart. I am using the US [!] version, name it mariokart.sfc and put all the archive files and the ROM together.
From here, bsnes will load up the ROMs, and start executing instructions. Since the emulation is so incomplete, it just deadlocks on the "Nintendo" logo as if there were no DSP on the cart at all, but if you enable tracing, you'll see it actually starts doing a lot of stuff before getting stuck in a really long and confusing loop.
[Note: the DSP-1B program and data ROMs are not included in this commit.
The PCB XML file mentioned above looks like this:
<?xml version='1.0' encoding='UTF-8'?>
<cartridge region='NTSC'>
<rom>
<map mode='shadow' address='00-3f:8000-ffff'/>
<map mode='linear' address='40-7f:0000-ffff'/>
<map mode='shadow' address='80-bf:8000-ffff'/>
<map mode='linear' address='c0-ff:0000-ffff'/>
</rom>
<ram size='800'>
<map mode='linear' address='20-3f:6000-7fff'/>
<map mode='linear' address='a0-bf:6000-7fff'/>
<map mode='linear' address='70-7f:0000-ffff'/>
</ram>
<upd77c25 program="dsp1b-program.bin" data="dsp1b-data.bin">
<dr>
<map address='00-1f:6000-6fff'/>
<map address='80-9f:6000-6fff'/>
</dr>
<sr>
<map address='00-1f:7000-7fff'/>
<map address='80-9f:7000-7fff'/>
</sr>
</upd77c25>
</cartridge>
Save it as 'mariokart.xml']
byuu says (about v072r09):
Fixes OP/LD RQM=1 on DR modify, Mario Kart can get in-game, but the
track is completely corrupted.
Reorders order of operations for OP, in an attempt to mimic parallelism.
Added support for OP KLM DST.
Added S1 flag setting, probably not correct.
byuu says:
I'm happy enough with the debugger now. Not 100% up to par with the old
one, but it also does some new things the old one didn't.
- step into / step over are disabled unless they can be done safely
- this means step over is usually grayed unless you hit step into first,
due to bsnes not being opcode-based (you can't skip an opcode that is
half-executed)
- you can now trace console output to disk
- stepping the CPU will print stepped SMP opcodes if the checkbox for it
is on and vice versa
- button added to clear the console log
(there was no r05 release posted to the WIP thread)
byuu says:
Updated libsnes to use new file and function names.
Also added EditBox::setCursorPosition for GTK+ and Qt, only used by the
debugger so far so that when text is added, it auto-scrolls to the
bottom.
(there was no r03 release posted to the WIP thread)
byuu says:
nall/snes/smp.hpp created, ~68 addressing modes compared to the CPU's
~27, ugh. All hooked up, you can step into / step over / trace the S-SMP
now as well.
byuu says:
Just debugger work here. About three or four hours to write
nall/snes/cpu.hpp, which is basically opcode encoding information for
disassembly.
byuu says:
- added pause shortcut ('P' key, as pause/break is too finicky)
- pause and auto-pause show on status bar
- added a debugger skeleton, very very primitive and completely unusable
- don't try it yet
- added software filter support
Also included is the new snesfilter library. It has all of the filters
the old one had, as well as scanline filters since that's not in my GUI
anymore
If you want scanlines and other software filters, then you can either
make your own hybrid two-in-one software filter, or make a pixel shader
(I don't have one of those yet.)
byuu says (since v070):
- fixed a regression in the accuracy/compatibility CPU core with IRQ
masking; fixes World Heroes 2
- fixed OAM address reset on $2100 writes for performance PPU core;
fixes Mahjongg 2 and others
- DSP-1 always returns high 8-bits of status register; fixes Ace wo
Nerae! freeze [Jonas Quinn]
- performance core can now take advantage of serial support
- pixel shaders now use a unified XML format; in the future they will
support multi-pass shaders and textures
- major code restructuring
- first public release of phoenix GUI port
- mightymo's cheat code pack is now an external file for the phoenix
port
- phoenix port stores cheat codes in XML format as well, unifying all
file formats to the same markup language
(there was no r15 release posted to the WIP thread)
byuu says:
This mostly contains improvements for nall, like path unification.
This should fix FitzRoy's issue with .. on Windows.
(there was no r13 release posted to the WIP thread)
byuu says:
- nall/string: trim and split functions now take the limit as a template
parameter for clarity, trim_once variants are removed
- quotable.trim<1>("\""); //remove quotes from string
- cheatcode.split<3>(","); //split up to three times, third one is
a description that may have commas
- foobar.trim(" "); //remove any and all spaces
- nall/string: added wildcard() and iwildcard() functions for pattern
matching
- nall/directory: accepts an optional pattern parameter to perform
wildcard matching
- lstring cartridges = directory::contents(path, "*.sfc");
- some people may prefer directory::contents("/path/to/files/*.sfc"),
but I like not having to build a string when you have the path
separated already
- nall/qt: removed entirely, now resides in bsnes/ui-qt/template; I do
intend to replace the check/radio actions with native Qt versions
later
- bsnes/data: new folder, share the parts that both UIs use; bsnes.ico,
bsnes.png, bsnes.Desktop, cheats.xml; simplify Makefile install target
- Makefile: install target now creates .bsnes folder and copies
cheats.xml there for you
- Makefile: gconftool hack removed, not needed for phoenix, will work
around with Qt later
- will probably make bsnes/Qt read the cheats.xml file externally as
well, as that file makes each profile 1MB bigger when embedded
- as such, will probably make bsnes also look in the binary directory
for that file, so Windows users don't have to copy it to their
userdata folder
byuu says:
- removed support for images with copier headers
- phoenix/Windows: Label properly refreshes on text changes, fixes video
settings sliders
- alt/ppu-performance: fixed mosaic Voffset bug, fixes Super Bowling et al
- alt/cpu: fixed CPU::joylatch() reporting, allows serial applications
to work with performance profile
- hooked up SNES::cartridge.basename, allows MSU1 and serial support
with the phoenix UI
- updated UPS patching code for bsnes/Qt, allowing it to compile again,
hidden config option file.bypassPatchCrc32 was removed
byuu says:
- phoenix/All: converted all instances of const char* to const
nall::string&
- above used to require: label.setText(string("FPS: ", fps)); but can
now use: label.setText({"FPS", fps});
- also avoids the need for the internal implementations to have to
check for null string pointers
- phoenix/GTK+: no longer disabling double buffering on the viewport.
Does not cause flickering, and fixes redraw issue on window resize
- phoenix/Qt: like phoenix/GTK+, it will use the default font on the
menubar as well, so child menu items are consistently sized now
- Linux: file browser can list contents of / and won't let you go
higher; Windows needs a similar guard for n:/ or \\
- UPS soft-patching support added
- external XML memory map loading support added
- cartridge folder support added: if folder ends in .sfc and there is
ONE .sfc ROM inside it, it will load the folder as if it were a ROM
- input assignment refreshes text instead of reloading the list, this
saves your position
- auto-advance wasn't working very well, will try again later
- input clear all button removed since it's pretty fast now to do
clear+down:repeat
byuu says:
- added workaround to phoenix/Windows to prevent horizontal scrollbar
always being visible on single-column ListBoxes
- phoenix gains Window::geometry()
- added code to save and restore window positions, as in bsnes/Qt.
Positions are saved to bsnes-phoenix-geometry.cfg this time
- resizing the main window will keep its position onscreen now
There's one issue with GTK+, if you close a window and then call
gtk_window_get_position(), it returns the previously set position rather
than where you actually placed the window. My easy fix of calling
gtk_window_get_position right before actually closing the window didn't
work, so for now you'll have to live with it.
byuu says:
- removed native OS dialog option, I don't plan to add all the code
required to make it optional everywhere
- cheat database supported, although it's external now. Either in the
.bsnes folder or with the binary, named cheats.xml
- cheats.xml is external so that binaries can be much smaller, important
for multiple profiles
- added "find codes" button to cheat editor (need to gray it out
permanently if cheats.xml isn't found)
- added cheat database add window, works the same as bsnes/Qt, but it
will also alert you if you run out of empty cheat slots upon import
- note: I should rename that ok button to "Import"
- hooked up callbacks for multitap/mouse/SS/justifier input
- added mapping for mouse axes and buttons
- used a simplified approach that only lets you map left/middle/right
buttons, but doesn't need a separate popup window or fake controls
- moved capture mouse command to tools menu
- different from Qt where you'd click inside the main window, meant to
be safer from accidental capture, escape still releases capture
- made a skeleton for GUI hotkey support, but the only hotkey is escape
byuu says:
- all three ports of phoenix gain the ability to use
ListBox::setCheckable(), checked(row), setChecked(row, checked
= true);
- cheat editor updated to take advantage of this
Some fun differences between the implementations. Windows was the least
flexible, it only lets you have a check at the start of each item.
Luckily that's all I need for my purposes so it'll work. It's also a lot
easier, as now I don't need a ton of extra code to try and set
per-column checkboxes. Now both Windows and Qt can put text into the
first item with the checkbox, but GTK+ cannot. Further, Qt needs this
because even if you hide the checkbox column, it still tries to search
for typed text from the checkbox column. GTK+ does this too, but unlike
GTK+, Qt lacks an API call to set the search column. Since my code
basically has to change this in real-time since you have to call the
setProperty functions after create(), this means I always set up the
checkbox columns regardless of whether or not they are used. For Qt,
I had to work around this and it'll be an annoying edge case if you try
and use setCheckable(true) and then setCheckable(false), because Qt has
no way to clear the checkboxes from an item once you've enabled them for
the first time. But without doing it this way, there's no way for eg the
ROM file loader to allow type-searching, so that's the way I do it.
Windows works the same, and GTK+ has a separate column (hidden from the
phoenix API standpoint) for the checkboxes, with no column header label
text.
All in all, a major hassle, but it was the only really major GUI hit
from leaving Qt, aside from the horror that's going to be the debugger,
which needs all kinds of highly specialized controls.
byuu says:
- added menu options to select controller port devices, they do actually
work too
- however, input mapping can't map analog axes yet, and the mouse can't
be captured yet, so it's of little use
- added clear and clear all buttons to the input mapper window, mainly
because there was no reason not to (escape clears active input too)
- going to be adding a "special" button in the future that lets you map
mouse axes and buttons
- fixed phoenix/Qt port, both the video rendering and Window::focused()
commands work now
The way I've implemented mouse mapping has always been screwy. So the
special button is going to pop open another window. For digital mapping,
it'll let you choose a mouse button, and for analog mapping, it'll let
you choose an axis. May add in some manual joypad assignment stuff in
there for analog joypad buttons, those things are impossible to
auto-detect.
(there was no r05 release posted to the WIP thread)
byuu says:
- bsnes/phoenix uses XML for per-game cheat codes, markup is identical
to the main database
- added clear and clear all buttons to the cheat code editor
- phoenix/GTK+ sets all child menu elements to match the parent menu font
- phoenix/Windows will draw a black canvas for the Viewport widget
(phoenix/GTK+ still needs this)
byuu says:
- fixed new config file input driver name (you'll have to delete your old config, or change to a different driver and back and restart)
- fixed slot loader windows' OK button placement
- fixed nall/directory.hpp when list size was zero
- rewrote nall/function.hpp, no longer requires <functional> or union tricks
- added state manager
The state manager is a little bit different this time. It's functionally
identical to bsnes/Qt, 100% of the way. But when you save slots, it
stores them in RAM. It only writes the BSA archive upon ROM unload
/ program exit. Yes, this means that technically if the emulator
crashes, you'll lose your states. But a) that very rarely happens, and
b) the old way was thrashing the disk like crazy, every letter you typed
dumped up to 8MB to disk. With this new method, I can simply store
a boolean valid flag before each slot, and pack the file better. Before,
a save on only slot 3 would be 3*state size (~1.2mb), it will now be
3bytes+state size (~400kb.) I have also added a proper signature because
of this, so it will detect when you load an archive for a previous
serializer version and ignore it. When you go to save (unload the game),
if there are no valid slots, the BSA archive gets unlinked (deleted.)
I am also planning a feature around the now-hidden "slot 0". My idea is
for it to be a fallback slot. How many times have you loaded a state
when you meant to save and said, "shit, now I lost some of my progress"?
The idea is that whenever you load a state, right before loading, it
will save to slot 0. When you unload the game, or exit the emulator, it
will also save to slot 0. You will be able to load from slot 0 from the
menu, but not save to it. It will appear at the bottom of the load list.
And lastly, I'll add an advanced option to auto-load slot 0 if it
exists, which will enable "close the emulator and restart where you left
off." functionality.
byuu has traditionally kept these shaders separately, but I don't see
why they shouldn't be stored alongside the code that uses them.
Unlike previous versions of pixel shaders, these are updated to use the
new file-format introduced in v070r03.
byuu says:
- fixed a bug in xml_element::parse() with <![CDATA[...]]> tags
- merged FragmentShader and and VertexShader into Shader, which is an
XML file that contains all relevant data
- updated Qt port to reflect the above
- added support for pixel shaders to the phoenix port
- updated all pixel shaders to use the new format
- ruby won't crash if you give an HLSL driver a GLSL shader or vice
versa, but it will still crash on bad programs
- phoenix::Viewport has its own window class, that paints a black brush
background
[The XML shader] format is subject to change, more specifically I may
change the <source> tag from HLSL shaders.
In the long-long term, it'd be nice to extend the format to allow
multiple shaders to be chained together and to encode base64 texture
files.
But for now, this is good enough.
byuu says:
- phoenix supports onActivate, or return key pressed, on text boxes
- phoenix supports setGeometry() on all widgets
- input settings can now map analog axes and analog buttons
- analog button support is simplified over bsnes/Qt, and it supports the
trigger inversion you see between Xbox 360 and Thrustmaster
controllers
- load cartridge window lets you press enter in the path box to select
the folder, but currently allows invalid folders (makes list empty)
- load cartridge won't reset your view if the folder doesn't change
- this means the last ROM you loaded is highlighted the next time you
go to load cartridge; you're welcome, FitzRoy :P
- removed quit system menu option
- added dummy controller port system menu options, there's no code
behind them yet
- added power/reset menu options, dropped the power checkbox in favor of
a standard power cycle option, removes unnecessary complexity
- added video mode scaling, 1x to 5x; and aspect ratio correction
- added video mode smooth toggle
- added audio settings panel with volume and input frequency adjustment
- config file is where you can control output frequency and latency,
they are too niche for a GUI
- fixed a realpath() crash on Linux when the bsnes binary was in /usr/bin
byuu says:
This release represents the coup de grâce of bsnes/Qt.
Changelog:
- configuration file is now called bsnes-qt.cfg; the first run of this
release will start with a clean state
- MSU1 now supports audio looping via new PCM file format
- disabled state load/save menu due to a serious bug in Qt 4.6.0 for
Windows
- RawInput: all keyboards merged to KB0, it should no longer be required
to reconfigure the keyboard out-of-the-box
- RawInput: fixed a bug where Xbox 360 controller states were being
overwritten by DirectInput controllers
- RawInput: fixed a device sorting bug caused by moving ruby to Unicode
- Direct3D: fixed a pixel shader bug caused by moving ruby to Unicode
- Linux port: fixed sudo make install target
- Linux port: default to gcc/g++ instead of gcc-4.5/g++-4.5 for one last
release
- updated to mightymo's 2010-09-20 cheat pack
byuu says (since v068):
- added new effect toggle tool window, which allows toggling of BG/OAM
graphics layers and DSP audio channels
- added an option to use the native OS file and folder open dialogs
instead of my custom browser
- added a new state selection window
- added frame skipping support, which is only used during fast
forwarding; as a result, fast forward is now ~80% faster
- removed unnecessary icons, added workaround for checkbox/radiobox menu
icons on Linux/GNOME
- added RTS/CTS support to serial simulation
- all cores: OAM high table even address writes should update OAM latch
data register [blargg]
- accuracy core: major improvements to mosaic emulation
- accuracy core: added additional hardware-based caching, resulting in
a ~15% speed boost
- accuracy core: emulated CGRAM address invalidation for writes during
active display
- performance core: added new S-PPU renderer, resulting in a ~10% speed
bost
byuu says:
This is basically the v069 release candidate, heavy testing would really
be appreciated. I'd like for v070 to be the first official phoenix
release, but if a major bug slips past us that will ruin it.
The big change is that save state support was added to the
PPU-performance core.
(there was no r23 release posted to the WIP thread)
byuu says:
Fixes OAM latchdata for all 3 cores and CGRAM address invalidation for
the accuracy core (the only one that really does it because it needs
cycle PPU timing.) Also removes the OAM/CGRAM read/write functions to
put them inside the actual MMIO functions. Easier to handle all the
special cases that way. VRAM is a bit more annoying since there's two
read and two write functions.
This should fix battletech/mechwarrior 3050 palette at least.
byuu says:
Wanted to torture myself, so I implemented the hardest window of all,
the cheat code editor. I had to sacrifice checkboxes inside lists,
unfortunately, but it's a necessary evil. Maybe some day if we can port
checkboxes inside list items to Windows and GTK+, we can add it back. It
should be the only really apparent GUI sacrifice, though. You toggle
cheats by double-clicking them in the list. Easy to do, but not
apparent.
I also added in the focus policy.
byuu says:
Changelog:
- adds synchronize video
- adds synchronize audio
- adds mute audio
- adds advanced settings window with driver selection only
- adds the pretty section header thing I started going toward with Qt
- adds a configuration file, saves to bsnes-phoenix.cfg (I don't make
the .bsnes folder yet)
- the status bar shows [A] for accuracy, [C] for compatibility and [P]
for carburetor
byuu says:
Changelog:
- fixed window casting crash in phoenix
- added perfect forwarding to nall::string variadic templates to fix
file load dialog crash in phoenix
- disabled copy constructors in utf8_t to prevent this problem from
occurring again in the future
- separated canvas window proc by creating a separate class for it
(ironically it was a desktop window causing the first crash)
- use processorArchitecture="*" to make compilation easier
- fixed status bar font assignment in phoenix/Windows
- added InitCommonControls + CoInitialize for XAudio2 on XP
- had to use DirectSound for audio; XAudio2 is crashing on exit which
breaks the profiling (only a problem because you can't change the
drivers without recompiling, there's really no reason to profile
XAudio2 anyway)
byuu says:
This adds proper manifest files to get the nice XP/Vista controls. Need
to find a way to auto-detect MinGW 32 vs 64 since I can't use $shell or
`` on gcc -v on Windows. For now you have to edit the
ui-phoenix/Makefile by hand.
I've implemented the video settings window. I am going to be using
separate windows this time. As nice as having everything in one place
was, I didn't like being forced to stretch things to fill out the
one-size-fits-all tab window I was using before. That and I don't feel
like implementing tab support with phoenix anyway.
The menu gets a load cartridge command, and bsnes writes save RAM files
now. Loading by file dialog crashes on 64-bit. Something's fucked up
there, but I don't know what. Again, help would be great here :)
byuu says:
This WIP fixes the Mode7 repeat issue in the accuracy core.
More importantly, it's the first build to include phoenix. There is
a stub GUI that does basically nothing right now. It will give you
a window, a command to close the emulator, and an FPS meter so you can
tell how fast it is. To load a ROM, you have to drag the ROM on top of
the binary. I don't know if it will work if the filename+path has spaces
in it or not, so avoid that to be safe.
[...]
For some reason, the 64-bit binary sometimes crashes on start, maybe 1:6
times. So just keep trying. I don't know what's up with that, I'd
appreciate if someone here wanted to debug that for me though :D
One really good bit of news, there was that old hiro bug where keyboard
input would cause the main window to beep. I spied on the main event
loop and, as suspected, the status bar was getting focus and rejecting
key presses. What. The. Fuck. Why would a status bar ever need focus? So
I set WM_DISABLED on it, which luckily leaves the font color alone.
I also had to use WM_DISABLED on the Viewport widget that I use for
video output. These two combined let me have my main window with no
keyboard beeping AND allow tab+shift-tab to work as you'd expect on
other windows, so hooray.
Now, at the moment there's no Manifest included, because Microsoft for
some reason includes the processorArcitecture in the file. So I can't
use the same manifest for 32-bit and 64-bit mode, or the binary will
crash on one or the other. Fuck. So the status bar may look old-school
or something, whatever, it's only temporary.
Next up, my goal is to avoid the hiro icon corruption bullshit by making
phoenix itself try and use an internal resource icon. So just compile
your app with that resource icon and voila, perfect icon. Not in there
yet so you get the white box.
Input is hard-coded, up/down/left/right/z/x/a/s/d/c/apostrophe/return.
Lastly, compilation is ... in a serious state of flux. The code is set
to compile bsnes/phoenix-gtk right now. Try it at your own risk. Give me
a few WIPs to get everything nice and refined. Ubuntu users will need
gcc-4.5, which you can get by adding the Maverick Meerkat repository,
updating apt, installing the gcc-4.5 + g++-4.5 packages, and then
removing and re-updating your apt/sources.list file so you don't end up
fucking your whole system when you run apt again in the future.
For anyone who can work with all of that, great! Please post a framerate
comparison between 32-bit and 64-bit builds. Any game, any screen, so
long as the FPS is not fluctuating when you measure it (eg don't do it
during an attract sequence.)
If anyone complains about the 64-bit binary not working and it turns out
they are on 32-bit Windows, they are going to be removed from this WIP
forum :P
byuu says:
This hopefully fixes vertical and horizontal mosaic with the accurate
S-PPU core.
It also adds frame-skipping support to the compatibility and performance
S-PPU cores. This is not visible to the user interface, because I feel
that virtually nobody is going to play with frame-skipping on when they
could use a faster emulation with it off. However, I did use it to
enhance the 'Fast Forward' key. When you press it, it will now turn off
video and audio sync, and set a frameskip of 9. This allows you to speed
things up an additional ~60% over your max theoretical speed without
frameskipping. ~35% with the compatible core, because the PPU is less of
a bottleneck for it. Slowdown was improved, it will turn on audio sync
if it is off until you release the key to ensure you actually get 30fps.
Eventually it'd probably be wise to set a cap on the fast forward speed,
but I hardly think it's an issue on today's computers.
byuu says:
Testing this one and all the new features would be appreciated.
New features?
http://img203.imageshack.us/img203/505/bsnes20100907.jpg
[For future reference, the above URL points to a screenshot of bsnes' Qt
GUI running with the following windows (apart from the main window) visible:
- A new 'state selection' dialog wih buttons labelled 'Slot 1' through
'Slot 10'.
- The 'Tools' dialog open to a new 'Effect Toggle' tab, which has
checkboxes for the various PPU backgrounds and sprites, and SPU
channels.
- The 'Configuration Settings' dialog open to the 'Advanced' tab, with
a "Use Native OS File Dialogs" checkbox.
- A 'Load Cartridge' dialog, which is the standard Windows file-open
dialog.
It seems these are the new features referred to. -- Ed]
byuu says:
This adds a new "Effect Toggle" window to the tools tab list. There's no
menu entry for it yet, oversight, but you can go to another tool and tab
to it.
The effect toggle window lets you toggle background/OAM layers on
a per-priority basis and DSP sound channels. This only works with the
compatibility and performance cores, because I'm not going to allow
accuracy-violating hacks like that into the core.
Non-essential icons have been removed, there's six of them left at the
moment. I am too much of a consistency guy to only have some scattered
around. I know other apps do that, but I'm not going to do that, and
I grow tired of trying to hammer in icons that don't really represent
the actions. Anyway, it still looks pretty good I think.
byuu says:
Holy hell, that was a total brain twister. After hours of crazy bit
twiddling and debug printf's, I finally figured out how to allow both
lores and hires scrolling in the accurate PPU renderer. In the process,
I modified the main loop to run from -7 to 255, regardless of the hires
setting, and perform X adjustment inside the tile fetching. This fixed
a strange main/subscreen misalignment issue, so I was able to restore
the proper sub-then-main rendering for the final screen output stage.
Code looks a good bit cleaner this way overall.
I also added load state and save state menus to the tools menu, so you
can use the menubar to load and save to ten slots. I am thinking that
I should nuke the icons. As pretty as they are, it's getting tiresome
trying to find icons for everything, I have no pictures to represent
loading or saving a slot, nor to represent individual slots. I'll just
stick to radios and checkboxes.
byuu says:
Bug-fix night for the new PPUs.
Accuracy:
Fixed BG palette clamping, which fixes Taz-Mania.
Added blocking for CGRAM writes during active display, to match the
compatibility core. It really should override to the last fetched
palette color, I'll probably try that out soon enough.
Performance:
Mosaic should match the other renderers. Unfortunately, as suspected, it
murders speed. 290->275fps. It's now only 11fps faster, hardly worth it
at all. But the old rendering code is really awful, so maybe it's for
the best it gets refreshed.
It's really tough to understand why this is such a performance hit, it's
just a decrement+compare check four times per pixel. But yeah, it hits
it really, really hard.
Fixed a missing check in Mode4 offset-per-tile, fixes vertical alignment
of a test image in the SNES Test Program.
(there was no r11 release posted to the WIP thread)
byuu says:
This took ten hours of mind boggling insanity to pull off.
It upgrades the S-PPU dot-based renderer to fetch one tile, and then
output all of its pixels before fetching again. It sounds easy enough,
but it's insanely difficult. I ended up taking one small shortcut, in
that rather than fetch at -7, I fetch at the first instance where a tile
is needed to plot to x=0. So if you have {-3 to +4 } as a tile, it
fetches at -3. That won't work so well on hardware, if two BGs fetch at
the same X offset, they won't have time.
I have had no luck staggering the reads at BG1=-7, BG3=-5, etc. While
I can shift and fetch just fine, what happens is that when a new tile is
fetched in, that gives a new palette, priority, etc; and this ends up
happening between two tiles which results in the right-most edges of the
screen ending up with the wrong colors and such.
Offset-per-tile is cheap as always. Although looking at it, I'm not sure
how BG3 could pre-fetch, especially with the way one or two OPT modes
can fetch two tiles.
There's no magic in Hoffset caching yet, so the SMW1 pixel issue is
still there.
Mode 7 got a bugfix, it was off-by-one horizontally from the mosaic
code. After re-designing the BG mosaic, I ended up needing a separate
mosaic for Mode7, and in the process I fixed that bug. The obvious
change is that the Chrono Trigger Mode7->Mode2 transition doesn't cause
the pendulum to jump anymore.
Windows were simplified just a tad. The range testing is shared for all
modes now. Ironically, it's a bit slower, but I'll take less code over
more speed for the accuracy core.
Speaking of speed, because there's so much less calculations per pixel
for BGs, performance for the entire emulator has gone up by 30% in the
accuracy core. Pretty neat overall, I can maintain 60fps in all but,
yeah you can guess can't you?
(there was no r09 release posted to the WIP thread)
byuu says:
It is feature-complete, but horizontal mosaic is less accurate. I have
an idea for a mosaic color ring buffer to get it equally accurate, but
I haven't implemented it yet. For now it's just a simple x & ~(mosaic >>
1) trick that is passable.
Hires blending was left out, as it's more processor intensive and
blargg's NTSC does a better job with that anyway.
There's some OPT vertical positioning issues in the SNES Test Program's
character test; Goodbye, Anthrox has some sort of fast CPU DMA issue;
etc.
Total speedup is a mere 13.5%. Not quite the 50% I wanted in the best
case, but I'll take what I can get.
254->289fps in Zelda 3 on my E8400 now. There's another 15% hiding with
blargg's SMP and 5-10% with blargg's fast DSP, but they lose too much
accuracy. It'd put me at or below Snes9X accuracy, while still being 50%
slower.
SSE2 was performing worse this time, both on x86 and amd64, so I left
that optimization off.
So, barring a miracle, this is about the best it's going to get.
byuu says:
This gets the basic new PPU skeleton up and running, still missing
a lot:
- Mode7
- direct color mode
- OAM color exemption (this one will impact performance negatively)
- vertical mosaic
- horizontal mosaic (this one may impact performance negatively)
- offset per tile
- interlace
- hires
- pseudo-hires
But it's correct enough to play most games okay.
So far, the new PPU is about 11% faster on my Atom, and 17% faster on my
E8400. I was hoping for more, but the window masking and sprite
calculation is just kicking my ass.
The 11/17 figure is total emulator overhead, so that means raw PPU vs
PPU, the new one is at least 22-34% faster than the old one.
I don't really have any ideas for additional optimizations. I'm even
using little-endian word reads where applicable. But at any rate, I need
to get all the above implemented correctly before trying to push
optimizations even further.
(there was no r06 release posted to the WIP thread)
byuu says:
New PPU renderer is coming along. Lots of new ideas, especially with
regards to the way the background renders in tiles rather than in
pixels. That skips the need for tile caching and compares, and it even
gets scrolling right.
The sprite item+tile lists are computing, but they are not rendering
yet.
It's a good deal faster for now, obviously, because 90% of the PPU
features are missing.
byuu says:
Started over again on the new S-PPU, heh. Three hours wasted last night
I guess.
I wanted to make the new one more like the accurate core in its
structure: multiple class instances for each background. It makes the
code easier to read, results in less structure insanity
(regs.main_enabled[bg] -> main_enabled), and will probably make it a tad
easier to parallelize if we want to go that route eg for the ARM.
Still very incomplete.
(there was no r03 release posted to the WIP thread)
byuu says:
This should provide hardware-accurate mosaic support in the accurate
renderer, with the exception that I'm still not sure what mid-frame
vertical mosaic or mid-scanline horizontal mosaic writes do. Either the
code I have is correct, or it bypasses the mosaic adjust and gives the
exact H/V positions.
I've also renamed the fast folder to alternative (thinking about naming
it simply alt instead), and started on a brand new PPU renderer. So far
it's just a barebones setup with some MMIO support and VRAM/OAM/CGRAM
writing. I'm not even confident that I can get this to be faster than
the current scanline renderer, but it's the only avenue that we have
left for any kind of significant bsnes speedup, so I have to try. I'm
going to finish up the MMIO stuff first, that way we have a clean slate
with no actual rendering. And then from here we can try various
different approaches.
byuu says:
This adds mosaic improvements to the S-PPU dot renderer. Specifically,
it eliminates the mosaic_table entirely, and performs mosaic adjustment
per pixel instead. It also moves from a mosaic countdown for mosaic Y to
a mosaic counter (incrementing).
In the process, I realized Sim Earth's map was broken, so I fixed that.
In doing so, I also fixed my old Mode7 demo that was always off-by-one,
causing different results on real hardware versus emulation. But then
I broke both Final Fantasy 5 and Air Strike Patrol effects that use
Mode7 but no mosaic.
I'm not really sure what's going on, but I think I am close. This is the
first time I can reproduce the Mode7 test ROM results without screwing
with M7Y which was obviously wrong. I think that somehow a mosaic >=
1 is glitching the Ycounter for the BG layers to tick one extra time.
There's a workaround that's not very nice to get everything going right
now. It could very well be that the workaround is hardware accurate, but
I can't help but feel there's a more eloquent way of doing this.
byuu says:
This adds RTS/CTS support to the serial communications emulation. Okay,
well the PC acts as if it is always ready, because it always is even on
the real thing, but the PC-waiting-for-SNES side works.
Source only, hardware communication only works on OS X and Linux
(Windows serial communication is totally different, I don't feel like
writing a Windows version), more documentation will come later.
byuu describes the changes since v067:
This release officially introduces the accuracy and performance cores,
alongside the previously-existing compatibility core. The accuracy core
allows the most accurate SNES emulation ever seen, with every last
processor running at the lowest possible clock synchronization level.
The performance core allows slower computers the chance to finally use
bsnes. It is capable of attaining 60fps in standard games even on an
entry-level Intel Atom processor, commonly found in netbooks.
The accuracy core is absolutely not meant for casual gaming at all. It
is meant solely for getting as close to 100% perfection as possible, no
matter the cost to speed. It should only be used for testing,
development or debugging.
The compatibility core is identical to bsnes v067 and earlier, but is
now roughly 10% faster. This is the default and recommended core for
casual gaming.
The performance core contains an entirely new S-CPU core, with
range-tested IRQs; and uses blargg's heavily-optimized S-DSP core
directly. Although there are very minor accuracy tradeoffs to increase
speed, I am confident that the performance core is still more accurate
and compatible than any other SNES emulator. The S-CPU, S-SMP, S-DSP,
SuperFX and SA-1 processors are all clock-based, just as in the accuracy
and compatibility cores; and as always, there are zero game-specific
hacks. Its compatibility is still well above 99%, running even the most
challenging games flawlessly.
If you have held off from using bsnes in the past due to its system
requirements, please give the performance core a try. I think you will
be impressed. I'm also not finished: I believe performance can be
increased even further.
I would also strongly suggest Windows Vista and Windows 7 users to take
advantage of the new XAudio2 driver by OV2. Not only does it give you
a performance boost, it also lowers latency and provides better sound by
way of skipping an API emulation layer.
Changelog:
- Split core into three profiles: accuracy, compatibility and
performance
- Accuracy core now takes advantage of variable-bitlength integers (eg
uint24_t)
- Performance core uses a new S-CPU core, written from scratch for speed
- Performance core uses blargg's snes_dsp library for S-DSP emulation
- Binaries are now compiled using GCC 4.5
- Added a workaround in the SA-1 core for a bug in GCC 4.5+
- The clock-based S-PPU renderer has greatly improved OAM emulation;
fixing Winter Gold and Megalomania rendering issues
- Corrected pseudo-hires color math in the clock-based S-PPU renderer;
fixing Super Buster Bros backgrounds
- Fixed a clamping bug in the Cx4 16-bit triangle operation [Jonas
Quinn]; fixing Mega Man X2 "gained weapon" star background effect
- Updated video renderer to properly handle mixed-resolution screens
with interlace enabled; fixing Air Strike Patrol level briefing screen
- Added mightymo's 2010-08-19 cheat code pack
- Windows port: added XAudio2 output support [OV2]
- Source: major code restructuring; virtual base classes for processor
- cores removed, build system heavily modified, etc.
byuu says:
Re-added blargg's DSP, but this time I merged only spc_dsp and also
fixed the initial regs for Dual Orb II. Which restores the 5-10% speedup
on the compatibility and performance cores. Fixed the initial register
values for the fast CPU core, which fixes Armored Police and the other
Atlus game's title screen in the performance core. Added a missing
debugvirtual prefix to op_step, which fixes CPU stepping in the
performance core. I was using the description field for profile
identification in savestates, but that was of course the description for
the state manager. Whoops. Added a new field for profile name to the
save states, and fixed the state manager to work with that change.
Adjusted the about screen colors, which is how you can tell which core
you're using without it being annoying. Probably did some other stuff
too, meh.
byuu says:
Removed snes_spc, and the fast/smp + fast/dsp wrappers around it.
Cloned dsp to fast/dsp, and re-added the state machine, affects
Compatibility and Performance cores.
Added debugger support to fast/cpu, with full properties list and Qt
debugger functionality.
Rewrote all debugger property functions to return data directly:
- this avoids some annoying conflicts where ChipDebugger::foo()
overshadows Chip::foo()
- this removes the need for an extra 20-200 functions per debugger
core
- this makes the overall code size a good bit smaller
- this currently makes PPU::oam_basesize() inaccessible, so the OAM
viewer will show wrong sprite sizes
Used an evil trick to simplify MMIO read/write address decoding:
- MMIO *mmio[0x8000], where only 0x2000-5fff are used, allows direct
indexing without -0x2000 adjust
So end result: both save states and debugger support work on all three
cores now. Dual Orb II sound is fixed. The speed hit was worse than
I thought, -7% for compatibility, and -10% for performance. At this
point, the compatibility core is the exact same code and speed as v067
official, and the performance core is now only ~36-40% faster than the
compatibility core. Sigh, so much for my dream of using this on my
netbook. At 53fps average now, compared to 39fps before. Profiling will
only get that to ~58fps, and that's way too low for the more intensive
scenes (Zelda 3 rain, CT black omen, etc.)
It would probably be a good idea to find out why my DSP is so much
slower than blargg's, given that it's based upon the same code. The
simple ring buffer stuff can't possibly slow things down that much.
More precisely, it would probably be best to leave blargg's DSP in the
performance core since it's a pretty minor issue, but then I'd have to
have three DSPs: accuracy=threaded, compatibility=state-machine,
performance=blargg. Too much hassle.
Only code in the core emulator now that wasn't at the very least
rewritten for bsnes would be the DSP-3 and DSP-4 modules, which are
really, really lazily done #define hacks around the original C code.
byuu says:
Fixed bsnes launcher on Windows XP
Fixed Windows bsnes launcher internationalization support (emulator can
be in a folder with spaces and Japanese characters, and you can drag
a Japanese file name onto the launcher, and it will load it properly)
Moved fast CPU to use a switch table for MMIO, unfortunately for no
speed gain
Bus::read/write take uint24 parameters for address, luckily no speed
penalty
MMIOAccess gained a handle() function, and hid the mmio[] table. Makes
hooking it cleaner
Added malloc.h header to nall/function.hpp to fix a ridiculous GCC 4.5.0
error
Fixed a fairly large bug in the fast CPU IRQ handler, which fixes
Robocop et al
Forgot to bump revision to .24 in the compiled binaries, too lazy to
recompile or hex edit to change them
Unfortunately, in order to add nice battery usage, I have to add the
sleep calls to the video and audio wait loops. But they don't know
anything about the GUI and its settings, nor do I really want to make
them know about this setting. I do not want to force allow it. Even with
the media timer trick, Sleep(0) makes Vsync+Async fail a lot more
frequently than never sleeping at all. I would rather laptop users
suffer 100% utilization of a single core than for all users to not be
able to get good audio+video sync. Not sure what to do about that, so
I'll probably just remove the battery usage comment from performance
mode for now.
byuu says:
Added missing $4200 IRQ lock, which fixes Chou Aniki on the fast CPU
core, so slower PCs can get their brotherly love on.
Added range-based controller IOBit latching to the fast CPU core, which
enables Super Scope and Justifier support. Uses the priority queue as
well, so there is zero speed-hit. Given the way range-testing works, the
trigger point may vary by 1-2 pixels when firing at the same spot. Not
really a big deal when it avoids a massive speed penalty.
Fixed PAL and interlace-mode HVIRQs at V=0,H<2 on the fast CPU core.
Added the dot-renderer's sprite list update-on-OAM-write functionality
to the scanline-based PPU renderer. Unfortunately it looks like all the
speed gain was already taken from the global dirty flag I was using
before, but this certainly won't hurt speed any, so whatever.
Added #ifdef to stop CoInitialize(0) on non-Windows ports.
Added #ifdefs to stop gradient fade on Windows port. Not going to fuck
over the Linux port aesthetic because of Qt bug #47,326,927. If there's
a way to tell what Qt theme is being used, I can leave it enabled for
XP/Vista themes.
Moved HDMA trigger from 1104 to 1112, and reduced channel overhead from
24 to 16, to better simulate one-cycle DMA->CPU sync.
Code clarity: I've re-added my varint.hpp classes, and am actively using
them in the accuracy cores. So far, I haven't done anything that would
detriment speed, but it is certainly cool. The APU ports exposed by the
CPU and SMP now take uint2 address arguments, the CPU WRAM address
register is a uint17, and the IRQ H/VTIME values are uint10. This
basically allows the source to clearly convey the data sizes, and
eliminates the need to manually mask values when writing to registers or
reading from memory. I'm going to be doing this everywhere, and it will
have a speed impact eventually, because the automation means we can't
skip masks when we know the data is already masked off.
Source: archive contains the launcher code, so that I can look into why
it's crashing on XP tomorrow.
It doesn't look like Circuit USA's flags are going to work too well with
this new CPU core. Still not sure what the hell Robocop vs The
Terminator is doing, I'll read through the mega SNES thread for clues
tomorrow. Speedy Gonzales is definitely broken, as modifying the MDR was
breaking things with my current core. Probably because the new CPU core
doesn't wait for a cycle edge to trigger.
I was thinking that perhaps we could keep some form of cheat codes list
to work as game-specific hacks for the performance core. Keeps the hacks
out of the emulator, but could allow the remaining bugs to be worked
around for people who have no choice but to use the performance core.
byuu says:
Added OV2's XAudio2 driver (it's better and faster than the DirectSound
one)
Fixed DirectInput keypad number codes
Added launcher to make the profiles work
Profiles now called: Accuracy, Compatibility, Performance (not debating
names anymore)
The launcher isn't going to work on OS X because of the .app folder
bullshit (yes, yes, .sfc folders.)
It also crashes on Windows XP for god only knows what reason. Works fine
on Windows 7 and Linux. So XP users, rename the .dll files to .exe to
test this release. I'll fix it on Monday.
The color highlighting fucks up the radio boxes on the Windows classic
theme, because Nokia can't afford a god damn QA team.
Lastly, I forgot to add launcher to the make archive-all command, so the
source for it will be in the next WIP.
byuu says:
This moves toward a profile-selection mode. Right now, it is incomplete.
There are three binaries, one for each profile. The GUI selection
doesn't actually do anything yet. There will be a launcher in a future
release that loads each profile's respective binary.
I reverted away from blargg's SMP library for the time being, in favor
of my own. This will fix most of the csnes/bsnes-performance bugs. This
causes a 10% speed hit on 64-bit platforms, and a 15% speed hit on
32-bit platforms. I hope to be able to regain that speed in the future,
I may also experiment with creating my own fast-SMP core which drops bus
hold delays and TEST register support (never used by anything, ever.)
Save states now work in all three cores, but they are not
cross-compatible. The profile name is stored in the description field of
the save states, and it won't load a state if the profile name doesn't
match.
The debugger only works on the research target for now. Give it time and
it will return for the other targets.
Other than that, let's please resume testing on all three once again.
See how far we get this time :)
I can confirm the following games have issues on the performance
profile:
- Armored Police Metal Jacket (minor logo flickering, not a big deal)
- Chou Aniki (won't start, so obviously unplayable)
- Robocop vs The Terminator (major in-game flickering, unplayable)
Anyone still have that gigantic bsnes thread archive from the ZSNES
forum? Maybe I posted about how to fix those two broken games in there,
heh.
I really want to release this as v1.0, but my better judgment says we
need to give it another week. Damn.
byuu says:
Since we're now talking about three splits, that's getting a bit out of
hand.
This WIP combines everything back into one project again. Added the
src/fast folder that has all the speed-oriented cores.
A slight slowdown to csnes from what it was before, I'm using blargg's
accurate DSP. I just don't like the idea of releasing a less accurate
DSP core than Snes9X v1.52 has. Plus the fast DSP core doesn't serialize
yet.
I moved back to snes_spc 0.9.0 because I care more about Tales and Star
Ocean than I do about Earthworm Jim 2. So if you try EWJ2 on csnes,
expect it to sound like it does on Snes9X. In other words, don't wear
headphones if you value your hearing.
The middle-of-the-road bsnes core uses blargg's accurate DSP, because
it's about 3% faster than mine which removes all of blargg's
optimizations. There is absolutely no accuracy loss here. bsnes v067.20
that is included should be equal to v067 official.
Performance:
Code:
asnes = 58fps
bsnes = 172fps +2.97x
csnes = 274fps +1.59x +4.72x
The binaries are not profiled, so that's an additional 15% slower from
the previous builds.
Save states only work on asnes, as I don't know how to serialize
blargg's cores yet. The copy_func thing is very confusing to me for some
reason. The debugger won't work anywhere.
Outside of that, please go ahead and bug test. Once I get the debugger
and save states working, I'll build some profiled v1.0 releases for all
three, and we can test that for a bit and then release.
byuu says:
12-15% faster than v067.10, and my Atom never goes below 58fps for
normal lo-res games at this point. Just a little more and I can leave
Async on. That's pretty much it though for the low hanging fruit.
Everything else will be a lot of work for a little gain. Speedups are
from range testing across scanline boundaries and from using blargg's
fast DSP core.
Snes9X is now only 1.93x faster than bsnes, and bsnes is now faster than
Super Sleuth.
I also fixed the Circuit USA menus (HDMA timing adjustment), Wild Guns
flickering (IRQ lock) and Jumpin' Derby (external IRQ triggering.)
There's definitely a lot of troublesome games, mostly the same ones we
had in the past (Koushien 2, Robocop vs The Terminator, etc.) I'm
definitely going to debug Starfox, but I may not bother with some of the
more obscure ones.
byuu says:
I wrote a new CPU core from scratch. It has range-based IRQs, and is
good enough even to run F-1 Grand Prix and Sink or Swim. It also uses
a binary min-heap array for the timing priority queue. This resulted in
a ~40% speedup.
I also added in blargg's snes_spc library, which is an S-SMP + S-DSP
emulator. I am still using his accurate DSP core, and not the fast one.
This gives an additional ~10% speedup.
THIS IS NOT PERFECT, THERE WILL BE BUGS!
I already know that Tales of Phantasia and Star Ocean are hitting some
edge cases. Now that it's fast enough, hopefully blargg can take a look
at it. Something he couldn't test before because you can't rip SPCs of
these games, so it's probably something simple.
My CPU core also doesn't nail every last possible edge case. So things
like Wild Guns and the two or three games that rely on NMI/IRQ hold
aren't going to work ... yet. Be patient.
The SuperFX and SA-1 cores are still cycle-accurate. It wouldn't hurt
compatibility to reduce their precision a bit.
End result is that you can now get well over 60fps in normal games even
n a first-generation Intel Atom.
byuu says:
This adds some sync.sh improvements to make it handle errors more
gracefully.
It also updates asnes a good bit. All of the four base processors now
have all publicly accessible functions right at the top of the main
headers, and everything else is private. This is to allow these headers
to essentially take the place of the previous base classes in the old
bsnes-merged format. So if there's something public there, you need to
implement that exact function to make your own module.
I removed the frame counter from the PPU, as it has nothing to do with
emulation. That now resides inside the Qt -> SNES interface code. Quite
amazing, I was actually saving the frame counter into the save state
files before, yuck.
Removed some baggage in the System class: it was friending a bunch of
long-dead functions and classes.
Forgot to re-add the CHEAT_SYSTEM define to info.hpp, so that's been put
back.
byuu says:
This fixes libsnes and debugger builds, and collapses bsnes/ppu/bppu to
bsnes/ppu and bsnes/dsp/sdsp to bsnes/dsp. It also introduces
bsnes/sync.sh, which will synchronize all of asnes/ with bsnes/,
excepting the custom speed-focused modules. So far, that's bsnes/ppu
(scanline renderer) and bsnes/dsp (state machine.)
Should make keeping the two ports in sync much, much easier. It's
basically the same thing as before, only you run sync.sh and have a few
duplicated folders now. May make it clearer by creating a stub/ or src/
folder inside bsnes to do all of the copying, so that you only see the
custom folders in bsnes/' root directory.
// Do NOT use rb.size() later in the code, since it'll include the padding.
// We should only need one "max_mult_minus1" here, not two, since it won't matter if it over-reads(due to doing "max_mult_atatime" multiplications at a time
// rather than just 1, in which case this over-read wouldn't happen), from the first half into the duplicated half,
// since those corresponding coefficients will be zero anyway; this is just to handle the case of reading off the end of the duplicated half to
if(bsl!=asl||bsl==0)returndest;//patterns must be the same length for 1:1 replace
for(unsignedi=0;i<sl;i++){
for(unsignedl=0;l<bsl;l++){
if(dest[i]==before[l]){
dest[i]=after[l];
break;
}
}
}
returndest;
}
}
#endif
Loaded 100 of 2227 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.