53C94: chip initialization and identification.

This commit is contained in:
Maxim Poliakovski 2022-01-22 04:36:31 +01:00
parent c8d39d5ee5
commit 5883524fb8
5 changed files with 163 additions and 63 deletions

View File

@ -1,38 +0,0 @@
/*
DingusPPC - The Experimental PowerPC Macintosh emulator
Copyright (C) 2018-21 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 NCR 53C94 SCSI controller emulation. */
#include "ncr53c94.h"
#include <loguru.hpp>
#include <cinttypes>
uint8_t Ncr53C94::read(uint8_t reg_offset)
{
LOG_F(9, "NCR53C94: reading from register %d", reg_offset);
return 0;
}
void Ncr53C94::write(uint8_t reg_offset, uint8_t value)
{
LOG_F(INFO, "NCR53C94: writing 0x%X to %d register", value, reg_offset);
}

View File

@ -0,0 +1,115 @@
/*
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 NCR53C94/Am53CF94 SCSI controller emulation. */
#include "sc53c94.h"
#include <loguru.hpp>
#include <cinttypes>
void Sc53C94::reset_device()
{
// part-unique ID to be read using a magic sequence
this->set_xfer_count = this->chip_id << 16;
this->clk_factor = 2;
this->sel_timeout = 0;
}
uint8_t Sc53C94::read(uint8_t reg_offset)
{
switch (reg_offset) {
case Read::Reg53C94::Xfer_Cnt_Hi:
if (this->config2 & CFG2_ENF) {
return (this->xfer_count >> 16) & 0xFFU;
}
break;
default:
LOG_F(9, "NCR53C94: reading from register %d", reg_offset);
}
return 0;
}
void Sc53C94::write(uint8_t reg_offset, uint8_t value)
{
switch (reg_offset) {
case Write::Reg53C94::Command:
add_command(value);
break;
case Write::Reg53C94::Sel_Timeout:
this->sel_timeout = value;
break;
case Write::Reg53C94::Clock_Factor:
this->clk_factor = value;
break;
case Write::Reg53C94::Config_1:
this->config1 = value;
break;
case Write::Reg53C94::Config_2:
this->config2 = value;
break;
case Write::Reg53C94::Config_3:
this->config3 = value;
break;
default:
LOG_F(INFO, "SC53C94: writing 0x%X to %d register", value, reg_offset);
}
}
void Sc53C94::add_command(uint8_t cmd)
{
bool is_dma_cmd = !!(cmd & 0x80);
cmd &= 0x7F;
if (this->on_reset && cmd != CMD_NOP) {
LOG_F(WARNING, "SC53C94: command register blocked after RESET!");
return;
}
// NOTE: Reset Device (chip), Reset Bus and DMA Stop commands execute
// immediately while all others are placed into the command FIFO
switch (cmd) {
case CMD_RESET_DEVICE:
reset_device();
this->on_reset = true; // block the command register
return;
case CMD_RESET_BUS:
LOG_F(ERROR, "SC53C94: RESET_BUS command not implemented yet");
return;
case CMD_DMA_STOP:
LOG_F(ERROR, "SC53C94: TARGET_DMA_STOP command not implemented yet");
return;
}
// HACK: commands should be placed into the command FIFO
if (cmd == CMD_NOP) {
if (is_dma_cmd) {
if (this->config2 & CFG2_ENF) { // extended mode: 24-bit
this->xfer_count = this->set_xfer_count & 0xFFFFFFUL;
} else { // standard mode: 16-bit
this->xfer_count = this->set_xfer_count & 0xFFFFUL;
}
}
this->on_reset = false;
}
}

View File

