mirror of
https://github.com/dingusdev/dingusppc.git
synced 2024-12-27 00:29:18 +00:00
0bd9d0e973
First, remove name override for subclasses of HWComponent (Chaos and ScsiBus) because HWComponent has its own name field. HWComponent name should be set as early as possible in the constructor so it can be used in log messages. PCIDevice should set name of HWComponent (through MMIODevice) in its constructor, using the name that is given to its constructor. For Bandit and Grackle, they don't need to set the HWComponent name since its PCIDevice constructor will now do it. Chaos is not a PCIDevice so it should set the MMIODevice name itself. Why does PCIDevice have a name that is separate from the HWComponent name?
122 lines
3.1 KiB
C++
122 lines
3.1 KiB
C++
/*
|
|
DingusPPC - The Experimental PowerPC Macintosh emulator
|
|
Copyright (C) 2018-22 divingkatae and maximum
|
|
(theweirdo) spatium
|
|
|
|
(Contact divingkatae#1017 or powermax#2286 on Discord for more info)
|
|
|
|
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, either version 3 of the License, or
|
|
(at your option) any later version.
|
|
|
|
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 <https://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
/** @file SCSI bus definitions. */
|
|
|
|
#ifndef SCSI_H
|
|
#define SCSI_H
|
|
|
|
#include <devices/common/hwcomponent.h>
|
|
|
|
#include <array>
|
|
#include <cinttypes>
|
|
#include <string>
|
|
|
|
/** SCSI control signals.
|
|
Bit positions follow the MESH controller convention for easier mapping.
|
|
*/
|
|
enum {
|
|
SCSI_CTRL_IO = 1 << 0,
|
|
SCSI_CTRL_CD = 1 << 1,
|
|
SCSI_CTRL_MSG = 1 << 2,
|
|
SCSI_CTRL_ATN = 1 << 3,
|
|
SCSI_CTRL_ACK = 1 << 4,
|
|
SCSI_CTRL_REQ = 1 << 5,
|
|
SCSI_CTRL_SEL = 1 << 6,
|
|
SCSI_CTRL_BSY = 1 << 7,
|
|
SCSI_CTRL_RST = 1 << 8,
|
|
};
|
|
|
|
enum ScsiPhase : int {
|
|
BUS_FREE = 0,
|
|
ARBITRATION,
|
|
SELECTION,
|
|
RESELECTION,
|
|
RESET,
|
|
};
|
|
|
|
enum ScsiMsg : int {
|
|
CONFIRM_SEL = 1,
|
|
BUS_PHASE_CHANGE,
|
|
};
|
|
|
|
/** Standard SCSI bus timing values measured in ns. */
|
|
#define BUS_SETTLE_DELAY 400
|
|
#define BUS_FREE_DELAY 800
|
|
#define BUS_CLEAR_DELAY 800
|
|
#define ARB_DELAY 2400
|
|
#define SEL_ABORT_TIME 200000
|
|
#define SEL_TIME_OUT 250000000
|
|
|
|
#define SCSI_MAX_DEVS 8
|
|
|
|
class ScsiDevice : public HWComponent {
|
|
public:
|
|
ScsiDevice() = default;
|
|
~ScsiDevice() = default;
|
|
|
|
virtual void notify(ScsiMsg msg_type, int param) = 0;
|
|
|
|
private:
|
|
int scsi_id;
|
|
};
|
|
|
|
/** This class provides a higher level abstraction for the SCSI bus. */
|
|
class ScsiBus : public HWComponent {
|
|
public:
|
|
ScsiBus();
|
|
~ScsiBus() = default;
|
|
|
|
// low-level control/status
|
|
void register_device(int id, ScsiDevice* dev_obj);
|
|
void assert_ctrl_line(int id, uint16_t mask);
|
|
void release_ctrl_line(int id, uint16_t mask);
|
|
void release_ctrl_lines(int id);
|
|
int current_phase() { return this->cur_phase; };
|
|
|
|
// high-level control/status
|
|
bool begin_arbitration(int id);
|
|
bool end_arbitration(int id);
|
|
bool begin_selection(int initiator_id, int target_id, bool atn);
|
|
void confirm_selection(int target_id);
|
|
bool end_selection(int initiator_id, int target_id);
|
|
void disconnect(int dev_id);
|
|
|
|
protected:
|
|
void change_bus_phase(int initiator_id);
|
|
|
|
private:
|
|
// SCSI devices registered with this bus
|
|
std::array<ScsiDevice*, SCSI_MAX_DEVS> devices;
|
|
|
|
// per-device state of the control lines
|
|
uint16_t dev_ctrl_lines[SCSI_MAX_DEVS];
|
|
|
|
uint16_t ctrl_lines;
|
|
int cur_phase;
|
|
int arb_winner_id;
|
|
int initiator_id;
|
|
int target_id;
|
|
uint8_t data_lines;
|
|
};
|
|
|
|
#endif // SCSI_H
|