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
|
#ifndef BASE_HPP
|
||||||
#define BASE_HPP
|
#define BASE_HPP
|
||||||
|
|
||||||
const char Version[] = "086.11";
|
const char Version[] = "086.12";
|
||||||
|
|
||||||
#include <nall/platform.hpp>
|
#include <nall/platform.hpp>
|
||||||
#include <nall/algorithm.hpp>
|
#include <nall/algorithm.hpp>
|
||||||
|
|
|
@ -52,6 +52,7 @@ void ArmDSP::enter() {
|
||||||
}
|
}
|
||||||
|
|
||||||
instruction = pipeline.instruction.opcode;
|
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) == 0x01000000) { op_move_to_register_from_status_register(); continue; }
|
||||||
if((instruction & 0x0fb000f0) == 0x01200000) { op_move_to_status_register_from_register(); continue; }
|
if((instruction & 0x0fb000f0) == 0x01200000) { op_move_to_status_register_from_register(); continue; }
|
||||||
if((instruction & 0x0e000010) == 0x00000000) { op_data_immediate_shift(); 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");
|
string filename = interface->path(Cartridge::Slot::Base, "st0018d.rom");
|
||||||
file fp;
|
file fp;
|
||||||
if(fp.open(filename, file::mode::read)) {
|
if(fp.open(filename, file::mode::read)) {
|
||||||
fp.read(aoRAM, 32 * 1024);
|
fp.read(dataROM, 32 * 1024);
|
||||||
fp.close();
|
fp.close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
struct ArmDSP : public Coprocessor {
|
struct ArmDSP : public Coprocessor {
|
||||||
uint8 programROM[128 * 1024];
|
uint8 programROM[128 * 1024];
|
||||||
uint8 programRAM[16 * 1024];
|
uint8 programRAM[16 * 1024];
|
||||||
uint8 aoRAM[32 * 1024];
|
uint8 dataROM[32 * 1024];
|
||||||
|
|
||||||
#include "registers.hpp"
|
#include "registers.hpp"
|
||||||
|
|
||||||
|
@ -23,6 +23,7 @@ struct ArmDSP : public Coprocessor {
|
||||||
bool condition();
|
bool condition();
|
||||||
void opcode(uint32 data);
|
void opcode(uint32 data);
|
||||||
|
|
||||||
|
void op_multiply();
|
||||||
void op_move_to_status_register_from_register();
|
void op_move_to_status_register_from_register();
|
||||||
void op_move_to_register_from_status_register();
|
void op_move_to_register_from_status_register();
|
||||||
void op_data_immediate_shift();
|
void op_data_immediate_shift();
|
||||||
|
|
|
@ -40,7 +40,7 @@ string ArmDSP::disassemble_opcode(uint32 pc) {
|
||||||
//{opcode}{condition}{s} rd,rm {shift} #immediate
|
//{opcode}{condition}{s} rd,rm {shift} #immediate
|
||||||
//{opcode}{condition} rn,rm {shift} #immediate
|
//{opcode}{condition} rn,rm {shift} #immediate
|
||||||
//{opcode}{condition}{s} rd,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 condition = instruction >> 28;
|
||||||
uint4 opcode = instruction >> 21;
|
uint4 opcode = instruction >> 21;
|
||||||
uint1 save = instruction >> 20;
|
uint1 save = instruction >> 20;
|
||||||
|
|
|
@ -25,7 +25,7 @@ uint8 ArmDSP::bus_iread(uint32 addr) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if(addr >= 0xa0000000 && addr <= 0xa0007fff) {
|
if(addr >= 0xa0000000 && addr <= 0xa0007fff) {
|
||||||
return aoRAM[addr & 0x00007fff];
|
return dataROM[addr & 0x00007fff];
|
||||||
}
|
}
|
||||||
|
|
||||||
if(addr >= 0xe0000000 && addr <= 0xe0003fff) {
|
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 == 0x4000002c) return print("* w4000002c = ", hex<2>(data), "\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
if(addr >= 0xa0000000 && addr <= 0xa0007fff) {
|
|
||||||
}
|
|
||||||
|
|
||||||
if(addr >= 0xe0000000 && addr <= 0xe0003fff) {
|
if(addr >= 0xe0000000 && addr <= 0xe0003fff) {
|
||||||
programRAM[addr & 0x00003fff] = data;
|
programRAM[addr & 0x00003fff] = data;
|
||||||
return;
|
return;
|
||||||
|
@ -64,10 +61,19 @@ void ArmDSP::bus_iwrite(uint32 addr, uint8 data) {
|
||||||
template<unsigned size>
|
template<unsigned size>
|
||||||
uint32 ArmDSP::bus_read(uint32 addr) {
|
uint32 ArmDSP::bus_read(uint32 addr) {
|
||||||
uint32 data = 0;
|
uint32 data = 0;
|
||||||
data |= bus_iread(addr + 0) << 0;
|
|
||||||
data |= bus_iread(addr + 1) << 8;
|
if(size == 1) {
|
||||||
data |= bus_iread(addr + 2) << 16;
|
uint32 mask = 255u << ((addr & ~3) << 3);
|
||||||
data |= bus_iread(addr + 3) << 24;
|
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(0&&addr >= 0x40000000 && addr <= 0x400000ff) {
|
||||||
if(addr != 0x40000020 || data != 0x80)
|
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 == 1) {
|
||||||
if(size == 2) data = (bus_read<2>(addr) & 0xffff0000) | (data & 0x0000ffff);
|
uint32 mask = 255u << ((addr & ~3) << 3);
|
||||||
bus_iwrite(addr + 0, data >> 0);
|
bus_iwrite(addr, data);
|
||||||
bus_iwrite(addr + 1, data >> 8);
|
}
|
||||||
bus_iwrite(addr + 2, data >> 16);
|
|
||||||
bus_iwrite(addr + 3, data >> 24);
|
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
|
#endif
|
||||||
|
|
|
@ -36,13 +36,13 @@ void ArmDSP::opcode(uint32 rm) {
|
||||||
//comparison opcodes always update flags
|
//comparison opcodes always update flags
|
||||||
if(opcode >= 8 && opcode <= 11) assert(s == 1);
|
if(opcode >= 8 && opcode <= 11) assert(s == 1);
|
||||||
|
|
||||||
static auto nz = [&](uint32 ro) {
|
static auto bit = [&](uint32 ro) {
|
||||||
if(!s) return;
|
if(!s) return;
|
||||||
cpsr.n = ro & 0x80000000;
|
cpsr.n = ro & 0x80000000;
|
||||||
cpsr.z = ro == 0;
|
cpsr.z = ro == 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
static auto nzcv = [&](uint32 ro) {
|
static auto add = [&](uint32 ro) {
|
||||||
if(!s) return;
|
if(!s) return;
|
||||||
cpsr.n = ro & 0x80000000;
|
cpsr.n = ro & 0x80000000;
|
||||||
cpsr.z = ro == 0;
|
cpsr.z = ro == 0;
|
||||||
|
@ -50,23 +50,58 @@ void ArmDSP::opcode(uint32 rm) {
|
||||||
cpsr.v = ~(ri ^ rm) & (ri ^ ro) & 0x80000000;
|
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) {
|
switch(opcode) {
|
||||||
case 0: rd = rn & rm; nz(rd); break; //AND (logical and)
|
case 0: rd = rn & rm; bit(rd); break; //AND (logical and)
|
||||||
case 1: rd = rn ^ rm; nz(rd); break; //EOR (logical exclusive or)
|
case 1: rd = rn ^ rm; bit(rd); break; //EOR (logical exclusive or)
|
||||||
case 2: rd = rn +~rm + 1; nzcv(rd); break; //SUB (subtract)
|
case 2: rd = rn - rm; sub(rd); break; //SUB (subtract)
|
||||||
case 3: rd = rm +~rn + 1; nzcv(rd); break; //RSB (reverse subtract)
|
case 3: rd = rm - rn; sub(rd); break; //RSB (reverse subtract)
|
||||||
case 4: rd = rn + rm; nzcv(rd); break; //ADD (add)
|
case 4: rd = rn + rm; add(rd); break; //ADD (add)
|
||||||
case 5: rd = rn + rm + cpsr.c; nzcv(rd); break; //ADC (add with carry)
|
case 5: rd = rn + rm + cpsr.c; add(rd); break; //ADC (add with carry)
|
||||||
case 6: rd = rn +~rm + cpsr.c; nzcv(rd); break; //SBC (subtract with carry)
|
case 6: rd = rn - rm -!cpsr.c; sub(rd); break; //SBC (subtract with carry)
|
||||||
case 7: rd = rm +~rn + cpsr.c; nzcv(rd); break; //RSC (reverse subtract with carry)
|
case 7: rd = rm - rn -!cpsr.c; sub(rd); break; //RSC (reverse subtract with carry)
|
||||||
case 8: ro = rn & rm; nz(ro); break; //TST (test)
|
case 8: ro = rn & rm; bit(ro); break; //TST (test)
|
||||||
case 9: ro = rn ^ rm; nz(ro); break; //TEQ (test equivalence)
|
case 9: ro = rn ^ rm; bit(ro); break; //TEQ (test equivalence)
|
||||||
case 10: ro = rn +~rm + 1; nzcv(ro); break; //CMP (compare)
|
case 10: ro = rn - rm; sub(ro); break; //CMP (compare)
|
||||||
case 11: ro = rn + rm; nzcv(ro); break; //CMN (compare negated)
|
case 11: ro = rn + rm; add(ro); break; //CMN (compare negated)
|
||||||
case 12: rd = rn | rm; nz(rd); break; //ORR (logical inclusive or)
|
case 12: rd = rn | rm; bit(rd); break; //ORR (logical inclusive or)
|
||||||
case 13: rd = rm; nz(rd); break; //MOV (move)
|
case 13: rd = rm; bit(rd); break; //MOV (move)
|
||||||
case 14: rd = rn &~rm; nz(rd); break; //BIC (bit clear)
|
case 14: rd = rn &~rm; bit(rd); break; //BIC (bit clear)
|
||||||
case 15: rd =~rm; nz(rd); break; //MVN (move not)
|
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