@ -1,6 +1,6 @@
/*
DingusPPC - The Experimental PowerPC Macintosh emulator
Copyright (C) 2018-21 divingkatae and maximum
Copyright (C) 2018-22 divingkatae and maximum
(theweirdo) spatium
(Contact divingkatae#1017 or powermax#2286 on Discord for more info)
@ -19,19 +19,19 @@ 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 NCR 53C94 SCSI controller definitions. */
/** @file NCR53C94/Am53CF94 SCSI controller definitions. */
/* NOTE: Power Macintosh computers don't have a real NCR 53C94 chip.
The corresponding functionality is provided by the 53C94 compatible
The corresponding functionality is provided by the 53CF94 compatible
cell in the custom Curio IC (Am79C950).
*/
#ifndef NCR53C94_H
#define NCR53C94_H
#ifndef SC_53C94_H
#define SC_53C94_H
#include <cinttypes>
/** NCR 53C94 read registers */
/** 53C94 read registers */
namespace Read {
enum Reg53C94 : uint8_t {
Xfer_Cnt_LSB = 0,
@ -45,13 +45,12 @@ namespace Read {
Config_1 = 8,
Config_2 = 0xB,
Config_3 = 0xC,
Config_4 = 0xD, // Curio extension?
Xfer_Cnt_Hi = 0xE, // Curio extension?
DMA = 0xF, // Curio extension?
Config_4 = 0xD, // Am53CF94 extension
Xfer_Cnt_Hi = 0xE, // Am53CF94 extension
};
};
/** NCR 53C94 write registers */
/** 53C94 write registers */
namespace Write {
enum Reg53C94 : uint8_t {
Xfer_Cnt_LSB = 0,
@ -63,27 +62,51 @@ namespace Write {
Synch_Period = 6,
Synch_Offset = 7,
Config_1 = 8,
Clk_Conv_Fac = 9,
Clock_Factor = 9,
Test_Mode = 0xA,
Config_2 = 0xB,
Config_3 = 0xC,
Config_4 = 0xD, // Curio extension?
Chip_ID = 0xE, // Curio extension?
DMA = 0xF, // Curio extension?
Config_4 = 0xD, // Am53CF94 extension
Xfer_Cnt_Hi = 0xE, // Am53CF94 extension
Data_Align = 0xF
};
};
class Ncr53C94 {
public:
Ncr53C94() = default;
~Ncr53C94() = default;
enum {
CMD_NOP = 0,
CMD_CLEAR_FIFO = 1,
CMD_RESET_DEVICE = 2,
CMD_RESET_BUS = 3,
CMD_DMA_STOP = 4,
};
// NCR 53C94 registers access
enum {
CFG2_ENF = 0x40, // Am53CF94: enable features (ENF) bit
};
class Sc53C94 {
public:
Sc53C94(uint8_t chip_id=12) { this->chip_id = chip_id; };
~Sc53C94() = default;
// 53C94 registers access
uint8_t read(uint8_t reg_offset);
void write(uint8_t reg_offset, uint8_t value);
protected:
void reset_device();
void add_command(uint8_t cmd);
private:
uint8_t chip_id;
uint8_t chip_id;
bool on_reset = false;
uint32_t xfer_count;
uint32_t set_xfer_count;
uint8_t sel_timeout;
uint8_t clk_factor;
uint8_t config1;
uint8_t config2;
uint8_t config3;
};
#endif // NCR53C94_H
#endif // SC_53C94_H

View File

@ -27,7 +27,7 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
#include <core/timermanager.h>
#include <cpu/ppc/ppcemu.h>
#include <cpu/ppc/ppcmmu.h>
#include <devices/common/scsi/ncr53c94.h>
#include <devices/common/scsi/sc53c94.h>
#include <devices/common/viacuda.h>
#include <devices/ethernet/mace.h>
#include <devices/floppy/swim3.h>
@ -48,7 +48,7 @@ AMIC::AMIC() : MMIODevice()
this->name = "Apple Memory-mapped I/O Controller";
// register I/O devices
this->scsi = std::unique_ptr<Ncr53C94> (new Ncr53C94());
this->scsi = std::unique_ptr<Sc53C94> (new Sc53C94());
this->escc = std::unique_ptr<EsccController> (new EsccController());
this->mace = std::unique_ptr<MaceController> (new MaceController(MACE_ID));
this->viacuda = std::unique_ptr<ViaCuda> (new ViaCuda());

View File

@ -26,7 +26,7 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
#include <devices/common/hwinterrupt.h>
#include <devices/common/mmiodevice.h>
#include <devices/common/scsi/ncr53c94.h>
#include <devices/common/scsi/sc53c94.h>
#include <devices/common/viacuda.h>
#include <devices/ethernet/mace.h>
#include <devices/floppy/swim3.h>
@ -174,7 +174,7 @@ private:
uint32_t pseudo_vbl_tid; // ID for the pseudo-VBL timer
// AMIC subdevices instances
std::unique_ptr<Ncr53C94> scsi;
std::unique_ptr<Sc53C94> scsi;
std::unique_ptr<EsccController> escc;
std::unique_ptr<MaceController> mace;
std::unique_ptr<ViaCuda> viacuda;