2012-02-29 12:59:48 +00:00
|
|
|
//ARMv3 (ARM6)
|
2012-02-26 07:59:44 +00:00
|
|
|
|
|
|
|
struct ArmDSP : public Coprocessor {
|
Update to v086r15 release.
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.
2012-03-02 11:07:17 +00:00
|
|
|
uint8 *firmware;
|
|
|
|
uint8 *programROM;
|
|
|
|
uint8 *dataROM;
|
|
|
|
uint8 *programRAM;
|
2012-02-26 07:59:44 +00:00
|
|
|
|
|
|
|
#include "registers.hpp"
|
|
|
|
|
|
|
|
static void Enter();
|
|
|
|
void enter();
|
Update to v086r16 release.
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.
2012-03-07 13:03:15 +00:00
|
|
|
void tick(unsigned clocks = 1);
|
2012-02-26 07:59:44 +00:00
|
|
|
|
|
|
|
void init();
|
|
|
|
void load();
|
|
|
|
void unload();
|
|
|
|
void power();
|
|
|
|
void reset();
|
Update to v086r15 release.
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.
2012-03-02 11:07:17 +00:00
|
|
|
void arm_reset();
|
|
|
|
|
|
|
|
ArmDSP();
|
|
|
|
~ArmDSP();
|
2012-02-26 07:59:44 +00:00
|
|
|
|
|
|
|
uint8 mmio_read(unsigned addr);
|
|
|
|
void mmio_write(unsigned addr, uint8 data);
|
|
|
|
|
|
|
|
//opcodes.cpp
|
|
|
|
bool condition();
|
2012-02-27 00:18:50 +00:00
|
|
|
void opcode(uint32 data);
|
2012-02-29 12:59:48 +00:00
|
|
|
void lsl(bool &c, uint32 &rm, uint32 rs);
|
|
|
|
void lsr(bool &c, uint32 &rm, uint32 rs);
|
|
|
|
void asr(bool &c, uint32 &rm, uint32 rs);
|
|
|
|
void ror(bool &c, uint32 &rm, uint32 rs);
|
|
|
|
void rrx(bool &c, uint32 &rm);
|
2012-02-26 07:59:44 +00:00
|
|
|
|
2012-02-29 12:56:21 +00:00
|
|
|
void op_multiply();
|
2012-02-28 11:21:18 +00:00
|
|
|
void op_move_to_status_register_from_register();
|
|
|
|
void op_move_to_register_from_status_register();
|
2012-02-27 00:18:50 +00:00
|
|
|
void op_data_immediate_shift();
|
2012-02-28 11:10:02 +00:00
|
|
|
void op_data_register_shift();
|
2012-02-28 11:21:18 +00:00
|
|
|
void op_data_immediate();
|
2012-02-26 07:59:44 +00:00
|
|
|
void op_move_immediate_offset();
|
2012-02-28 11:21:18 +00:00
|
|
|
void op_move_register_offset();
|
2012-02-27 00:18:50 +00:00
|
|
|
void op_move_multiple();
|
2012-02-28 11:21:18 +00:00
|
|
|
void op_branch();
|
2012-02-26 07:59:44 +00:00
|
|
|
|
|
|
|
//memory.cpp
|
Update to v086r15 release.
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.
2012-03-02 11:07:17 +00:00
|
|
|
uint8 bus_read(uint32 addr);
|
|
|
|
void bus_write(uint32 addr, uint8 data);
|
Update to v086r14 release.
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.
2012-03-01 12:23:05 +00:00
|
|
|
|
Update to v086r15 release.
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.
2012-03-02 11:07:17 +00:00
|
|
|
uint32 bus_readword(uint32 addr);
|
Update to v086r14 release.
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.
2012-03-01 12:23:05 +00:00
|
|
|
void bus_writeword(uint32 addr, uint32 data);
|
2012-03-10 12:37:36 +00:00
|
|
|
void bus_writebyte(uint32 addr, uint32 data);
|
2012-02-26 07:59:44 +00:00
|
|
|
|
|
|
|
//disassembler.cpp
|
|
|
|
string disassemble_opcode(uint32 pc);
|
|
|
|
string disassemble_registers();
|
|
|
|
|
|
|
|
//serialization.cpp
|
|
|
|
void serialize(serializer&);
|
|
|
|
};
|
|
|
|
|
|
|
|
extern ArmDSP armdsp;
|