Update to v101r14 release.
byuu says:
Changelog:
- rewrote the Z80 core to properly handle 0xDD (IX0 and 0xFD (IY)
prefixes
- added Processor::Z80::Bus as a new type of abstraction
- all of the instructions implemented have their proper T-cycle counts
now
- added nall/certificates for my public keys
The goal of `Processor::Z80::Bus` is to simulate the opcode fetches being
2-read + 2-wait states; operand+regular reads/writes being 3-read. For
now, this puts the cycle counts inside the CPU core. At the moment, I
can't think of any CPU core where this wouldn't be appropriate. But it's
certainly possible that such a case exists. So this may not be the
perfect solution.
The reason for having it be a subclass of Processor::Z80 instead of
virtual functions for the MasterSystem::CPU core to define is due to
naming conflicts. I wanted the core to say `in(addr)` and have it take
the four clocks. But I also wanted a version of the function that didn't
consume time when called. One way to do that would be for the core to
call `Z80::in(addr)`, which then calls the regular `in(addr)` that goes to
`MasterSystem::CPU::in(addr)`. But I don't want to put the `Z80::`
prefix on all of the opcodes. Very easy to forget it, and then end up not
consuming any time. Another is to use uglier names in the
`MasterSystem::CPU` core, like `read_`, `write_`, `in_`, `out_`, etc. But,
yuck.
So ... yeah, this is an experiment. We'll see how it goes.
2016-09-03 11:26:04 +00:00
|
|
|
auto Z80::wait(uint clocks) -> void {
|
|
|
|
step(clocks);
|
|
|
|
}
|
|
|
|
|
|
|
|
auto Z80::opcode() -> uint8 {
|
|
|
|
step(4);
|
|
|
|
return bus->read(r.pc++);
|
|
|
|
}
|
|
|
|
|
|
|
|
auto Z80::operand() -> uint8 {
|
|
|
|
step(3);
|
|
|
|
return bus->read(r.pc++);
|
|
|
|
}
|
|
|
|
|
2016-09-06 00:09:33 +00:00
|
|
|
auto Z80::operands() -> uint16 {
|
|
|
|
uint16 data = operand() << 0;
|
|
|
|
return data | operand() << 8;
|
|
|
|
}
|
|
|
|
|
2016-10-31 21:10:33 +00:00
|
|
|
auto Z80::push(uint16 x) -> void {
|
|
|
|
write(--SP, x >> 8);
|
|
|
|
write(--SP, x >> 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
auto Z80::pop() -> uint16 {
|
|
|
|
uint16 data = read(SP++) << 0;
|
|
|
|
return data | read(SP++) << 8;
|
|
|
|
}
|
|
|
|
|
2016-09-04 13:51:27 +00:00
|
|
|
auto Z80::displace(uint16& x) -> uint16 {
|
2016-09-06 13:53:14 +00:00
|
|
|
if(&x != &r.ix.word && &x != &r.iy.word) return x;
|
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.
2017-01-06 08:11:38 +00:00
|
|
|
auto d = operand();
|
2016-09-04 13:51:27 +00:00
|
|
|
wait(5);
|
|
|
|
return x + (int8)d;
|
|
|
|
}
|
|
|
|
|
Update to v101r14 release.
byuu says:
Changelog:
- rewrote the Z80 core to properly handle 0xDD (IX0 and 0xFD (IY)
prefixes
- added Processor::Z80::Bus as a new type of abstraction
- all of the instructions implemented have their proper T-cycle counts
now
- added nall/certificates for my public keys
The goal of `Processor::Z80::Bus` is to simulate the opcode fetches being
2-read + 2-wait states; operand+regular reads/writes being 3-read. For
now, this puts the cycle counts inside the CPU core. At the moment, I
can't think of any CPU core where this wouldn't be appropriate. But it's
certainly possible that such a case exists. So this may not be the
perfect solution.
The reason for having it be a subclass of Processor::Z80 instead of
virtual functions for the MasterSystem::CPU core to define is due to
naming conflicts. I wanted the core to say `in(addr)` and have it take
the four clocks. But I also wanted a version of the function that didn't
consume time when called. One way to do that would be for the core to
call `Z80::in(addr)`, which then calls the regular `in(addr)` that goes to
`MasterSystem::CPU::in(addr)`. But I don't want to put the `Z80::`
prefix on all of the opcodes. Very easy to forget it, and then end up not
consuming any time. Another is to use uglier names in the
`MasterSystem::CPU` core, like `read_`, `write_`, `in_`, `out_`, etc. But,
yuck.
So ... yeah, this is an experiment. We'll see how it goes.
2016-09-03 11:26:04 +00:00
|
|
|
auto Z80::read(uint16 addr) -> uint8 {
|
|
|
|
step(3);
|
|
|
|
return bus->read(addr);
|
|
|
|
}
|
|
|
|
|
|
|
|
auto Z80::write(uint16 addr, uint8 data) -> void {
|
|
|
|
step(3);
|
|
|
|
return bus->write(addr, data);
|
|
|
|
}
|
|
|
|
|
|
|
|
auto Z80::in(uint8 addr) -> uint8 {
|
|
|
|
step(4);
|
|
|
|
return bus->in(addr);
|
|
|
|
}
|
|
|
|
|
|
|
|
auto Z80::out(uint8 addr, uint8 data) -> void {
|
|
|
|
step(4);
|
|
|
|
return bus->out(addr, data);
|
|
|
|
}
|