The real implementation is harder because it conflicts with how the
the VR4300 pipeline is emulated, but at the end of the day in the happy
path these functions are LW/SW. So instead of just refusing to emulate
them, better fallback to LW/SW.
IS Viewer emulation is currently gated by a command-line flag. All
other major emulators supporting ISViewer (Ares, dillonb, m64p) enable
it by default, and it does not seem to create any problem.
To help homebrew developers discover the feature without showing logs
by default, change the code to always emulate the ISViewer hardware
and add a warning if the ROM uses it but the command line flag was
not specified. This should point users towards correct usage, and
prevents possibly-verbose logs to be shown by default.
Nintendo 64 homebrew community is standardizing on a convention to
declare the save memory type as a header flag. This convention has been
first introduced by EverDrive 64 as a way to handle games not present
in their DB, but it's been since adopted by libdragon as well.
With this commit, cen64 will automatically configure the correct savetype
for homebrew ROMs using the special header flag.
I've also added support for a 1Mbit SRAM savetype. This was never used
in commercial games but it is available with EverDrive64 and is one of
the possible configuration options. It costs nothing to support it and
may help development of homebrew games that decide to use that savetype.
Currently, the experience of cen64 binaries of Windows is not the
greatest, to be kind. If you get the binary and double-click on it,
you get nothing (no feedback whatsoever). If you run it from the
console, you get nothing (no command line help is shown). I am not sure
how Windows users ever manage to use it.
This happens because the binary is linked as a windowed application,
but when run with no command line applications, it exits after printing
the help with printf, which does nothing since no console is
attached to the windowed application.
This PR improves the usability on Windows. It compiles cen64 has a
console application (as was meant to be used), so that the help text
or any other stdout/stderr output is now visible on console. Moreover,
to provide a decent experience to users double-clicking on the
binary, it displays an error message explaining that it should be run
from the command line instead.
Fixes a Segfault when loading Dezaemon 3D.
* Unfortunately, Dezaemon 3D does not actually work yet. It appears to
fail the SRAM test, which still needs further investigation.
Adds an option alias for sram256k to disambiguate with new sram768k option.
1) Setting SP_PC was not resetting the pipeline. This caused that
changing the PC within a HALT/UNHALT sequence was still causing
previous instructions in the pipeline (at the old address) to be
executed. This is not how the hardware works: SP_PC is immediate and
discards the whole pipeline.
2) BREAK did not correctly halt the processor at the right instruction,
which in turn caused resumption after HALT to execute the wrong
set of instructions. This was caused by the fact that the SP_STATUS
change was written into the EXDF latch, which in turn takes 3 cycles
to reach completion. Instead, we now use the DFWB latch, and we cause
it to abort the RSP cycle if the processor is halted. This happens
at the beginning of next cycle, which is the correct moment.
2bis) Since we are at it, use rsp_status_write to modify the RSP in
this case, rather than a direct write to the register. This change
fixes a race condition: SP_STATUS must be accessed atomically when
cen64 runs in multithreaded mode. To use rsp_status_write, we need
to introduce a nonexisting SP_SET_BROKE bit: we use the MSB, but then
mask it out in MTC0 to avoid some code to inadvertently have that bit
set.
3) When unhalting after BREAK, it's important to keep the correct
PC which comes from the EX stage (the one that was going to be
executed if BREAK didn't occur). Before, it was using the IF PC (fetch)
which is farther in the future.
Fixes#155
* Set local time offset when writing to Joybus or 64DD RTC.
* Refactor get_local_time to use ISO C Time APIs.
Special thanks to @jago85 and @LuigiBlood for their research!
This is now basically perfect compared to real hardware. Verified
used the extensive testsuite here: https://github.com/rasky/n64_pi_dma_test
The only missing part is timing and making the transfer happen in
background, at least block by block.
First, since the internal register is kept in CPU cycles (not RCP cycles),
we need to double the value written via MTC0/DMTC0.
Second, writing a count equal to compare would cause an infinite loop
because the fault would be triggered while PC was on the instruction
doing MTC0 itself, which would be then re-executed at the end of the
exception. On real hardware, in general, when COUNT==COMPARE, the
interrupt happens a few cycles later, enough for PC to move to other
opcodes. Instead of trying to implement this, I've simply made sure
that the interrupt happened after the opcode was executed rather than
before. Also, since the internal counter is in CPU cycles, we make
sure to only raise the CAUSE bit once.
Currently, all load/store opcodes (with the exception of LWL/LWR) mask
the lowest bit of address that causes a TLB exception in the BADVADDR
COP0 register. This is wrong because the VR4300 reports the exact
faulting address in that register, the reason being that the exception
handler must require it.