mirror of https://github.com/bsnes-emu/bsnes.git
Update to v086r12 release.
byuu says: Attract demonstration game is fully playable.
This commit is contained in:
parent
112520cf45
commit
a00c7cb639
|
@ -1,7 +1,7 @@
|
|||
#ifndef BASE_HPP
|
||||
#define BASE_HPP
|
||||
|
||||
const char Version[] = "086.11";
|
||||
const char Version[] = "086.12";
|
||||
|
||||
#include <nall/platform.hpp>
|
||||
#include <nall/algorithm.hpp>
|
||||
|
|
|
@ -52,6 +52,7 @@ void ArmDSP::enter() {
|
|||
}
|
||||
|
||||
instruction = pipeline.instruction.opcode;
|
||||
if((instruction & 0x0fc000f0) == 0x00000090) { op_multiply(); continue; }
|
||||
if((instruction & 0x0fb000f0) == 0x01000000) { op_move_to_register_from_status_register(); continue; }
|
||||
if((instruction & 0x0fb000f0) == 0x01200000) { op_move_to_status_register_from_register(); continue; }
|
||||
if((instruction & 0x0e000010) == 0x00000000) { op_data_immediate_shift(); continue; }
|
||||
|
@ -126,7 +127,7 @@ void ArmDSP::power() {
|
|||
string filename = interface->path(Cartridge::Slot::Base, "st0018d.rom");
|
||||
file fp;
|
||||
if(fp.open(filename, file::mode::read)) {
|
||||
fp.read(aoRAM, 32 * 1024);
|
||||
fp.read(dataROM, 32 * 1024);
|
||||
fp.close();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
struct ArmDSP : public Coprocessor {
|
||||
uint8 programROM[128 * 1024];
|
||||
uint8 programRAM[16 * 1024];
|
||||
uint8 aoRAM[32 * 1024];
|
||||
uint8 dataROM[32 * 1024];
|
||||
|
||||
#include "registers.hpp"
|
||||
|
||||
|
@ -23,6 +23,7 @@ struct ArmDSP : public Coprocessor {
|
|||
bool condition();
|
||||
void opcode(uint32 data);
|
||||
|
||||
void op_multiply();
|
||||
void op_move_to_status_register_from_register();
|
||||
void op_move_to_register_from_status_register();
|
||||
void op_data_immediate_shift();
|
||||
|
|
|
@ -40,7 +40,7 @@ string ArmDSP::disassemble_opcode(uint32 pc) {
|
|||
//{opcode}{condition}{s} rd,rm {shift} #immediate
|
||||
//{opcode}{condition} rn,rm {shift} #immediate
|
||||
//{opcode}{condition}{s} rd,rn,rm {shift} #immediate
|
||||
if((instruction & 0x0e000000) == 0x00000000) {
|
||||
if((instruction & 0x0e000010) == 0x00000000) {
|
||||
uint4 condition = instruction >> 28;
|
||||
uint4 opcode = instruction >> 21;
|
||||
uint1 save = instruction >> 20;
|
||||
|
|
|
@ -25,7 +25,7 @@ uint8 ArmDSP::bus_iread(uint32 addr) {
|
|||
}
|
||||
|
||||
if(addr >= 0xa0000000 && addr <= 0xa0007fff) {
|
||||
return aoRAM[addr & 0x00007fff];
|
||||
return dataROM[addr & 0x00007fff];
|
||||
}
|
||||
|
||||
if(addr >= 0xe0000000 && addr <= 0xe0003fff) {
|
||||
|
@ -50,9 +50,6 @@ void ArmDSP::bus_iwrite(uint32 addr, uint8 data) {
|
|||
if(addr == 0x4000002c) return print("* w4000002c = ", hex<2>(data), "\n");
|
||||
}
|
||||
|
||||
if(addr >= 0xa0000000 && addr <= 0xa0007fff) {
|
||||
}
|
||||
|
||||
if(addr >= 0xe0000000 && addr <= 0xe0003fff) {
|
||||
programRAM[addr & 0x00003fff] = data;
|
||||
return;
|
||||
|
@ -64,10 +61,19 @@ void ArmDSP::bus_iwrite(uint32 addr, uint8 data) {
|
|||
template<unsigned size>
|
||||
uint32 ArmDSP::bus_read(uint32 addr) {
|
||||
uint32 data = 0;
|
||||
|
||||
if(size == 1) {
|
||||
uint32 mask = 255u << ((addr & ~3) << 3);
|
||||
data |= bus_iread(addr) & mask;
|
||||
}
|
||||
|
||||
if(size == 4) {
|
||||
addr &= ~3;
|
||||
data |= bus_iread(addr + 0) << 0;
|
||||
data |= bus_iread(addr + 1) << 8;
|
||||
data |= bus_iread(addr + 2) << 16;
|
||||
data |= bus_iread(addr + 3) << 24;
|
||||
}
|
||||
|
||||
if(0&&addr >= 0x40000000 && addr <= 0x400000ff) {
|
||||
if(addr != 0x40000020 || data != 0x80)
|
||||
|
@ -95,12 +101,18 @@ void ArmDSP::bus_write(uint32 addr, uint32 data) {
|
|||
}
|
||||
}
|
||||
|
||||
if(size == 1) data = (bus_read<1>(addr) & 0xffffff00) | (data & 0x000000ff);
|
||||
if(size == 2) data = (bus_read<2>(addr) & 0xffff0000) | (data & 0x0000ffff);
|
||||
if(size == 1) {
|
||||
uint32 mask = 255u << ((addr & ~3) << 3);
|
||||
bus_iwrite(addr, data);
|
||||
}
|
||||
|
||||
if(size == 4) {
|
||||
addr &= ~3;
|
||||
bus_iwrite(addr + 0, data >> 0);
|
||||
bus_iwrite(addr + 1, data >> 8);
|
||||
bus_iwrite(addr + 2, data >> 16);
|
||||
bus_iwrite(addr + 3, data >> 24);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -36,13 +36,13 @@ void ArmDSP::opcode(uint32 rm) {
|
|||
//comparison opcodes always update flags
|
||||
if(opcode >= 8 && opcode <= 11) assert(s == 1);
|
||||
|
||||
static auto nz = [&](uint32 ro) {
|
||||
static auto bit = [&](uint32 ro) {
|
||||
if(!s) return;
|
||||
cpsr.n = ro & 0x80000000;
|
||||
cpsr.z = ro == 0;
|
||||
};
|
||||
|
||||
static auto nzcv = [&](uint32 ro) {
|
||||
static auto add = [&](uint32 ro) {
|
||||
if(!s) return;
|
||||
cpsr.n = ro & 0x80000000;
|
||||
cpsr.z = ro == 0;
|
||||
|
@ -50,23 +50,58 @@ void ArmDSP::opcode(uint32 rm) {
|
|||
cpsr.v = ~(ri ^ rm) & (ri ^ ro) & 0x80000000;
|
||||
};
|
||||
|
||||
static auto sub = [&](uint32 ro) {
|
||||
if(!s) return;
|
||||
cpsr.n = ro & 0x80000000;
|
||||
cpsr.z = ro == 0;
|
||||
cpsr.c = ro > ri;
|
||||
cpsr.v = (ri ^ rm) & (ri ^ ro) & 0x80000000;
|
||||
};
|
||||
|
||||
switch(opcode) {
|
||||
case 0: rd = rn & rm; nz(rd); break; //AND (logical and)
|
||||
case 1: rd = rn ^ rm; nz(rd); break; //EOR (logical exclusive or)
|
||||
case 2: rd = rn +~rm + 1; nzcv(rd); break; //SUB (subtract)
|
||||
case 3: rd = rm +~rn + 1; nzcv(rd); break; //RSB (reverse subtract)
|
||||
case 4: rd = rn + rm; nzcv(rd); break; //ADD (add)
|
||||
case 5: rd = rn + rm + cpsr.c; nzcv(rd); break; //ADC (add with carry)
|
||||
case 6: rd = rn +~rm + cpsr.c; nzcv(rd); break; //SBC (subtract with carry)
|
||||
case 7: rd = rm +~rn + cpsr.c; nzcv(rd); break; //RSC (reverse subtract with carry)
|
||||
case 8: ro = rn & rm; nz(ro); break; //TST (test)
|
||||
case 9: ro = rn ^ rm; nz(ro); break; //TEQ (test equivalence)
|
||||
case 10: ro = rn +~rm + 1; nzcv(ro); break; //CMP (compare)
|
||||
case 11: ro = rn + rm; nzcv(ro); break; //CMN (compare negated)
|
||||
case 12: rd = rn | rm; nz(rd); break; //ORR (logical inclusive or)
|
||||
case 13: rd = rm; nz(rd); break; //MOV (move)
|
||||
case 14: rd = rn &~rm; nz(rd); break; //BIC (bit clear)
|
||||
case 15: rd =~rm; nz(rd); break; //MVN (move not)
|
||||
case 0: rd = rn & rm; bit(rd); break; //AND (logical and)
|
||||
case 1: rd = rn ^ rm; bit(rd); break; //EOR (logical exclusive or)
|
||||
case 2: rd = rn - rm; sub(rd); break; //SUB (subtract)
|
||||
case 3: rd = rm - rn; sub(rd); break; //RSB (reverse subtract)
|
||||
case 4: rd = rn + rm; add(rd); break; //ADD (add)
|
||||
case 5: rd = rn + rm + cpsr.c; add(rd); break; //ADC (add with carry)
|
||||
case 6: rd = rn - rm -!cpsr.c; sub(rd); break; //SBC (subtract with carry)
|
||||
case 7: rd = rm - rn -!cpsr.c; sub(rd); break; //RSC (reverse subtract with carry)
|
||||
case 8: ro = rn & rm; bit(ro); break; //TST (test)
|
||||
case 9: ro = rn ^ rm; bit(ro); break; //TEQ (test equivalence)
|
||||
case 10: ro = rn - rm; sub(ro); break; //CMP (compare)
|
||||
case 11: ro = rn + rm; add(ro); break; //CMN (compare negated)
|
||||
case 12: rd = rn | rm; bit(rd); break; //ORR (logical inclusive or)
|
||||
case 13: rd = rm; bit(rd); break; //MOV (move)
|
||||
case 14: rd = rn &~rm; bit(rd); break; //BIC (bit clear)
|
||||
case 15: rd =~rm; bit(rd); break; //MVN (move not)
|
||||
}
|
||||
}
|
||||
|
||||
//(mul,mla){condition}{s}
|
||||
//cccc 0000 00as dddd nnnn ssss 1001 mmmm
|
||||
//c = condition
|
||||
//a = accumulate
|
||||
//s = save flags
|
||||
//d = rd
|
||||
//n = rn
|
||||
//s = rs
|
||||
//n = rm
|
||||
void ArmDSP::op_multiply() {
|
||||
if(!condition()) return;
|
||||
|
||||
uint1 accumulate = instruction >> 21;
|
||||
uint1 save = instruction >> 20;
|
||||
uint4 d = instruction >> 16;
|
||||
uint4 n = instruction >> 12;
|
||||
uint4 s = instruction >> 8;
|
||||
uint4 m = instruction >> 0;
|
||||
|
||||
r[d] = r[m] * r[s];
|
||||
if(accumulate) r[d] += r[n];
|
||||
if(save) {
|
||||
cpsr.n = r[d] & 0x80000000;
|
||||
cpsr.z = r[d] == 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue