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:
Tim Allen 2017-01-06 19:11:38 +11:00
parent 5bdf55f08f
commit 569f5abc28
14 changed files with 288 additions and 74 deletions

View File

@ -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/";

View File

@ -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 {

View File

@ -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;
}
}

View File

@ -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;

View File

@ -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;
}

View File

@ -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);

View File

@ -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) {

View File

@ -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;
}

View File

@ -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++);

View File

@ -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)

View File

@ -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);
}

View File

@ -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;
}

View File

@ -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 {

View File

@ -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");