mirror of
https://github.com/MoleskiCoder/EightBit.git
synced 2025-08-07 18:25:07 +00:00
MC6809 tidy a few items and show a "functional" (rather than macro based) rmw routine.
This commit is contained in:
@@ -4,6 +4,7 @@
|
|||||||
// http://www.cpu-world.com/Arch/6809.html
|
// http://www.cpu-world.com/Arch/6809.html
|
||||||
|
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
#include <functional>
|
||||||
|
|
||||||
#include <Bus.h>
|
#include <Bus.h>
|
||||||
#include <BigEndianProcessor.h>
|
#include <BigEndianProcessor.h>
|
||||||
@@ -112,6 +113,7 @@ namespace EightBit {
|
|||||||
virtual uint8_t busRead() final;
|
virtual uint8_t busRead() final;
|
||||||
|
|
||||||
virtual void call(register16_t destination) final;
|
virtual void call(register16_t destination) final;
|
||||||
|
virtual void ret() final;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const uint8_t RESETvector = 0xfe; // RESET vector
|
const uint8_t RESETvector = 0xfe; // RESET vector
|
||||||
@@ -125,7 +127,33 @@ namespace EightBit {
|
|||||||
|
|
||||||
void eat(int cycles = 1) {
|
void eat(int cycles = 1) {
|
||||||
for (int cycle = 0; cycle < cycles; ++cycle)
|
for (int cycle = 0; cycle < cycles; ++cycle)
|
||||||
memoryRead(0xffff);
|
memoryRead(Mask16);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read/Modify/Write
|
||||||
|
|
||||||
|
// Macro version: easy to use
|
||||||
|
// RMW(AM_direct_byte, asl)
|
||||||
|
#define RMW(ACCESSOR, OPERATION) \
|
||||||
|
{ \
|
||||||
|
const auto data = ACCESSOR(); \
|
||||||
|
const auto address = BUS().ADDRESS(); \
|
||||||
|
const auto result = OPERATION(data); \
|
||||||
|
eat(); \
|
||||||
|
memoryWrite(address, result); \
|
||||||
|
}
|
||||||
|
|
||||||
|
typedef std::function<uint8_t(void)> accessor_t;
|
||||||
|
typedef std::function<uint8_t(uint8_t)> operation_t;
|
||||||
|
|
||||||
|
// C++ 11 version: looks great, but verbose to use
|
||||||
|
// rmw([this]() { return AM_direct_byte(); }, [this](uint8_t data) { return asl(data); });
|
||||||
|
void rmw(accessor_t accessor, operation_t operation) {
|
||||||
|
const auto data = accessor();
|
||||||
|
const auto address = BUS().ADDRESS();
|
||||||
|
const auto result = operation(data);
|
||||||
|
eat();
|
||||||
|
memoryWrite(address, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Stack manipulation
|
// Stack manipulation
|
||||||
@@ -363,7 +391,6 @@ namespace EightBit {
|
|||||||
uint8_t rol(uint8_t operand);
|
uint8_t rol(uint8_t operand);
|
||||||
uint8_t ror(uint8_t operand);
|
uint8_t ror(uint8_t operand);
|
||||||
void rti();
|
void rti();
|
||||||
void rts();
|
|
||||||
uint8_t sbc(uint8_t operand, uint8_t data);
|
uint8_t sbc(uint8_t operand, uint8_t data);
|
||||||
uint8_t sub(uint8_t operand, uint8_t data, uint8_t carry = 0);
|
uint8_t sub(uint8_t operand, uint8_t data, uint8_t carry = 0);
|
||||||
register16_t sub(register16_t operand, register16_t data);
|
register16_t sub(register16_t operand, register16_t data);
|
||||||
|
@@ -4,16 +4,6 @@
|
|||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
|
|
||||||
// Read/Modify/Write
|
|
||||||
#define RMW(ACCESSOR, OPERATION) \
|
|
||||||
{ \
|
|
||||||
const auto data = ACCESSOR(); \
|
|
||||||
const auto address = BUS().ADDRESS(); \
|
|
||||||
const auto result = OPERATION(data); \
|
|
||||||
eat(); \
|
|
||||||
memoryWrite(address, result); \
|
|
||||||
}
|
|
||||||
|
|
||||||
EightBit::mc6809::mc6809(Bus& bus)
|
EightBit::mc6809::mc6809(Bus& bus)
|
||||||
: BigEndianProcessor(bus) {
|
: BigEndianProcessor(bus) {
|
||||||
RaisedPOWER.connect([this](EventArgs) {
|
RaisedPOWER.connect([this](EventArgs) {
|
||||||
@@ -61,17 +51,17 @@ void EightBit::mc6809::handleHALT() {
|
|||||||
|
|
||||||
void EightBit::mc6809::handleRESET() {
|
void EightBit::mc6809::handleRESET() {
|
||||||
BigEndianProcessor::handleRESET();
|
BigEndianProcessor::handleRESET();
|
||||||
memoryRead(0xfffe);
|
memoryRead({ 0xff, RESETvector });
|
||||||
raiseNMI();
|
raiseNMI();
|
||||||
lowerBA();
|
lowerBA();
|
||||||
raiseBS();
|
raiseBS();
|
||||||
DP() = 0;
|
DP() = 0;
|
||||||
CC() = setBit(CC(), IF); // Disable IRQ
|
CC() = setBit(CC(), IF); // Disable IRQ
|
||||||
CC() = setBit(CC(), FF); // Disable FIRQ
|
CC() = setBit(CC(), FF); // Disable FIRQ
|
||||||
memoryRead(0xfffe);
|
memoryRead();
|
||||||
memoryRead(0xfffe);
|
memoryRead();
|
||||||
memoryRead(0xfffe);
|
memoryRead();
|
||||||
jump(getWordPaged(0xff, RESETvector));
|
jump(getWord());
|
||||||
eat();
|
eat();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -142,6 +132,11 @@ void EightBit::mc6809::call(register16_t destination) {
|
|||||||
jump(destination);
|
jump(destination);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void EightBit::mc6809::ret() {
|
||||||
|
BigEndianProcessor::ret();
|
||||||
|
eat();
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|
||||||
int EightBit::mc6809::execute() {
|
int EightBit::mc6809::execute() {
|
||||||
@@ -421,7 +416,7 @@ void EightBit::mc6809::executeUnprefixed() {
|
|||||||
case 0x3B: memoryRead(); rti(); break; // RTI (inherent)
|
case 0x3B: memoryRead(); rti(); break; // RTI (inherent)
|
||||||
|
|
||||||
// RTS
|
// RTS
|
||||||
case 0x39: memoryRead(); rts(); break; // RTS (inherent)
|
case 0x39: memoryRead(); ret(); break; // RTS (inherent)
|
||||||
|
|
||||||
// SBC
|
// SBC
|
||||||
|
|
||||||
@@ -1088,11 +1083,6 @@ void EightBit::mc6809::rti() {
|
|||||||
eat();
|
eat();
|
||||||
}
|
}
|
||||||
|
|
||||||
void EightBit::mc6809::rts() {
|
|
||||||
ret();
|
|
||||||
eat();
|
|
||||||
}
|
|
||||||
|
|
||||||
void EightBit::mc6809::swi() {
|
void EightBit::mc6809::swi() {
|
||||||
eat();
|
eat();
|
||||||
saveEntireRegisterState();
|
saveEntireRegisterState();
|
||||||
|
Reference in New Issue
Block a user