mirror of
https://github.com/FrancescoRigoni/Lib65816.git
synced 2024-09-29 09:54:44 +00:00
95 lines
3.3 KiB
C++
95 lines
3.3 KiB
C++
|
/*
|
||
|
* This file is part of the 65816 Emulator Library.
|
||
|
* Copyright (c) 2018 Francesco Rigoni.
|
||
|
*
|
||
|
* https://github.com/FrancescoRigoni/Lib65816
|
||
|
*
|
||
|
* This program is free software: you can redistribute it and/or modify
|
||
|
* it under the terms of the GNU General Public License as published by
|
||
|
* the Free Software Foundation, version 3.
|
||
|
*
|
||
|
* This program is distributed in the hope that it will be useful, but
|
||
|
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||
|
* General Public License for more details.
|
||
|
*
|
||
|
* You should have received a copy of the GNU General Public License
|
||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||
|
*/
|
||
|
|
||
|
#include <cmath>
|
||
|
#include "SystemBus.hpp"
|
||
|
#include "Log.hpp"
|
||
|
|
||
|
#define LOG_TAG "SystemBus"
|
||
|
|
||
|
void SystemBus::registerDevice(SystemBusDevice *device) {
|
||
|
mDevices.push_back(device);
|
||
|
}
|
||
|
|
||
|
void SystemBus::storeByte(const Address &address, uint8_t value) {
|
||
|
for (SystemBusDevice *device : mDevices) {
|
||
|
Address decodedAddress;
|
||
|
if (device->decodeAddress(address, decodedAddress)) {
|
||
|
device->storeByte(decodedAddress, value);
|
||
|
return;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void SystemBus::storeTwoBytes(const Address &address, uint16_t value) {
|
||
|
for (SystemBusDevice *device : mDevices) {
|
||
|
Address decodedAddress;
|
||
|
if (device->decodeAddress(address, decodedAddress)) {
|
||
|
uint8_t leastSignificantByte = (uint8_t)(value & 0xFF);
|
||
|
uint8_t mostSignificantByte = (uint8_t)((value & 0xFF00) >> 8);
|
||
|
device->storeByte(decodedAddress, leastSignificantByte);
|
||
|
decodedAddress.incrementOffsetBy(1);
|
||
|
device->storeByte(decodedAddress, mostSignificantByte);
|
||
|
return;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
uint8_t SystemBus::readByte(const Address &address) {
|
||
|
for (SystemBusDevice *device : mDevices) {
|
||
|
Address decodedAddress;
|
||
|
if (device->decodeAddress(address, decodedAddress)) {
|
||
|
return device->readByte(decodedAddress);
|
||
|
}
|
||
|
}
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
uint16_t SystemBus::readTwoBytes(const Address &address) {
|
||
|
for (SystemBusDevice *device : mDevices) {
|
||
|
Address decodedAddress;
|
||
|
if (device->decodeAddress(address, decodedAddress)) {
|
||
|
uint8_t leastSignificantByte = device->readByte(decodedAddress);
|
||
|
decodedAddress.incrementOffsetBy(sizeof(uint8_t));
|
||
|
uint8_t mostSignificantByte = device->readByte(decodedAddress);
|
||
|
uint16_t value = ((uint16_t)mostSignificantByte << 8) | leastSignificantByte;
|
||
|
return value;
|
||
|
}
|
||
|
}
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
Address SystemBus::readAddressAt(const Address &address) {
|
||
|
Address decodedAddress { 0x00, 0x0000 };
|
||
|
for (SystemBusDevice *device : mDevices) {
|
||
|
if (device->decodeAddress(address, decodedAddress)) {
|
||
|
// Read offset
|
||
|
uint8_t leastSignificantByte = device->readByte(decodedAddress);
|
||
|
decodedAddress.incrementOffsetBy(sizeof(uint8_t));
|
||
|
uint8_t mostSignificantByte = device->readByte(decodedAddress);
|
||
|
uint16_t offset = ((uint16_t)mostSignificantByte << 8) | leastSignificantByte;
|
||
|
// Read bank
|
||
|
decodedAddress.incrementOffsetBy(sizeof(uint8_t));
|
||
|
uint8_t bank = device->readByte(decodedAddress);
|
||
|
return Address(bank, offset);
|
||
|
}
|
||
|
}
|
||
|
return decodedAddress;
|
||
|
}
|