mirror of https://github.com/bsnes-emu/bsnes.git
Update to v101r27 release.
byuu says: Changelog: - SMS: emulated the generic Sega memory mapper (none of the more limited forms of it yet) - (missing ROM shift, ROM write enable emulation -- no commercial games use either, though) - SMS: bus I/O returns 0xff instead of 0x00 so games don't think every key is being pressed at once - (this is a hack until I implement proper controller pad reading) - SMS: very limited protection against reading/writing past the end of ROM/RAM (todo: should mirror) - SMS: VDP background HSCROLL subtracts, rather than adds, to the offset (unlike VSCROLL) - SMS: VDP VSCROLL is 9-bit, modulates voffset+vscroll to 224 in 192-line mode (32x28 tilemap) - SMS: VDP tiledata for backgrounds and sprites use `7-(x&7)` rather than `(x&7)` - SMS: fix output color to be 6-bit rather than 5-bit - SMS: left clip uses register `#7`, not palette color `#7` - (todo: do we want `color[reg7]` or `color[16 + reg7]`?) - SMS: refined handling of 0xcb, 0xed prefixes in the Z80 core and its disassembler - SMS: emulated (0xfd, 0xdd) 0xcb opcodes 0x00-0x0f (still missing 0x10-0xff) - SMS: fixed 0xcb 0b-----110 opcodes to use direct HL and never allow (IX,IY)+d - SMS: fixed major logic bug in (IX,IY)+d displacement - (was using `read(x)` instead of `operand()` for the displacement byte fetch before) - icarus: fake there always being 32KiB of RAM in all SMS cartridges for the time being - (not sure how to detect this stuff yet; although I've read it's not even really possible `>_>`) TODO: remove processor/z80/dissassembler.cpp code block at line 396 (as it's unnecessary.) Lots of commercial games are starting to show trashed graphical output now.
This commit is contained in:
parent
5bdf55f08f
commit
569f5abc28
|
@ -12,7 +12,7 @@ using namespace nall;
|
|||
|
||||
namespace Emulator {
|
||||
static const string Name = "higan";
|
||||
static const string Version = "101.26";
|
||||
static const string Version = "101.27";
|
||||
static const string Author = "byuu";
|
||||
static const string License = "GPLv3";
|
||||
static const string Website = "http://byuu.org/";
|
||||
|
|
|
@ -5,13 +5,14 @@ namespace MasterSystem {
|
|||
Bus bus;
|
||||
|
||||
auto Bus::read(uint16 addr) -> uint8 {
|
||||
if(addr < 0xc000) return cartridge.read(addr);
|
||||
return ram[addr & 0x1fff];
|
||||
if(auto data = cartridge.read(addr)) return data();
|
||||
if(addr >= 0xc000) return ram[addr & 0x1fff];
|
||||
return 0x00;
|
||||
}
|
||||
|
||||
auto Bus::write(uint16 addr, uint8 data) -> void {
|
||||
if(addr < 0xc000) return cartridge.write(addr, data);
|
||||
ram[addr & 0x1fff] = data;
|
||||
if(cartridge.write(addr, data)) return;
|
||||
if(addr >= 0xc000) ram[addr & 0x1fff] = data;
|
||||
}
|
||||
|
||||
auto Bus::in(uint8 addr) -> uint8 {
|
||||
|
@ -31,7 +32,7 @@ auto Bus::in(uint8 addr) -> uint8 {
|
|||
|
||||
}
|
||||
|
||||
return 0x00;
|
||||
return 0xff;
|
||||
}
|
||||
|
||||
auto Bus::out(uint8 addr, uint8 data) -> void {
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
namespace MasterSystem {
|
||||
|
||||
Cartridge cartridge;
|
||||
#include "mapper.cpp"
|
||||
|
||||
auto Cartridge::load() -> bool {
|
||||
information = {};
|
||||
|
@ -73,17 +74,23 @@ auto Cartridge::unload() -> void {
|
|||
ram = {};
|
||||
}
|
||||
|
||||
auto Cartridge::read(uint16 addr) -> uint8 {
|
||||
return rom.data[addr & rom.mask];
|
||||
}
|
||||
|
||||
auto Cartridge::write(uint16 addr, uint8 data) -> void {
|
||||
}
|
||||
|
||||
auto Cartridge::power() -> void {
|
||||
}
|
||||
|
||||
auto Cartridge::reset() -> void {
|
||||
memory::fill(&mapper, sizeof(Mapper));
|
||||
mapper.romPage0 = 0;
|
||||
mapper.romPage1 = 1;
|
||||
mapper.romPage2 = 2;
|
||||
}
|
||||
|
||||
auto Cartridge::Memory::read(uint addr) -> uint8 {
|
||||
if(addr < this->size) return this->data[addr];
|
||||
return 0x00;
|
||||
}
|
||||
|
||||
auto Cartridge::Memory::write(uint addr, uint8 data) -> void {
|
||||
if(addr < this->size) this->data[addr] = data;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -8,12 +8,13 @@ struct Cartridge {
|
|||
auto save() -> void;
|
||||
auto unload() -> void;
|
||||
|
||||
auto read(uint16 addr) -> uint8;
|
||||
auto write(uint16 addr, uint8 data) -> void;
|
||||
|
||||
auto power() -> void;
|
||||
auto reset() -> void;
|
||||
|
||||
//mapper.cpp
|
||||
auto read(uint16 addr) -> maybe<uint8>;
|
||||
auto write(uint16 addr, uint8 data) -> bool;
|
||||
|
||||
private:
|
||||
struct Information {
|
||||
uint pathID = 0;
|
||||
|
@ -26,10 +27,31 @@ private:
|
|||
uint8* data = nullptr;
|
||||
uint size = 0;
|
||||
uint mask = 0;
|
||||
|
||||
auto read(uint addr) -> uint8;
|
||||
auto write(uint addr, uint8 data) -> void;
|
||||
};
|
||||
|
||||
Memory rom;
|
||||
Memory ram;
|
||||
|
||||
struct Mapper {
|
||||
//$fffc
|
||||
uint2 shift;
|
||||
uint1 ramPage2;
|
||||
uint1 ramEnablePage2;
|
||||
uint1 ramEnablePage3;
|
||||
uint1 romWriteEnable;
|
||||
|
||||
//$fffd
|
||||
uint8 romPage0;
|
||||
|
||||
//$fffe
|
||||
uint8 romPage1;
|
||||
|
||||
//$ffff
|
||||
uint8 romPage2;
|
||||
} mapper;
|
||||
};
|
||||
|
||||
extern Cartridge cartridge;
|
||||
|
|
|
@ -0,0 +1,92 @@
|
|||
auto Cartridge::read(uint16 addr) -> maybe<uint8> {
|
||||
uint2 page = addr >> 14;
|
||||
addr &= 0x3fff;
|
||||
|
||||
switch(page) {
|
||||
|
||||
case 0: {
|
||||
if(addr <= 0x03ff) return rom.read(addr);
|
||||
return rom.read(mapper.romPage0 << 14 | addr);
|
||||
}
|
||||
|
||||
case 1: {
|
||||
return rom.read(mapper.romPage1 << 14 | addr);
|
||||
}
|
||||
|
||||
case 2: {
|
||||
if(mapper.ramEnablePage2) {
|
||||
return ram.read(mapper.ramPage2 << 14 | addr);
|
||||
}
|
||||
|
||||
return rom.read(mapper.romPage2 << 14 | addr);
|
||||
}
|
||||
|
||||
case 3: {
|
||||
if(mapper.ramEnablePage3) {
|
||||
return ram.read(addr);
|
||||
}
|
||||
|
||||
return nothing;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
unreachable;
|
||||
}
|
||||
|
||||
auto Cartridge::write(uint16 addr, uint8 data) -> bool {
|
||||
if(addr == 0xfffc) {
|
||||
mapper.shift = data.bits(0,1);
|
||||
mapper.ramPage2 = data.bit(2);
|
||||
mapper.ramEnablePage2 = data.bit(3);
|
||||
mapper.ramEnablePage3 = data.bit(4);
|
||||
mapper.romWriteEnable = data.bit(7);
|
||||
}
|
||||
|
||||
if(addr == 0xfffd) {
|
||||
mapper.romPage0 = data;
|
||||
}
|
||||
|
||||
if(addr == 0xfffe) {
|
||||
mapper.romPage1 = data;
|
||||
}
|
||||
|
||||
if(addr == 0xffff) {
|
||||
mapper.romPage2 = data;
|
||||
}
|
||||
|
||||
uint2 page = addr >> 14;
|
||||
addr &= 0x3fff;
|
||||
|
||||
switch(page) {
|
||||
|
||||
case 0: {
|
||||
return false;
|
||||
}
|
||||
|
||||
case 1: {
|
||||
return false;
|
||||
}
|
||||
|
||||
case 2: {
|
||||
if(mapper.ramEnablePage2) {
|
||||
ram.write(mapper.ramPage2 << 14 | addr, data);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
case 3: {
|
||||
if(mapper.ramEnablePage3) {
|
||||
ram.write(addr, data);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
unreachable;
|
||||
}
|
|
@ -12,15 +12,17 @@ auto VDP::Background::run() -> void {
|
|||
}
|
||||
|
||||
uint8 hoffset = state.x;
|
||||
if(!vdp.io.horizontalScrollLock || hoffset >= 16) hoffset += vdp.io.hscroll;
|
||||
if(!vdp.io.horizontalScrollLock || hoffset >= 16) hoffset -= vdp.io.hscroll;
|
||||
|
||||
uint8 voffset = state.y;
|
||||
uint9 voffset = state.y;
|
||||
if(!vdp.io.verticalScrollLock || hoffset <= 191) voffset += vdp.io.vscroll;
|
||||
|
||||
uint14 nameTableAddress;
|
||||
if(vdp.vlines() == 192) {
|
||||
if(voffset >= 224) voffset -= 224;
|
||||
nameTableAddress = vdp.io.nameTableAddress << 11;
|
||||
} else {
|
||||
voffset &= 255;
|
||||
nameTableAddress = (vdp.io.nameTableAddress & ~1) << 11 | 0x700;
|
||||
}
|
||||
nameTableAddress += ((voffset >> 3) << 6) + ((hoffset >> 3) << 1);
|
||||
|
@ -35,7 +37,7 @@ auto VDP::Background::run() -> void {
|
|||
output.palette = tiledata.bit(11);
|
||||
output.priority = tiledata.bit(12);
|
||||
|
||||
auto index = hoffset & 7;
|
||||
auto index = 7 - (hoffset & 7);
|
||||
patternAddress += (voffset & 7) << 2;
|
||||
output.color.bit(0) = vdp.vram[patternAddress + 0].bit(index);
|
||||
output.color.bit(1) = vdp.vram[patternAddress + 1].bit(index);
|
||||
|
|
|
@ -43,11 +43,12 @@ auto VDP::Sprite::run() -> void {
|
|||
address += o.pattern << 5;
|
||||
address += (y & (large ? 15 : 7)) << 2;
|
||||
|
||||
auto index = 7 - (x & 7);
|
||||
uint4 color;
|
||||
color.bit(0) = vdp.vram[address + 0].bit(x & 7);
|
||||
color.bit(1) = vdp.vram[address + 1].bit(x & 7);
|
||||
color.bit(2) = vdp.vram[address + 2].bit(x & 7);
|
||||
color.bit(3) = vdp.vram[address + 3].bit(x & 7);
|
||||
color.bit(0) = vdp.vram[address + 0].bit(index);
|
||||
color.bit(1) = vdp.vram[address + 1].bit(index);
|
||||
color.bit(2) = vdp.vram[address + 2].bit(index);
|
||||
color.bit(3) = vdp.vram[address + 3].bit(index);
|
||||
if(color == 0) continue;
|
||||
|
||||
if(output.color) {
|
||||
|
|
|
@ -34,13 +34,13 @@ auto VDP::main() -> void {
|
|||
sprite.run();
|
||||
step(2);
|
||||
|
||||
uint5 color = cram[16 | io.backdropColor];
|
||||
uint6 color = cram[io.backdropColor];
|
||||
if(background.output.color && (background.output.priority || !sprite.output.color)) {
|
||||
color = cram[background.output.palette << 4 | background.output.color];
|
||||
} else if(sprite.output.color) {
|
||||
color = cram[16 | sprite.output.color];
|
||||
}
|
||||
if(x <= 7 && io.leftClip) color = cram[7];
|
||||
if(x <= 7 && io.leftClip) color = cram[io.backdropColor];
|
||||
if(!io.displayEnable) color = 0;
|
||||
buffer[io.vcounter * 256 + x] = color;
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
auto Z80::disassemble(uint16 pc) -> string {
|
||||
string s;
|
||||
string s, output;
|
||||
s.append(hex(pc, 4L), " ");
|
||||
|
||||
uint8 prefix = 0x00;
|
||||
|
@ -20,7 +20,21 @@ auto Z80::disassemble(uint16 pc) -> string {
|
|||
}
|
||||
}
|
||||
|
||||
s.append(pad(disassemble__(pc, prefix, code), -18L, ' '));
|
||||
if(code == 0xcb && prefix) {
|
||||
auto d = (int8)code;
|
||||
code = bus->read(pc++);
|
||||
output = disassembleCBd(pc, prefix, d, code);
|
||||
} else if(code == 0xcb) {
|
||||
code = bus->read(pc++);
|
||||
output = disassembleCB(pc, prefix, code);
|
||||
} else if(code == 0xed) {
|
||||
code = bus->read(pc++);
|
||||
output = disassembleED(pc, prefix, code);
|
||||
} else {
|
||||
output = disassemble(pc, prefix, code);
|
||||
}
|
||||
|
||||
s.append(pad(output, -18L, ' '));
|
||||
|
||||
finish:
|
||||
s.append(" AF:", hex(r.af.word, 4L));
|
||||
|
@ -76,7 +90,7 @@ auto Z80::disassemble(uint16 pc) -> string {
|
|||
#define IHL string{"(", HL, displace(), ")"}
|
||||
#define ISP "(sp)"
|
||||
|
||||
auto Z80::disassemble__(uint16 pc, uint8 prefix, uint8 code) -> string {
|
||||
auto Z80::disassemble(uint16 pc, uint8 prefix, uint8 code) -> string {
|
||||
auto byte = [&] {
|
||||
return bus->read(pc++);
|
||||
};
|
||||
|
@ -97,9 +111,6 @@ auto Z80::disassemble__(uint16 pc, uint8 prefix, uint8 code) -> string {
|
|||
return d >= 0 ? string{"+$", hex(d, 2L)} : string{"-$", hex(-d, 2L)};
|
||||
};
|
||||
|
||||
if(code == 0xcb) return code = byte(), disassembleCB(pc, prefix, code);
|
||||
if(code == 0xed) return code = byte(), disassembleED(pc, prefix, code);
|
||||
|
||||
switch(code) {
|
||||
op(0x00, "nop ")
|
||||
op(0x01, "ld ", BC, NN)
|
||||
|
@ -382,6 +393,12 @@ auto Z80::disassembleCB(uint16 pc, uint8 prefix, uint8 code) -> string {
|
|||
return d >= 0 ? string{"+$", hex(d, 2L)} : string{"-$", hex(-d, 2L)};
|
||||
};
|
||||
|
||||
if(prefix) {
|
||||
auto d = (int8)code;
|
||||
string ds = d >= 0 ? string{"+$", hex(d, 2L)} : string{"-$", hex(-d, 2L)};
|
||||
return {"rlc (", HL, ds, ")"};
|
||||
}
|
||||
|
||||
switch(code) {
|
||||
op(0x00, "rlc ", B)
|
||||
op(0x01, "rlc ", C)
|
||||
|
@ -644,6 +661,33 @@ auto Z80::disassembleCB(uint16 pc, uint8 prefix, uint8 code) -> string {
|
|||
unreachable;
|
||||
}
|
||||
|
||||
auto Z80::disassembleCBd(uint16 pc, uint8 prefix, int8 d, uint8 code) -> string {
|
||||
auto displace = [&] {
|
||||
return d >= 0 ? string{"+$", hex(d, 2L)} : string{"-$", hex(-d, 2L)};
|
||||
};
|
||||
|
||||
switch(code) {
|
||||
op(0x00, "rlc ", IHL, B)
|
||||
op(0x01, "rlc ", IHL, C)
|
||||
op(0x02, "rlc ", IHL, D)
|
||||
op(0x03, "rlc ", IHL, E)
|
||||
op(0x04, "rlc ", IHL, H)
|
||||
op(0x05, "rlc ", IHL, L)
|
||||
op(0x06, "rlc ", IHL)
|
||||
op(0x07, "rlc ", IHL, A)
|
||||
op(0x08, "rrc ", IHL, B)
|
||||
op(0x09, "rrc ", IHL, C)
|
||||
op(0x0a, "rrc ", IHL, D)
|
||||
op(0x0b, "rrc ", IHL, E)
|
||||
op(0x0c, "rrc ", IHL, H)
|
||||
op(0x0d, "rrc ", IHL, L)
|
||||
op(0x0e, "rrc ", IHL)
|
||||
op(0x0f, "rrc ", IHL, A)
|
||||
}
|
||||
|
||||
return {"???"};
|
||||
}
|
||||
|
||||
auto Z80::disassembleED(uint16 pc, uint8 prefix, uint8 code) -> string {
|
||||
auto byte = [&] {
|
||||
return bus->read(pc++);
|
||||
|
|
|
@ -9,13 +9,24 @@ auto Z80::instruction() -> void {
|
|||
r.iff2 = 1;
|
||||
}
|
||||
|
||||
instruction__(code);
|
||||
if(code == 0xcb && r.hlp != &r.hl) {
|
||||
uint16 addr = HL + (int8)operand();
|
||||
wait(1);
|
||||
instructionCBd(addr, opcode());
|
||||
} else if(code == 0xcb) {
|
||||
instructionCB(opcode());
|
||||
} else if(code == 0xed) {
|
||||
instructionED(opcode());
|
||||
} else {
|
||||
instruction(code);
|
||||
}
|
||||
|
||||
r.hlp = &r.hl;
|
||||
}
|
||||
|
||||
#define op(id, name, ...) case id: return instruction##name(__VA_ARGS__);
|
||||
|
||||
auto Z80::instruction__(uint8 code) -> void {
|
||||
auto Z80::instruction(uint8 code) -> void {
|
||||
switch(code) {
|
||||
op(0x00, NOP)
|
||||
op(0x01, LD_rr_nn, BC)
|
||||
|
@ -220,7 +231,7 @@ auto Z80::instruction__(uint8 code) -> void {
|
|||
op(0xc8, RET_c, ZF == 1)
|
||||
op(0xc9, RET)
|
||||
op(0xca, JP_c_nn, ZF == 1)
|
||||
op(0xcb, CB, opcode())
|
||||
//op(0xcb, cb:)
|
||||
op(0xcc, CALL_c_nn, ZF == 1)
|
||||
op(0xcd, CALL_nn)
|
||||
op(0xce, ADC_a_n)
|
||||
|
@ -253,7 +264,7 @@ auto Z80::instruction__(uint8 code) -> void {
|
|||
op(0xea, JP_c_nn, PF == 1)
|
||||
op(0xeb, EX_rr_rr, DE, _HL)
|
||||
op(0xec, CALL_c_nn, PF == 1)
|
||||
op(0xed, ED, opcode())
|
||||
//op(0xed, ed:)
|
||||
op(0xee, XOR_a_n)
|
||||
op(0xef, RST_o, 5)
|
||||
op(0xf0, RET_c, SF == 0)
|
||||
|
@ -283,7 +294,7 @@ auto Z80::instructionCB(uint8 code) -> void {
|
|||
op(0x03, RLC_r, E)
|
||||
op(0x04, RLC_r, H)
|
||||
op(0x05, RLC_r, L)
|
||||
op(0x06, RLC_irr, HL)
|
||||
op(0x06, RLC_irr, _HL)
|
||||
op(0x07, RLC_r, A)
|
||||
op(0x08, RRC_r, B)
|
||||
op(0x09, RRC_r, C)
|
||||
|
@ -291,7 +302,7 @@ auto Z80::instructionCB(uint8 code) -> void {
|
|||
op(0x0b, RRC_r, E)
|
||||
op(0x0c, RRC_r, H)
|
||||
op(0x0d, RRC_r, L)
|
||||
op(0x0e, RRC_irr, HL)
|
||||
op(0x0e, RRC_irr, _HL)
|
||||
op(0x0f, RRC_r, A)
|
||||
op(0x10, RL_r, B)
|
||||
op(0x11, RL_r, C)
|
||||
|
@ -299,7 +310,7 @@ auto Z80::instructionCB(uint8 code) -> void {
|
|||
op(0x13, RL_r, E)
|
||||
op(0x14, RL_r, H)
|
||||
op(0x15, RL_r, L)
|
||||
op(0x16, RL_irr, HL)
|
||||
op(0x16, RL_irr, _HL)
|
||||
op(0x17, RL_r, A)
|
||||
op(0x18, RR_r, B)
|
||||
op(0x19, RR_r, C)
|
||||
|
@ -307,7 +318,7 @@ auto Z80::instructionCB(uint8 code) -> void {
|
|||
op(0x1b, RR_r, E)
|
||||
op(0x1c, RR_r, H)
|
||||
op(0x1d, RR_r, L)
|
||||
op(0x1e, RR_irr, HL)
|
||||
op(0x1e, RR_irr, _HL)
|
||||
op(0x1f, RR_r, A)
|
||||
op(0x20, SLA_r, B)
|
||||
op(0x21, SLA_r, C)
|
||||
|
@ -315,7 +326,7 @@ auto Z80::instructionCB(uint8 code) -> void {
|
|||
op(0x23, SLA_r, E)
|
||||
op(0x24, SLA_r, H)
|
||||
op(0x25, SLA_r, L)
|
||||
op(0x26, SLA_irr, HL)
|
||||
op(0x26, SLA_irr, _HL)
|
||||
op(0x27, SLA_r, A)
|
||||
op(0x28, SRA_r, B)
|
||||
op(0x29, SRA_r, C)
|
||||
|
@ -323,7 +334,7 @@ auto Z80::instructionCB(uint8 code) -> void {
|
|||
op(0x2b, SRA_r, E)
|
||||
op(0x2c, SRA_r, H)
|
||||
op(0x2d, SRA_r, L)
|
||||
op(0x2e, SRA_irr, HL)
|
||||
op(0x2e, SRA_irr, _HL)
|
||||
op(0x2f, SRA_r, A)
|
||||
op(0x30, SLL_r, B)
|
||||
op(0x31, SLL_r, C)
|
||||
|
@ -331,7 +342,7 @@ auto Z80::instructionCB(uint8 code) -> void {
|
|||
op(0x33, SLL_r, E)
|
||||
op(0x34, SLL_r, H)
|
||||
op(0x35, SLL_r, L)
|
||||
op(0x36, SLL_irr, HL)
|
||||
op(0x36, SLL_irr, _HL)
|
||||
op(0x37, SLL_r, A)
|
||||
op(0x38, SRL_r, B)
|
||||
op(0x39, SRL_r, C)
|
||||
|
@ -339,7 +350,7 @@ auto Z80::instructionCB(uint8 code) -> void {
|
|||
op(0x3b, SRL_r, E)
|
||||
op(0x3c, SRL_r, H)
|
||||
op(0x3d, SRL_r, L)
|
||||
op(0x3e, SRL_irr, HL)
|
||||
op(0x3e, SRL_irr, _HL)
|
||||
op(0x3f, SRL_r, A)
|
||||
op(0x40, BIT_o_r, 0, B)
|
||||
op(0x41, BIT_o_r, 0, C)
|
||||
|
@ -347,7 +358,7 @@ auto Z80::instructionCB(uint8 code) -> void {
|
|||
op(0x43, BIT_o_r, 0, E)
|
||||
op(0x44, BIT_o_r, 0, H)
|
||||
op(0x45, BIT_o_r, 0, L)
|
||||
op(0x46, BIT_o_irr, 0, HL)
|
||||
op(0x46, BIT_o_irr, 0, _HL)
|
||||
op(0x47, BIT_o_r, 0, A)
|
||||
op(0x48, BIT_o_r, 1, B)
|
||||
op(0x49, BIT_o_r, 1, C)
|
||||
|
@ -355,7 +366,7 @@ auto Z80::instructionCB(uint8 code) -> void {
|
|||
op(0x4b, BIT_o_r, 1, E)
|
||||
op(0x4c, BIT_o_r, 1, H)
|
||||
op(0x4d, BIT_o_r, 1, L)
|
||||
op(0x4e, BIT_o_irr, 1, HL)
|
||||
op(0x4e, BIT_o_irr, 1, _HL)
|
||||
op(0x4f, BIT_o_r, 1, A)
|
||||
op(0x50, BIT_o_r, 2, B)
|
||||
op(0x51, BIT_o_r, 2, C)
|
||||
|
@ -363,7 +374,7 @@ auto Z80::instructionCB(uint8 code) -> void {
|
|||
op(0x53, BIT_o_r, 2, E)
|
||||
op(0x54, BIT_o_r, 2, H)
|
||||
op(0x55, BIT_o_r, 2, L)
|
||||
op(0x56, BIT_o_irr, 2, HL)
|
||||
op(0x56, BIT_o_irr, 2, _HL)
|
||||
op(0x57, BIT_o_r, 2, A)
|
||||
op(0x58, BIT_o_r, 3, B)
|
||||
op(0x59, BIT_o_r, 3, C)
|
||||
|
@ -371,7 +382,7 @@ auto Z80::instructionCB(uint8 code) -> void {
|
|||
op(0x5b, BIT_o_r, 3, E)
|
||||
op(0x5c, BIT_o_r, 3, H)
|
||||
op(0x5d, BIT_o_r, 3, L)
|
||||
op(0x5e, BIT_o_irr, 3, HL)
|
||||
op(0x5e, BIT_o_irr, 3, _HL)
|
||||
op(0x5f, BIT_o_r, 3, A)
|
||||
op(0x60, BIT_o_r, 4, B)
|
||||
op(0x61, BIT_o_r, 4, C)
|
||||
|
@ -379,7 +390,7 @@ auto Z80::instructionCB(uint8 code) -> void {
|
|||
op(0x63, BIT_o_r, 4, E)
|
||||
op(0x64, BIT_o_r, 4, H)
|
||||
op(0x65, BIT_o_r, 4, L)
|
||||
op(0x66, BIT_o_irr, 4, HL)
|
||||
op(0x66, BIT_o_irr, 4, _HL)
|
||||
op(0x67, BIT_o_r, 4, A)
|
||||
op(0x68, BIT_o_r, 5, B)
|
||||
op(0x69, BIT_o_r, 5, C)
|
||||
|
@ -387,7 +398,7 @@ auto Z80::instructionCB(uint8 code) -> void {
|
|||
op(0x6b, BIT_o_r, 5, E)
|
||||
op(0x6c, BIT_o_r, 5, H)
|
||||
op(0x6d, BIT_o_r, 5, L)
|
||||
op(0x6e, BIT_o_irr, 5, HL)
|
||||
op(0x6e, BIT_o_irr, 5, _HL)
|
||||
op(0x6f, BIT_o_r, 5, A)
|
||||
op(0x70, BIT_o_r, 6, B)
|
||||
op(0x71, BIT_o_r, 6, C)
|
||||
|
@ -395,7 +406,7 @@ auto Z80::instructionCB(uint8 code) -> void {
|
|||
op(0x73, BIT_o_r, 6, E)
|
||||
op(0x74, BIT_o_r, 6, H)
|
||||
op(0x75, BIT_o_r, 6, L)
|
||||
op(0x76, BIT_o_irr, 6, HL)
|
||||
op(0x76, BIT_o_irr, 6, _HL)
|
||||
op(0x77, BIT_o_r, 6, A)
|
||||
op(0x78, BIT_o_r, 7, B)
|
||||
op(0x79, BIT_o_r, 7, C)
|
||||
|
@ -403,7 +414,7 @@ auto Z80::instructionCB(uint8 code) -> void {
|
|||
op(0x7b, BIT_o_r, 7, E)
|
||||
op(0x7c, BIT_o_r, 7, H)
|
||||
op(0x7d, BIT_o_r, 7, L)
|
||||
op(0x7e, BIT_o_irr, 7, HL)
|
||||
op(0x7e, BIT_o_irr, 7, _HL)
|
||||
op(0x7f, BIT_o_r, 7, A)
|
||||
op(0x80, RES_o_r, 0, B)
|
||||
op(0x81, RES_o_r, 0, C)
|
||||
|
@ -411,7 +422,7 @@ auto Z80::instructionCB(uint8 code) -> void {
|
|||
op(0x83, RES_o_r, 0, E)
|
||||
op(0x84, RES_o_r, 0, H)
|
||||
op(0x85, RES_o_r, 0, L)
|
||||
op(0x86, RES_o_irr, 0, HL)
|
||||
op(0x86, RES_o_irr, 0, _HL)
|
||||
op(0x87, RES_o_r, 0, A)
|
||||
op(0x88, RES_o_r, 1, B)
|
||||
op(0x89, RES_o_r, 1, C)
|
||||
|
@ -419,7 +430,7 @@ auto Z80::instructionCB(uint8 code) -> void {
|
|||
op(0x8b, RES_o_r, 1, E)
|
||||
op(0x8c, RES_o_r, 1, H)
|
||||
op(0x8d, RES_o_r, 1, L)
|
||||
op(0x8e, RES_o_irr, 1, HL)
|
||||
op(0x8e, RES_o_irr, 1, _HL)
|
||||
op(0x8f, RES_o_r, 1, A)
|
||||
op(0x90, RES_o_r, 2, B)
|
||||
op(0x91, RES_o_r, 2, C)
|
||||
|
@ -427,7 +438,7 @@ auto Z80::instructionCB(uint8 code) -> void {
|
|||
op(0x93, RES_o_r, 2, E)
|
||||
op(0x94, RES_o_r, 2, H)
|
||||
op(0x95, RES_o_r, 2, L)
|
||||
op(0x96, RES_o_irr, 2, HL)
|
||||
op(0x96, RES_o_irr, 2, _HL)
|
||||
op(0x97, RES_o_r, 2, A)
|
||||
op(0x98, RES_o_r, 3, B)
|
||||
op(0x99, RES_o_r, 3, C)
|
||||
|
@ -435,7 +446,7 @@ auto Z80::instructionCB(uint8 code) -> void {
|
|||
op(0x9b, RES_o_r, 3, E)
|
||||
op(0x9c, RES_o_r, 3, H)
|
||||
op(0x9d, RES_o_r, 3, L)
|
||||
op(0x9e, RES_o_irr, 3, HL)
|
||||
op(0x9e, RES_o_irr, 3, _HL)
|
||||
op(0x9f, RES_o_r, 3, A)
|
||||
op(0xa0, RES_o_r, 4, B)
|
||||
op(0xa1, RES_o_r, 4, C)
|
||||
|
@ -443,7 +454,7 @@ auto Z80::instructionCB(uint8 code) -> void {
|
|||
op(0xa3, RES_o_r, 4, E)
|
||||
op(0xa4, RES_o_r, 4, H)
|
||||
op(0xa5, RES_o_r, 4, L)
|
||||
op(0xa6, RES_o_irr, 4, HL)
|
||||
op(0xa6, RES_o_irr, 4, _HL)
|
||||
op(0xa7, RES_o_r, 4, A)
|
||||
op(0xa8, RES_o_r, 5, B)
|
||||
op(0xa9, RES_o_r, 5, C)
|
||||
|
@ -451,7 +462,7 @@ auto Z80::instructionCB(uint8 code) -> void {
|
|||
op(0xab, RES_o_r, 5, E)
|
||||
op(0xac, RES_o_r, 5, H)
|
||||
op(0xad, RES_o_r, 5, L)
|
||||
op(0xae, RES_o_irr, 5, HL)
|
||||
op(0xae, RES_o_irr, 5, _HL)
|
||||
op(0xaf, RES_o_r, 5, A)
|
||||
op(0xb0, RES_o_r, 6, B)
|
||||
op(0xb1, RES_o_r, 6, C)
|
||||
|
@ -459,7 +470,7 @@ auto Z80::instructionCB(uint8 code) -> void {
|
|||
op(0xb3, RES_o_r, 6, E)
|
||||
op(0xb4, RES_o_r, 6, H)
|
||||
op(0xb5, RES_o_r, 6, L)
|
||||
op(0xb6, RES_o_irr, 6, HL)
|
||||
op(0xb6, RES_o_irr, 6, _HL)
|
||||
op(0xb7, RES_o_r, 6, A)
|
||||
op(0xb8, RES_o_r, 7, B)
|
||||
op(0xb9, RES_o_r, 7, C)
|
||||
|
@ -467,7 +478,7 @@ auto Z80::instructionCB(uint8 code) -> void {
|
|||
op(0xbb, RES_o_r, 7, E)
|
||||
op(0xbc, RES_o_r, 7, H)
|
||||
op(0xbd, RES_o_r, 7, L)
|
||||
op(0xbe, RES_o_irr, 7, HL)
|
||||
op(0xbe, RES_o_irr, 7, _HL)
|
||||
op(0xbf, RES_o_r, 7, A)
|
||||
op(0xc0, SET_o_r, 0, B)
|
||||
op(0xc1, SET_o_r, 0, C)
|
||||
|
@ -475,7 +486,7 @@ auto Z80::instructionCB(uint8 code) -> void {
|
|||
op(0xc3, SET_o_r, 0, E)
|
||||
op(0xc4, SET_o_r, 0, H)
|
||||
op(0xc5, SET_o_r, 0, L)
|
||||
op(0xc6, SET_o_irr, 0, HL)
|
||||
op(0xc6, SET_o_irr, 0, _HL)
|
||||
op(0xc7, SET_o_r, 0, A)
|
||||
op(0xc8, SET_o_r, 1, B)
|
||||
op(0xc9, SET_o_r, 1, C)
|
||||
|
@ -483,7 +494,7 @@ auto Z80::instructionCB(uint8 code) -> void {
|
|||
op(0xcb, SET_o_r, 1, E)
|
||||
op(0xcc, SET_o_r, 1, H)
|
||||
op(0xcd, SET_o_r, 1, L)
|
||||
op(0xce, SET_o_irr, 1, HL)
|
||||
op(0xce, SET_o_irr, 1, _HL)
|
||||
op(0xcf, SET_o_r, 1, A)
|
||||
op(0xd0, SET_o_r, 2, B)
|
||||
op(0xd1, SET_o_r, 2, C)
|
||||
|
@ -491,7 +502,7 @@ auto Z80::instructionCB(uint8 code) -> void {
|
|||
op(0xd3, SET_o_r, 2, E)
|
||||
op(0xd4, SET_o_r, 2, H)
|
||||
op(0xd5, SET_o_r, 2, L)
|
||||
op(0xd6, SET_o_irr, 2, HL)
|
||||
op(0xd6, SET_o_irr, 2, _HL)
|
||||
op(0xd7, SET_o_r, 2, A)
|
||||
op(0xd8, SET_o_r, 3, B)
|
||||
op(0xd9, SET_o_r, 3, C)
|
||||
|
@ -499,7 +510,7 @@ auto Z80::instructionCB(uint8 code) -> void {
|
|||
op(0xdb, SET_o_r, 3, E)
|
||||
op(0xdc, SET_o_r, 3, H)
|
||||
op(0xdd, SET_o_r, 3, L)
|
||||
op(0xde, SET_o_irr, 3, HL)
|
||||
op(0xde, SET_o_irr, 3, _HL)
|
||||
op(0xdf, SET_o_r, 3, A)
|
||||
op(0xe0, SET_o_r, 4, B)
|
||||
op(0xe1, SET_o_r, 4, C)
|
||||
|
@ -507,7 +518,7 @@ auto Z80::instructionCB(uint8 code) -> void {
|
|||
op(0xe3, SET_o_r, 4, E)
|
||||
op(0xe4, SET_o_r, 4, H)
|
||||
op(0xe5, SET_o_r, 4, L)
|
||||
op(0xe6, SET_o_irr, 4, HL)
|
||||
op(0xe6, SET_o_irr, 4, _HL)
|
||||
op(0xe7, SET_o_r, 4, A)
|
||||
op(0xe8, SET_o_r, 5, B)
|
||||
op(0xe9, SET_o_r, 5, C)
|
||||
|
@ -515,7 +526,7 @@ auto Z80::instructionCB(uint8 code) -> void {
|
|||
op(0xeb, SET_o_r, 5, E)
|
||||
op(0xec, SET_o_r, 5, H)
|
||||
op(0xed, SET_o_r, 5, L)
|
||||
op(0xee, SET_o_irr, 5, HL)
|
||||
op(0xee, SET_o_irr, 5, _HL)
|
||||
op(0xef, SET_o_r, 5, A)
|
||||
op(0xf0, SET_o_r, 6, B)
|
||||
op(0xf1, SET_o_r, 6, C)
|
||||
|
@ -523,7 +534,7 @@ auto Z80::instructionCB(uint8 code) -> void {
|
|||
op(0xf3, SET_o_r, 6, E)
|
||||
op(0xf4, SET_o_r, 6, H)
|
||||
op(0xf5, SET_o_r, 6, L)
|
||||
op(0xf6, SET_o_irr, 6, HL)
|
||||
op(0xf6, SET_o_irr, 6, _HL)
|
||||
op(0xf7, SET_o_r, 6, A)
|
||||
op(0xf8, SET_o_r, 7, B)
|
||||
op(0xf9, SET_o_r, 7, C)
|
||||
|
@ -531,11 +542,34 @@ auto Z80::instructionCB(uint8 code) -> void {
|
|||
op(0xfb, SET_o_r, 7, E)
|
||||
op(0xfc, SET_o_r, 7, H)
|
||||
op(0xfd, SET_o_r, 7, L)
|
||||
op(0xfe, SET_o_irr, 7, HL)
|
||||
op(0xfe, SET_o_irr, 7, _HL)
|
||||
op(0xff, SET_o_r, 7, A)
|
||||
}
|
||||
}
|
||||
|
||||
auto Z80::instructionCBd(uint16 addr, uint8 code) -> void {
|
||||
uint8 _;
|
||||
|
||||
switch(code) {
|
||||
op(0x00, RLC_irr_r, addr, B)
|
||||
op(0x01, RLC_irr_r, addr, C)
|
||||
op(0x02, RLC_irr_r, addr, D)
|
||||
op(0x03, RLC_irr_r, addr, E)
|
||||
op(0x04, RLC_irr_r, addr, H)
|
||||
op(0x05, RLC_irr_r, addr, L)
|
||||
op(0x06, RLC_irr_r, addr, _)
|
||||
op(0x07, RLC_irr_r, addr, A)
|
||||
op(0x08, RRC_irr_r, addr, B)
|
||||
op(0x09, RRC_irr_r, addr, C)
|
||||
op(0x0a, RRC_irr_r, addr, D)
|
||||
op(0x0b, RRC_irr_r, addr, E)
|
||||
op(0x0c, RRC_irr_r, addr, H)
|
||||
op(0x0d, RRC_irr_r, addr, L)
|
||||
op(0x0e, RRC_irr_r, addr, _)
|
||||
op(0x0f, RRC_irr_r, addr, A)
|
||||
}
|
||||
}
|
||||
|
||||
auto Z80::instructionED(uint8 code) -> void {
|
||||
switch(code) {
|
||||
op(0x40, IN_r_ic, B)
|
||||
|
|
|
@ -738,11 +738,14 @@ auto Z80::instructionRLA() -> void {
|
|||
YF = A.bit(5);
|
||||
}
|
||||
|
||||
auto Z80::instructionRLC_irr(uint16& x) -> void {
|
||||
auto addr = displace(x);
|
||||
auto Z80::instructionRLC_irr(uint16& addr) -> void {
|
||||
write(addr, RLC(read(addr)));
|
||||
}
|
||||
|
||||
auto Z80::instructionRLC_irr_r(uint16& addr, uint8& x) -> void {
|
||||
write(addr, x = RLC(read(addr)));
|
||||
}
|
||||
|
||||
auto Z80::instructionRLC_r(uint8& x) -> void {
|
||||
x = RLC(x);
|
||||
}
|
||||
|
@ -794,11 +797,14 @@ auto Z80::instructionRRA() -> void {
|
|||
YF = A.bit(5);
|
||||
}
|
||||
|
||||
auto Z80::instructionRRC_irr(uint16& x) -> void {
|
||||
auto addr = displace(x);
|
||||
auto Z80::instructionRRC_irr(uint16& addr) -> void {
|
||||
write(addr, RRC(read(addr)));
|
||||
}
|
||||
|
||||
auto Z80::instructionRRC_irr_r(uint16& addr, uint8& x) -> void {
|
||||
write(addr, x = RRC(read(addr)));
|
||||
}
|
||||
|
||||
auto Z80::instructionRRC_r(uint8& x) -> void {
|
||||
x = RRC(x);
|
||||
}
|
||||
|
|
|
@ -29,7 +29,7 @@ auto Z80::pop() -> uint16 {
|
|||
|
||||
auto Z80::displace(uint16& x) -> uint16 {
|
||||
if(&x != &r.ix.word && &x != &r.iy.word) return x;
|
||||
auto d = read(x);
|
||||
auto d = operand();
|
||||
wait(5);
|
||||
return x + (int8)d;
|
||||
}
|
||||
|
|
|
@ -36,8 +36,9 @@ struct Z80 {
|
|||
|
||||
//instruction.cpp
|
||||
auto instruction() -> void;
|
||||
auto instruction__(uint8 code) -> void;
|
||||
auto instruction(uint8 code) -> void;
|
||||
auto instructionCB(uint8 code) -> void;
|
||||
auto instructionCBd(uint16 addr, uint8 code) -> void;
|
||||
auto instructionED(uint8 code) -> void;
|
||||
|
||||
//instructions.cpp
|
||||
|
@ -148,6 +149,7 @@ struct Z80 {
|
|||
auto instructionRL_r(uint8&) -> void;
|
||||
auto instructionRLA() -> void;
|
||||
auto instructionRLC_irr(uint16&) -> void;
|
||||
auto instructionRLC_irr_r(uint16&, uint8&) -> void;
|
||||
auto instructionRLC_r(uint8&) -> void;
|
||||
auto instructionRLCA() -> void;
|
||||
auto instructionRLD() -> void;
|
||||
|
@ -155,6 +157,7 @@ struct Z80 {
|
|||
auto instructionRR_r(uint8&) -> void;
|
||||
auto instructionRRA() -> void;
|
||||
auto instructionRRC_irr(uint16&) -> void;
|
||||
auto instructionRRC_irr_r(uint16&, uint8&) -> void;
|
||||
auto instructionRRC_r(uint8&) -> void;
|
||||
auto instructionRRCA() -> void;
|
||||
auto instructionRRD() -> void;
|
||||
|
@ -183,8 +186,9 @@ struct Z80 {
|
|||
|
||||
//disassembler.cpp
|
||||
auto disassemble(uint16 pc) -> string;
|
||||
auto disassemble__(uint16 pc, uint8 prefix, uint8 code) -> string;
|
||||
auto disassemble(uint16 pc, uint8 prefix, uint8 code) -> string;
|
||||
auto disassembleCB(uint16 pc, uint8 prefix, uint8 code) -> string;
|
||||
auto disassembleCBd(uint16 pc, uint8 prefix, int8 d, uint8 code) -> string;
|
||||
auto disassembleED(uint16 pc, uint8 prefix, uint8 code) -> string;
|
||||
|
||||
struct Registers {
|
||||
|
|
|
@ -11,6 +11,7 @@ struct MasterSystemCartridge {
|
|||
MasterSystemCartridge::MasterSystemCartridge(string location, uint8_t* data, uint size) {
|
||||
manifest.append("board\n");
|
||||
manifest.append(" rom name=program.rom size=0x", hex(size), "\n");
|
||||
manifest.append(" ram name=save.ram size=0x8000\n");
|
||||
manifest.append("\n");
|
||||
manifest.append("information\n");
|
||||
manifest.append(" title: ", Location::prefix(location), "\n");
|
||||
|
|
Loading…
Reference in New Issue