Powerview Compiles with develop merged (Wont work though)

This commit is contained in:
Tony Kuker 2023-02-03 23:31:32 -06:00
parent 428376d9c2
commit b86bf4b47a
8 changed files with 850 additions and 715 deletions

View File

@ -15,6 +15,7 @@
#include "scsi_printer.h"
#include "scsi_host_bridge.h"
#include "scsi_daynaport.h"
#include "scsi_powerview.h"
#include "host_services.h"
#include "device_factory.h"
#include <ifaddrs.h>
@ -64,6 +65,7 @@ DeviceFactory::DeviceFactory()
device_mapping["daynaport"] = SCDP;
device_mapping["printer"] = SCLP;
device_mapping["services"] = SCHS;
device_mapping["powerview"] = SCPV;
}
PbDeviceType DeviceFactory::GetTypeForFile(const string& filename) const
@ -151,6 +153,15 @@ shared_ptr<PrimaryDevice> DeviceFactory::CreateDevice(PbDeviceType type, int lun
device->SetDefaultParams(default_params.find(SCLP)->second);
break;
case SCPV:
device = make_shared<SCSIPowerView>(lun);
// Since this is an emulation for a specific device the full INQUIRY data have to be set accordingly
device->SetVendor("RADIUS ");
device->SetProduct("PowerView ");
device->SetRevision("V1.0");
device->SetDefaultParams(default_params.find(SCPV)->second);
break;
default:
break;
}

View File

@ -12,6 +12,7 @@
#pragma once
#include <vector>
#include <cstdint>
using namespace std;

View File

@ -1,9 +1,8 @@
//---------------------------------------------------------------------------
//
// SCSI Target Emulator RaSCSI (*^..^*)
// for Raspberry Pi
// SCSI Target Emulator PiSCSI for Raspberry Pi
//
// Copyright (C) 2020-2021 akuker
// Copyright (C) 2020-2023 akuker
// Copyright (C) 2020 joshua stein <jcs@jcs.org>
//
// Licensed under the BSD 3-Clause License.
@ -19,37 +18,51 @@
//---------------------------------------------------------------------------
#include "scsi_powerview.h"
#include <sstream>
#include <iomanip>
#include <sstream>
#include <string>
#include <sys/ioctl.h>
#include "exceptions.h"
// #include "exceptions.h"
#include <err.h>
#include <fcntl.h>
#include <linux/fb.h>
#include "os.h"
#include "disk.h"
// #include "os.h"
// #include "disk.h"
#include <sys/mman.h>
#include "log.h"
#include "controllers/scsidev_ctrl.h"
#include "shared/log.h"
// #include "controllers/scsidev_ctrl.h"
unsigned char SCSIPowerView::reverse_table[256];
const BYTE SCSIPowerView::m_inquiry_response[] = {
0x03, 0x00, 0x01, 0x01, 0x46, 0x00, 0x00, 0x00, 0x52, 0x41, 0x44, 0x49, 0x55, 0x53, 0x20, 0x20,
0x50, 0x6F, 0x77, 0x65, 0x72, 0x56, 0x69, 0x65, 0x77, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
0x56, 0x31, 0x2E, 0x30, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x20, 0x00, 0x01, 0x00, 0x00, 0x00,
0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00,
0x05, 0x00, 0x00, 0x00, 0x00, 0x06, 0x43, 0xF9, 0x00, 0x00, 0xFF,
const uint8_t SCSIPowerView::m_inquiry_response[] = {
0x03, 0x00, 0x01, 0x01, 0x46, 0x00, 0x00, 0x00, 0x52, 0x41, 0x44, 0x49, 0x55, 0x53, 0x20, 0x20, 0x50, 0x6F, 0x77,
0x65, 0x72, 0x56, 0x69, 0x65, 0x77, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x56, 0x31, 0x2E, 0x30, 0x00, 0x00,
0x00, 0x00, 0x10, 0x00, 0x20, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00,
0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x06, 0x43, 0xF9, 0x00, 0x00, 0xFF,
};
SCSIPowerView::SCSIPowerView() : Disk("SCPV")
using namespace scsi_defs;
// using namespace scsi_command_util;
SCSIPowerView::SCSIPowerView(int lun) : PrimaryDevice(SCPV, lun)
{
SupportsParams(true);
}
bool SCSIPowerView::Init(const unordered_map<string, string>& params)
{
LOGTRACE("Entering %s", __PRETTY_FUNCTION__);
AddCommand(SCSIDEV::eCmdPvReadConfig, "Unknown PowerViewC8", &SCSIPowerView::CmdReadConfig);
AddCommand(SCSIDEV::eCmdPvWriteConfig, "Unknown PowerViewC9", &SCSIPowerView::CmdWriteConfig);
AddCommand(SCSIDEV::eCmdPvWriteFrameBuffer, "Unknown PowerViewCA", &SCSIPowerView::CmdWriteFramebuffer);
AddCommand(SCSIDEV::eCmdPvWriteColorPalette, "Unknown PowerViewCB", &SCSIPowerView::CmdWriteColorPalette);
AddCommand(SCSIDEV::eCmdUnknownPowerViewCC, "Unknown PowerViewCC", &SCSIPowerView::UnknownCommandCC);
PrimaryDevice::Init(params);
// AddCommand(scsi_command::eCmdTestUnitReady, [this] { TestUnitReady(); });
AddCommand(scsi_command::eCmdPvReadConfig, [this] { CmdReadConfig(); });
AddCommand(scsi_command::eCmdPvWriteConfig, [this] { CmdWriteConfig(); });
AddCommand(scsi_command::eCmdPvWriteFrameBuffer, [this] { CmdWriteFramebuffer(); });
AddCommand(scsi_command::eCmdPvWriteColorPalette, [this] { CmdWriteColorPalette(); });
AddCommand(scsi_command::eCmdUnknownPowerViewCC, [this] { UnknownCommandCC(); });
LOGTRACE("%s - creating lookup table", __PRETTY_FUNCTION__);
@ -63,38 +76,38 @@ SCSIPowerView::SCSIPowerView() : Disk("SCPV")
}
framebuffer_black = 0;
framebuffer_blue = (/*red*/ 0 << fbinfo.red.offset) |
(/*green*/ 0 << fbinfo.green.offset)|
(/*blue*/ 0xFF << fbinfo.blue.offset) |
(/*alpha*/ 0 << fbinfo.transp.offset);
framebuffer_yellow = (/*red*/ 0 << fbinfo.red.offset) |
(/*green*/ 0xFF << fbinfo.green.offset)|
(/*blue*/ 0x0 << fbinfo.blue.offset) |
(/*alpha*/ 0 << fbinfo.transp.offset);
framebuffer_red = (/*red*/ 0xFF << fbinfo.red.offset) |
(/*green*/ 0 << fbinfo.green.offset)|
(/*blue*/ 0 << fbinfo.blue.offset) |
(/*alpha*/ 0 << fbinfo.transp.offset);
framebuffer_blue = (/*red*/ 0 << fbinfo.red.offset) | (/*green*/ 0 << fbinfo.green.offset) |
(/*blue*/ 0xFF << fbinfo.blue.offset) | (/*alpha*/ 0 << fbinfo.transp.offset);
framebuffer_yellow = (/*red*/ 0 << fbinfo.red.offset) | (/*green*/ 0xFF << fbinfo.green.offset) |
(/*blue*/ 0x0 << fbinfo.blue.offset) | (/*alpha*/ 0 << fbinfo.transp.offset);
framebuffer_red = (/*red*/ 0xFF << fbinfo.red.offset) | (/*green*/ 0 << fbinfo.green.offset) |
(/*blue*/ 0 << fbinfo.blue.offset) | (/*alpha*/ 0 << fbinfo.transp.offset);
// Default to one bit color (black & white) if we don't know any better
color_depth = eColorsBW;
(void)HwInit();
LOGTRACE("Done with %s", __PRETTY_FUNCTION__);
return true;
}
// void SCSIPowerView::TestUnitReady()
// {
// // Always successful
// EnterStatusPhase();
// }
//---------------------------------------------------------------------------
//
// Log a message to the framebuffer display
//
//---------------------------------------------------------------------------
void SCSIPowerView::fbcon_text(char* message)
void SCSIPowerView::fbcon_text(const char* message)
{
int fd = open("/dev/tty1", O_RDWR);
if (0 < fd)
{
if (0 < fd) {
write(fd, message, strlen(message));
}
else
{
} else {
LOGWARN("%s Unable to open /dev/tty1", __PRETTY_FUNCTION__);
}
close(fd);
@ -109,13 +122,10 @@ void SCSIPowerView::fbcon_text(char* message)
void SCSIPowerView::fbcon_cursor(bool blank)
{
int fd = open("/dev/tty1", O_RDWR);
if (0 < fd)
{
if (0 < fd) {
write(fd, "\033[?25", 5);
write(fd, blank ? "h" : "l", 1);
}
else
{
} else {
LOGWARN("%s Unable to open /dev/tty1", __PRETTY_FUNCTION__);
}
close(fd);
@ -144,24 +154,17 @@ SCSIPowerView::~SCSIPowerView()
munmap(this->fb, fbfixinfo.smem_len);
close(this->fbfd);
for (auto const& command : commands) {
delete command.second;
}
// for (auto const& command : commands) {
// delete command.second;
// }
}
void SCSIPowerView::AddCommand(SCSIDEV::scsi_command opcode, const char* name, void (SCSIPowerView::*execute)(SASIDEV *))
void SCSIPowerView::ClearFrameBuffer(uint32_t blank_color)
{
commands[opcode] = new command_t(name, execute);
}
void SCSIPowerView::ClearFrameBuffer(DWORD blank_color){
// For each row
for (DWORD idx_row_y = 0; idx_row_y < fbinfo.yres-1; idx_row_y++){
for (uint32_t idx_row_y = 0; idx_row_y < fbinfo.yres - 1; idx_row_y++) {
// For each column
for (DWORD idx_col_x = 0; idx_col_x < fbinfo.xres-1; idx_col_x++){
for (uint32_t idx_col_x = 0; idx_col_x < fbinfo.xres - 1; idx_col_x++) {
uint32_t loc = ((idx_col_x) * (this->fbbpp / 8)) + ((idx_row_y)*fblinelen);
uint8_t temp_color = blank_color;
@ -171,8 +174,6 @@ void SCSIPowerView::ClearFrameBuffer(DWORD blank_color){
}
}
}
}
//---------------------------------------------------------------------------
@ -181,196 +182,250 @@ void SCSIPowerView::ClearFrameBuffer(DWORD blank_color){
//
//---------------------------------------------------------------------------
// void SCSIPowerView::CmdPvReadConfig(SASIDEV *controller)
void SCSIPowerView::CmdReadConfig(SASIDEV *controller)
void SCSIPowerView::CmdReadConfig()
{
// GetController()->SetLength(Read(GetController()->GetCmd(), GetController()->GetBuffer(), record));
// GetController()->Error(sense_key::ILLEGAL_REQUEST, asc::INVALID_LUN);
// GetController()->SetStatus(status::GOOD);
// GetController()->SetLength(RetrieveStats(GetController()->GetCmd(), GetController()->GetBuffer()));
// // Set next block
// GetController()->SetBlocks(1);
// GetController()->SetNext(1);
// Set transfer amount
ctrl->length = ctrl->cmd[6];
LOGWARN("%s Message Length %d", __PRETTY_FUNCTION__, (int)ctrl->length);
/////// ctrl->length = ctrl->cmd[6];
int length = GetController()->GetCmd(6);
if (ctrl->length <= 0) {
GetController()->SetLength(length);
LOGWARN("%s Message Length %d", __PRETTY_FUNCTION__, (int)length);
vector<uint8_t>& buffer = GetController()->GetBuffer();
/////////if (ctrl->length <= 0) {
if (length <= 0) {
// Failure (Error)
controller->Error();
///////////controller->Error();
GetController()->Error(sense_key::ILLEGAL_REQUEST, asc::INVALID_FIELD_IN_CDB);
return;
}
// Response to "C8 00 00 31 83 00 01 00" is "00"
if(ctrl->cmd[4] == 0x83){
if(ctrl->length != 1){
LOGWARN("%s Received unexpected length: %02X %02X %02X %02X %02X %02X", __PRETTY_FUNCTION__, ctrl->cmd[0], ctrl->cmd[1], ctrl->cmd[2], ctrl->cmd[3], ctrl->cmd[4], ctrl->cmd[5]);
//////////if(ctrl->cmd[4] == 0x83){
if (GetController()->GetCmd(4) == 0x83) {
if (length != 1) {
LOGWARN("%s Received unexpected length: %02X %02X %02X %02X %02X %02X", __PRETTY_FUNCTION__,
GetController()->GetCmd(0), GetController()->GetCmd(1), GetController()->GetCmd(2),
GetController()->GetCmd(3), GetController()->GetCmd(4), GetController()->GetCmd(5));
}
}
// Response to "C8 00 00 31 00 00 03 00" is "01 09 08"
else if(ctrl->cmd[4] == 0x00){
if(ctrl->length != 3){
LOGWARN("%s Received unexpected length: %02X %02X %02X %02X %02X %02X", __PRETTY_FUNCTION__, ctrl->cmd[0], ctrl->cmd[1], ctrl->cmd[2], ctrl->cmd[3], ctrl->cmd[4], ctrl->cmd[5]);
/////////else if(ctrl->cmd[4] == 0x00){
else if (GetController()->GetCmd(4) == 0x00) {
if (length != 3) {
LOGWARN("%s Received unexpected length: %02X %02X %02X %02X %02X %02X", __PRETTY_FUNCTION__,
GetController()->GetCmd(0), GetController()->GetCmd(1), GetController()->GetCmd(2),
GetController()->GetCmd(3), GetController()->GetCmd(4), GetController()->GetCmd(5));
}
}
// Response to "C8 00 00 31 82 00 01 00" is "01"
else if(ctrl->cmd[4] == 0x82){
ctrl->buffer[0] = 0x01;
if(ctrl->length != 1){
LOGWARN("%s Received unexpected length: %02X %02X %02X %02X %02X %02X", __PRETTY_FUNCTION__, ctrl->cmd[0], ctrl->cmd[1], ctrl->cmd[2], ctrl->cmd[3], ctrl->cmd[4], ctrl->cmd[5]);
else if (GetController()->GetCmd(4) == 0x82) {
buffer[0] = 0x01;
if (length != 1) {
LOGWARN("%s Received unexpected length: %02X %02X %02X %02X %02X %02X", __PRETTY_FUNCTION__,
GetController()->GetCmd(0), GetController()->GetCmd(1), GetController()->GetCmd(2),
GetController()->GetCmd(3), GetController()->GetCmd(4), GetController()->GetCmd(5));
}
}
else{
LOGWARN("%s Unhandled command received: %02X %02X %02X %02X %02X %02X", __PRETTY_FUNCTION__, ctrl->cmd[0], ctrl->cmd[1], ctrl->cmd[2], ctrl->cmd[3], ctrl->cmd[4], ctrl->cmd[5]);
ctrl->buffer[0] = 0x00;
ctrl->buffer[1] = 0x00;
ctrl->buffer[2] = 0x00;
} else {
LOGWARN("%s Unhandled command received: %02X %02X %02X %02X %02X %02X", __PRETTY_FUNCTION__,
GetController()->GetCmd(0), GetController()->GetCmd(1), GetController()->GetCmd(2),
GetController()->GetCmd(3), GetController()->GetCmd(4), GetController()->GetCmd(5));
buffer[0] = 0x00;
buffer[1] = 0x00;
buffer[2] = 0x00;
}
// Set next block
ctrl->blocks = 1;
ctrl->next = 1;
//////ctrl->blocks = 1;
//////ctrl->next = 1;
controller->DataIn();
GetController()->SetBlocks(1);
GetController()->SetNext(1);
//////controller->DataIn();
EnterDataInPhase();
}
//---------------------------------------------------------------------------
//
// Unknown Command C9 - Write a configuration value?
//
//---------------------------------------------------------------------------
void SCSIPowerView::CmdWriteConfig(SASIDEV *controller)
void SCSIPowerView::CmdWriteConfig()
{
// Set transfer amount
ctrl->length = ctrl->cmd[6];
LOGTRACE("%s Message Length %d", __PRETTY_FUNCTION__, (int)ctrl->length);
////////ctrl->length = ctrl->cmd[6];
int length = GetController()->GetCmd(6);
GetController()->SetLength(length);
LOGTRACE("%s Message Length %d", __PRETTY_FUNCTION__, length);
if (ctrl->length == 0){
controller->Status();
}
else
{
// Set next block
ctrl->blocks = 1;
ctrl->next = 1;
///////if (ctrl->length == 0){
if (length == 0) {
EnterStatusPhase();
// controller->Status();
} else {
GetController()->SetBlocks(1);
GetController()->SetNext(1);
// // Set next block
// ctrl->blocks = 1;
// ctrl->next = 1;
controller->DataOut();
// controller->DataOut();
EnterDataOutPhase();
}
}
//---------------------------------------------------------------------------
//
// Command to Write a Frame Buffer update
//
//---------------------------------------------------------------------------
void SCSIPowerView::CmdWriteFramebuffer(SASIDEV *controller)
void SCSIPowerView::CmdWriteFramebuffer()
{
// Make sure the receive buffer is big enough
if (ctrl->bufsize < POWERVIEW_BUFFER_SIZE) {
free(ctrl->buffer);
ctrl->bufsize = POWERVIEW_BUFFER_SIZE;
ctrl->buffer = (BYTE *)malloc(ctrl->bufsize);
}
// int bufsize = GetController()->GetBufferSize();
// // Make sure the receive buffer is big enough
// if (ctrl->bufsize < POWERVIEW_BUFFER_SIZE) {
// free(ctrl->buffer);
// ctrl->bufsize = POWERVIEW_BUFFER_SIZE;
// ctrl->buffer = (uint8_t *)malloc(ctrl->bufsize);
// }
// Set transfer amount
uint16_t width_x = ctrl->cmd[5] + (ctrl->cmd[4] << 8);
uint16_t height_y = ctrl->cmd[7] + (ctrl->cmd[6] << 8);
GetController()->AllocateBuffer(POWERVIEW_BUFFER_SIZE);
ctrl->length = width_x * height_y;
// // Set transfer amount
// uint16_t width_x = ctrl->cmd[5] + (ctrl->cmd[4] << 8);
// uint16_t height_y = ctrl->cmd[7] + (ctrl->cmd[6] << 8);
LOGTRACE("%s Message Length %d [%08X]", __PRETTY_FUNCTION__, (int)ctrl->length, (unsigned int)ctrl->length);
uint16_t width_x = GetController()->GetCmd(5) + (GetController()->GetCmd(4) << 8);
uint16_t height_y = GetController()->GetCmd(7) + (GetController()->GetCmd(6) << 8);
if (ctrl->length <= 0) {
// ctrl->length = width_x * height_y;
int length = width_x * height_y;
GetController()->SetLength(length);
LOGTRACE("%s Message Length %d [%08X]", __PRETTY_FUNCTION__, length, length);
if (length <= 0) {
// Failure (Error)
controller->Error();
// controller->Error();
GetController()->Error(sense_key::ILLEGAL_REQUEST, asc::INVALID_FIELD_IN_CDB);
return;
}
// Set next block
ctrl->blocks = 1;
ctrl->next = 1;
// ctrl->blocks = 1;
// ctrl->next = 1;
GetController()->SetBlocks(1);
GetController()->SetNext(1);
controller->DataOut();
// controller->DataOut();
EnterDataOutPhase();
}
//---------------------------------------------------------------------------
//
// Receive a new color palette from the host
//
//---------------------------------------------------------------------------
void SCSIPowerView::CmdWriteColorPalette(SASIDEV *controller)
void SCSIPowerView::CmdWriteColorPalette()
{
eColorDepth_t received_color_depth = (eColorDepth_t)((uint16_t)ctrl->cmd[4] + ((uint16_t)ctrl->cmd[3] << 8));
ctrl->length = (uint16_t)received_color_depth * 4;
LOGTRACE("%s Message Length %d", __PRETTY_FUNCTION__, (int)ctrl->length);
// eColorDepth_t received_color_depth = (eColorDepth_t)((uint16_t)ctrl->cmd[4] + ((uint16_t)ctrl->cmd[3] << 8));
eColorDepth_t received_color_depth =
(eColorDepth_t)((uint16_t)GetController()->GetCmd(4) + ((uint16_t)GetController()->GetCmd(3) << 8));
int length = (uint16_t)received_color_depth * 4;
GetController()->SetLength(length);
LOGTRACE("%s Message Length %d", __PRETTY_FUNCTION__, length);
// The driver sends "1" for black and white, which is really
// TWO colors: Black and White
if (received_color_depth == eColorsBW) {
ctrl->length = 8;
// ctrl->length = 8;
GetController()->SetLength(8);
}
if (ctrl->length <= 0) {
if (length <= 0) {
// Failure (Error)
controller->Error();
// controller->Error();
GetController()->Error(sense_key::ILLEGAL_REQUEST, asc::INVALID_FIELD_IN_CDB);
return;
}
// Set next block
ctrl->blocks = 1;
ctrl->next = 1;
// ctrl->blocks = 1;
// ctrl->next = 1;
GetController()->SetBlocks(1);
GetController()->SetNext(1);
controller->DataOut();
EnterDataOutPhase();
// controller->DataOut();
}
//---------------------------------------------------------------------------
//
// Unknown Command CC
//
//---------------------------------------------------------------------------
void SCSIPowerView::UnknownCommandCC(SASIDEV *controller)
void SCSIPowerView::UnknownCommandCC()
{
// Set transfer amount
ctrl->length = 0x8bb;
LOGTRACE("%s Message Length %d", __PRETTY_FUNCTION__, (int)ctrl->length);
if (ctrl->length <= 0) {
// ctrl->length = 0x8bb;
int length = 0x8bb;
GetController()->SetLength(length);
LOGTRACE("%s Message Length %d", __PRETTY_FUNCTION__, length);
// if (ctrl->length <= 0) {
if (length <= 0) {
// Failure (Error)
controller->Error();
// controller->Error();
GetController()->Error(sense_key::ILLEGAL_REQUEST, asc::INVALID_FIELD_IN_CDB);
return;
}
// Set next block
ctrl->blocks = 1;
ctrl->next = 1;
// ctrl->blocks = 1;
// ctrl->next = 1;
GetController()->SetBlocks(1);
GetController()->SetNext(1);
controller->DataOut();
EnterDataOutPhase();
// controller->DataOut();
}
bool SCSIPowerView::Dispatch(SCSIDEV *controller)
{
ctrl = controller->GetCtrl();
// bool SCSIPowerView::Dispatch(SCSIDEV *controller)
// {
// ctrl = controller->GetCtrl();
if (commands.count(static_cast<SCSIDEV::scsi_command>(ctrl->cmd[0]))) {
command_t *command = commands[static_cast<SCSIDEV::scsi_command>(ctrl->cmd[0])];
// if (commands.count(static_cast<SCSIDEV::scsi_command>(ctrl->cmd[0]))) {
// command_t *command = commands[static_cast<SCSIDEV::scsi_command>(ctrl->cmd[0])];
LOGDEBUG("%s Executing %s ($%02X)", __PRETTY_FUNCTION__, command->name, (unsigned int)ctrl->cmd[0]);
// LOGDEBUG("%s Executing %s ($%02X)", __PRETTY_FUNCTION__, command->name, (unsigned int)ctrl->cmd[0]);
(this->*command->execute)(controller);
// (this->*command->execute)(controller);
return true;
}
// return true;
// }
LOGTRACE("%s Calling base class for dispatching $%02X", __PRETTY_FUNCTION__, (unsigned int)ctrl->cmd[0]);
// LOGTRACE("%s Calling base class for dispatching $%02X", __PRETTY_FUNCTION__, (unsigned int)ctrl->cmd[0]);
// The base class handles the less specific commands
return Disk::Dispatch(controller);
}
// // The base class handles the less specific commands
// return Disk::Dispatch(controller);
// }
bool SCSIPowerView::Init(const map<string, string>& params)
bool SCSIPowerView::HwInit()
{
LOGTRACE("Entering %s", __PRETTY_FUNCTION__);
SetParams(params.empty() ? GetDefaultParams() : params);
this->fbfd = open("/dev/fb0", O_RDWR);
if (this->fbfd == -1) {
@ -390,7 +445,8 @@ bool SCSIPowerView::Init(const map<string, string>& params)
}
if (fbinfo.bits_per_pixel != 16) {
LOGERROR("PowerView emulation only supports 16 bits per pixel framebuffer. Currently set to %d", fbinfo.bits_per_pixel);
LOGERROR("PowerView emulation only supports 16 bits per pixel framebuffer. Currently set to %d",
fbinfo.bits_per_pixel);
LOGERROR("Try running \"fbset -depth 16\"");
return false;
}
@ -401,7 +457,7 @@ bool SCSIPowerView::Init(const map<string, string>& params)
fblinelen = fbfixinfo.line_length;
fb = (char*)mmap(0, fbfixinfo.smem_len, PROT_READ | PROT_WRITE, MAP_SHARED, fbfd, 0);
if ((int)fb == -1){
if (fb == MAP_FAILED) {
LOGERROR("Unable to mmap the framebuffer memory. Are you running as root?");
return false;
}
@ -423,10 +479,11 @@ bool SCSIPowerView::Init(const map<string, string>& params)
ClearFrameBuffer(framebuffer_blue);
// Report status to the screen
char status_string[256];
sprintf(status_string, "PowerView initialized on %dx%d %d bpp framebuffer\r", fbinfo.xres, fbinfo.yres, fbinfo.bits_per_pixel);
fbcon_text(status_string);
LOGINFO(status_string);
// char status_string[256];
string status_string = fmt::format("PowerView initialized on {}x{} {} bpp framebuffer\r", fbinfo.xres, fbinfo.yres,
fbinfo.bits_per_pixel);
fbcon_text(status_string.c_str());
LOGINFO("%s", status_string.c_str());
return true;
}
@ -436,15 +493,18 @@ bool SCSIPowerView::Init(const map<string, string>& params)
// INQUIRY
//
//---------------------------------------------------------------------------
int SCSIPowerView::Inquiry(const DWORD *cdb, BYTE *buf)
// int SCSIPowerView::Inquiry(const uint32_t *cdb, uint8_t *buf)
vector<uint8_t> SCSIPowerView::InquiryInternal() const
{
int allocation_length = cdb[4] + (((DWORD)cdb[3]) << 8);
vector<uint8_t> buf = HandleInquiry(device_type::PROCESSOR, scsi_level::SCSI_2, false);
int allocation_length = GetController()->GetCmd(4) + (((uint32_t)GetController()->GetCmd(3)) << 8);
if (allocation_length > 0) {
if ((unsigned int)allocation_length > sizeof(m_inquiry_response)) {
allocation_length = (int)sizeof(m_inquiry_response);
}
memcpy(buf, m_inquiry_response, allocation_length);
memcpy(buf.data(), m_inquiry_response, allocation_length);
// // Basic data
// // buf[0] ... Processor Device
@ -462,53 +522,64 @@ int SCSIPowerView::Inquiry(const DWORD *cdb, BYTE *buf)
// memcpy(&buf[8], GetPaddedName().c_str(), 28);
}
LOGTRACE("response size is %d", allocation_length);
LOGTRACE("%s response size is %d", __PRETTY_FUNCTION__, allocation_length);
return allocation_length;
return buf;
}
bool SCSIPowerView::WriteConfiguration(const DWORD *cdb, const BYTE *buf, const DWORD length)
bool SCSIPowerView::WriteConfiguration()
{
// const uint32_t *cdb, const uint8_t *buf, const uint32_t length
// vector<int>& cdb = GetController()->GetCmd();
vector<uint8_t>& buf = GetController()->GetBuffer();
int length = GetController()->GetCmd(6); // TODO: Is this right?
std::stringstream ss;
ss << std::hex;
for( DWORD i(0) ; i < length; ++i ){
for (int i(0); i < length; ++i) {
ss << std::setw(2) << std::setfill('0') << (int)buf[i];
}
LOGDEBUG("%s Received Config Write of length %d: %s", __PRETTY_FUNCTION__, length, ss.str().c_str());
return true;
}
bool SCSIPowerView::WriteUnknownCC(const DWORD *cdb, const BYTE *buf, const DWORD length)
bool SCSIPowerView::WriteUnknownCC()
{
// const uint32_t *cdb, const uint8_t *buf, const uint32_t length
// vector<int>& cdb = GetController()->GetCmd();
vector<uint8_t>& buf = GetController()->GetBuffer();
int length = GetController()->GetCmd(6); // TODO: Is this right?
if(length > sizeof(unknown_cc_data)){
LOGERROR("%s Received Unknown CC data that is larger (%d bytes) than allocated size (%d bytes)", __PRETTY_FUNCTION__, length, sizeof(unknown_cc_data));
if (length > (int)sizeof(unknown_cc_data)) {
LOGERROR("%s Received Unknown CC data that is larger (%d bytes) than allocated size (%d bytes)",
__PRETTY_FUNCTION__, length, (int)sizeof(unknown_cc_data));
return false;
}
LOGINFO("%s Unknown CC of size %ul received", __PRETTY_FUNCTION__, length);
memcpy(unknown_cc_data, buf, length);
memcpy(unknown_cc_data, buf.data(), length);
unknown_cc_data_length = length;
return true;
}
bool SCSIPowerView::WriteColorPalette(const DWORD *cdb, const BYTE *buf, const DWORD length)
bool SCSIPowerView::WriteColorPalette()
{
// const uint32_t *cdb, const uint8_t *buf, const uint32_t length
vector<int>& cdb = GetController()->GetCmd();
// vector<uint8_t>& buf = GetController()->GetBuffer();
int length = GetController()->GetCmd(6); // TODO: Is this right?
if (length <= 1) {
LOGDEBUG("%s Received Color Palette with depth of %u", __PRETTY_FUNCTION__, length);
// This is still a valid condition.
return true;
}
if(length > sizeof(color_palette)){
LOGERROR("%s Received Color Palette that is larger (%d bytes) than allocated size (%d bytes)", __PRETTY_FUNCTION__, length, sizeof(color_palette));
if (length > (int)sizeof(color_palette)) {
LOGERROR("%s Received Color Palette that is larger (%d bytes) than allocated size (%d bytes)",
__PRETTY_FUNCTION__, length, (int)sizeof(color_palette));
return false;
}
@ -542,7 +613,8 @@ bool SCSIPowerView::WriteColorPalette(const DWORD *cdb, const BYTE *buf, const D
// color_palette_length = length;
// memcpy(color_palette, default_color_palette_256, sizeof(default_color_palette_256));
LOGINFO("%s Color type: %04x Palette of size %ul received", __PRETTY_FUNCTION__, (uint16_t)cdb[4] + ((uint16_t)cdb[3] << 8), length);
LOGINFO("%s Color type: %04x Palette of size %ul received", __PRETTY_FUNCTION__,
(uint16_t)cdb[4] + ((uint16_t)cdb[3] << 8), length);
#ifdef DUMP_COLOR_PALETTE
FILE* fp;
@ -570,7 +642,7 @@ bool SCSIPowerView::WriteColorPalette(const DWORD *cdb, const BYTE *buf, const D
fputs(newstring, fp);
for(DWORD i = 0; i < length; i+=4){
for (uint32_t i = 0; i < length; i += 4) {
if (i % 16 == 0) {
sprintf(newstring, "%u: ", i);
fputs(newstring, fp);
@ -580,7 +652,6 @@ bool SCSIPowerView::WriteColorPalette(const DWORD *cdb, const BYTE *buf, const D
fputs(newstring, fp);
if (i % 16 == 12) {
fputs("\n", fp);
}
}
@ -590,9 +661,14 @@ bool SCSIPowerView::WriteColorPalette(const DWORD *cdb, const BYTE *buf, const D
return true;
}
bool SCSIPowerView::WriteFrameBuffer(const DWORD *cdb, const BYTE *buf, const DWORD length)
bool SCSIPowerView::WriteFrameBuffer()
{
// const uint32_t *cdb, const uint8_t *buf, const uint32_t length
vector<int>& cdb = GetController()->GetCmd();
vector<uint8_t>& buf = GetController()->GetBuffer();
// int length = GetController()->GetCmd(6); // TODO: Is this right?
char newstring[1024];
// uint32_t new_screen_width_px =0;
// uint32_t new_screen_height_px=0;
@ -602,13 +678,16 @@ bool SCSIPowerView::WriteFrameBuffer(const DWORD *cdb, const BYTE *buf, const DW
uint32_t offset_col_px = 0;
// Set transfer amount
uint32_t update_width_x_bytes = ctrl->cmd[5] + (ctrl->cmd[4] << 8);
uint32_t update_height_y_bytes = ctrl->cmd[7] + (ctrl->cmd[6] << 8);
uint32_t offset = (uint32_t)ctrl->cmd[3] + ((uint32_t)ctrl->cmd[2] << 8) + ((uint32_t)ctrl->cmd[1] << 16);
// uint32_t update_width_x_bytes = ctrl->cmd[5] + (ctrl->cmd[4] << 8);
// uint32_t update_height_y_bytes = ctrl->cmd[7] + (ctrl->cmd[6] << 8);
// uint32_t offset = (uint32_t)ctrl->cmd[3] + ((uint32_t)ctrl->cmd[2] << 8) + ((uint32_t)ctrl->cmd[1] << 16);
LOGWARN("THIS ISN'T RIGHT!!!")
uint32_t update_width_x_bytes = 0; // cmd[5] + (cmd[4] << 8);
uint32_t update_height_y_bytes = 0; // cmd[7] + (cmd[6] << 8);
uint32_t offset = 0; //(uint32_t)cmd[3] + ((uint32_t)cmd[2] << 8) + ((uint32_t)cmd[1] << 16);
bool full_framebuffer_refresh = (offset == 0) && (cdb[9] == 0x00);
switch (color_depth) {
case (eColorsBW):
// One bit per pixel
@ -637,30 +716,33 @@ bool SCSIPowerView::WriteFrameBuffer(const DWORD *cdb, const BYTE *buf, const DW
}
update_height_px = update_height_y_bytes;
if (full_framebuffer_refresh) {
screen_width_px = update_width_px;
screen_height_px = update_height_px;
switch (color_depth) {
case eColorDepth_t::eColorsBW:
sprintf(newstring, " Black & White %04X - %u x %u \r", color_depth, screen_width_px, screen_height_px);
sprintf(newstring, " Black & White %04X - %u x %u \r", color_depth,
screen_width_px, screen_height_px);
break;
case eColorDepth_t::eColors16:
sprintf(newstring, " 16 colors/grays %04X - %u x %u \r", color_depth, screen_width_px,screen_height_px );
sprintf(newstring, " 16 colors/grays %04X - %u x %u \r", color_depth,
screen_width_px, screen_height_px);
break;
case eColorDepth_t::eColors256:
sprintf(newstring, " 256 colors/grays %04X - %u x %u \r", color_depth, screen_width_px, screen_height_px);
sprintf(newstring, " 256 colors/grays %04X - %u x %u \r", color_depth,
screen_width_px, screen_height_px);
break;
default:
sprintf(newstring, " UNKNOWN COLOR DEPTH!! %04X - %u x %u \r", color_depth, screen_width_px, screen_height_px);
sprintf(newstring, " UNKNOWN COLOR DEPTH!! %04X - %u x %u \r", color_depth,
screen_width_px, screen_height_px);
break;
}
fbcon_text(newstring);
}
LOGTRACE("Calculate Offset: %u (%08X) Screen width: %u height: %u Update X: %u (%06X) Y: %u (%06X)", offset, offset, screen_width_px, screen_height_px, offset_row_px, offset_row_px, offset_col_px, offset_col_px);
LOGTRACE("Calculate Offset: %u (%08X) Screen width: %u height: %u Update X: %u (%06X) Y: %u (%06X)", offset, offset,
screen_width_px, screen_height_px, offset_row_px, offset_row_px, offset_col_px, offset_col_px);
if (update_width_px == 0) {
// This is some weird error condition. For now, just return.
@ -669,7 +751,8 @@ bool SCSIPowerView::WriteFrameBuffer(const DWORD *cdb, const BYTE *buf, const DW
}
if (update_height_px + offset_row_px > 800) {
LOGWARN("%s Height: (%d + %d) = %d is larger than the limit", __PRETTY_FUNCTION__, update_height_px, offset_row_px, update_height_px + offset_row_px);
LOGWARN("%s Height: (%d + %d) = %d is larger than the limit", __PRETTY_FUNCTION__, update_height_px,
offset_row_px, update_height_px + offset_row_px);
return true;
}
if (update_width_px + offset_col_px > 800) {
@ -680,37 +763,41 @@ bool SCSIPowerView::WriteFrameBuffer(const DWORD *cdb, const BYTE *buf, const DW
color_depth = eColors256;
// We don't know if we're 256 grays or 256 colors. So, this could be goofy looking
// We're down in an error condition anyway.
LOGINFO("Based upon size of screen update, switching to 256 colors. This may be incorrect if the screen is supposed to be 256 grays");
LOGINFO("Based upon size of screen update, switching to 256 colors. This may be incorrect if the "
"screen is supposed to be 256 grays");
memcpy(color_palette, default_color_palette_256, sizeof(default_color_palette_256));
// Try it again.... (Re-call this function)
return WriteFrameBuffer(cdb, buf, length);
return WriteFrameBuffer();
}
if ((update_width_px == (800 * 2)) || (update_width_px == (640 * 2)) || (update_width_px == (600 * 2))) {
color_depth = eColors16;
LOGINFO("Based upon size of screen update, switching to 16 colors. This may be incorrect if the screen is supposed to be 16 grays");
LOGINFO("Based upon size of screen update, switching to 16 colors. This may be incorrect if the screen "
"is supposed to be 16 grays");
memcpy(color_palette, default_color_palette_16, sizeof(default_color_palette_16));
// Try it again.... (Re-call this function)
return WriteFrameBuffer(cdb, buf, length);
return WriteFrameBuffer();
}
}
LOGWARN("%s width: (%d + %d) = %d is larger than the limit", __PRETTY_FUNCTION__, update_width_px, offset_col_px, update_width_px + offset_col_px);
LOGWARN("%s width: (%d + %d) = %d is larger than the limit", __PRETTY_FUNCTION__, update_width_px,
offset_col_px, update_width_px + offset_col_px);
return true;
}
LOGDEBUG("Update Position: %d:%d Offset: %d Screen Width: %d Width px: %d:%d (bytes: %d, %d)", offset_col_px, offset_row_px, offset, screen_width_px, update_width_px, update_height_px, update_width_x_bytes, update_height_y_bytes);
LOGDEBUG("Update Position: %d:%d Offset: %d Screen Width: %d Width px: %d:%d (bytes: %d, %d)", offset_col_px,
offset_row_px, offset, screen_width_px, update_width_px, update_height_px, update_width_x_bytes,
update_height_y_bytes);
DWORD random_print = rand() % (update_height_px * update_width_px);
uint32_t random_print = rand() % (update_height_px * update_width_px);
// For each row
for (DWORD idx_row_y = 0; idx_row_y < (update_height_px); idx_row_y++){
for (uint32_t idx_row_y = 0; idx_row_y < (update_height_px); idx_row_y++) {
// For each column
for (DWORD idx_col_x = 0; idx_col_x < (update_width_px); idx_col_x++){
BYTE pixel_color_idx=0;
DWORD pixel_buffer_idx = 0;
BYTE pixel_buffer_byte = 0;
DWORD pixel_bit_number = 0;
for (uint32_t idx_col_x = 0; idx_col_x < (update_width_px); idx_col_x++) {
uint32_t pixel_color_idx = 0;
uint32_t pixel_buffer_idx = 0;
uint8_t pixel_buffer_byte = 0;
uint32_t pixel_bit_number = 0;
uint32_t loc = 0;
switch (color_depth) {
@ -725,8 +812,7 @@ bool SCSIPowerView::WriteFrameBuffer(const DWORD *cdb, const BYTE *buf, const DW
pixel_buffer_idx = (idx_row_y * update_width_x_bytes) + (idx_col_x / 2);
if (idx_col_x % 2) {
pixel_color_idx = buf[pixel_buffer_idx] & 0x0F;
}
else{
} else {
pixel_color_idx = buf[pixel_buffer_idx] >> 4;
}
break;
@ -756,17 +842,16 @@ bool SCSIPowerView::WriteFrameBuffer(const DWORD *cdb, const BYTE *buf, const DW
green >>= (8 - fbinfo.green.length);
red >>= (8 - fbinfo.blue.length);
uint32_t fb_pixel = (red << fbinfo.red.offset) |
(green << fbinfo.green.offset)|
(blue << fbinfo.blue.offset);
uint32_t fb_pixel =
(red << fbinfo.red.offset) | (green << fbinfo.green.offset) | (blue << fbinfo.blue.offset);
if (random_print == (idx_col_x * idx_row_y)) {
LOGDEBUG("idx:%d (%02X) [%02X %02X %02X %02X] fb_pixel:%08X ", pixel_color_idx, pixel_color_idx, data_idx, red, green, blue, fb_pixel);
LOGDEBUG("idx:%d (%02X) [%02X %02X %02X %02X] fb_pixel:%08X ", pixel_color_idx, pixel_color_idx,
data_idx, red, green, blue, fb_pixel);
}
*(this->fb + loc + 1) = (BYTE)((fb_pixel >> 8) & 0xFF);
*(this->fb + loc + 0) = (BYTE)((fb_pixel) & 0xFF);
*(this->fb + loc + 1) = (uint8_t)((fb_pixel >> 8) & 0xFF);
*(this->fb + loc + 0) = (uint8_t)((fb_pixel)&0xFF);
}
}
@ -778,13 +863,16 @@ bool SCSIPowerView::WriteFrameBuffer(const DWORD *cdb, const BYTE *buf, const DW
switch (color_depth) {
case (eColorsBW):
sprintf(newstring, "/tmp/fb_eColorsBW_%04X_%ux%u.txt",dumpfb_idx++, update_width_x_bytes, update_height_y_bytes);
sprintf(newstring, "/tmp/fb_eColorsBW_%04X_%ux%u.txt", dumpfb_idx++, update_width_x_bytes,
update_height_y_bytes);
break;
case (eColors16):
sprintf(newstring, "/tmp/fb_eColors16_%04X_%ux%u.txt",dumpfb_idx++, update_width_x_bytes, update_height_y_bytes);
sprintf(newstring, "/tmp/fb_eColors16_%04X_%ux%u.txt", dumpfb_idx++, update_width_x_bytes,
update_height_y_bytes);
break;
case (eColors256):
sprintf(newstring, "/tmp/fb_eColors256_%04X_%ux%u.txt",dumpfb_idx++, update_width_x_bytes, update_height_y_bytes);
sprintf(newstring, "/tmp/fb_eColors256_%04X_%ux%u.txt", dumpfb_idx++, update_width_x_bytes,
update_height_y_bytes);
break;
default:
return false;
@ -797,7 +885,7 @@ bool SCSIPowerView::WriteFrameBuffer(const DWORD *cdb, const BYTE *buf, const DW
fputs(newstring, fp);
for(DWORD i = 0; i < length; i+=4){
for (uint32_t i = 0; i < length; i += 4) {
if (i % 16 == 0) {
sprintf(newstring, "%u: ", i);
fputs(newstring, fp);
@ -807,15 +895,41 @@ bool SCSIPowerView::WriteFrameBuffer(const DWORD *cdb, const BYTE *buf, const DW
fputs(newstring, fp);
if (i % 16 == 12) {
fputs("\n", fp);
}
}
fclose(fp);
#endif
//******************************************************************************
return true;
}
bool SCSIPowerView::WriteBytes(const vector<int>& cdb, vector<uint8_t>& buf, uint32_t)
{
(void)cdb;
(void)buf;
// const int data_format = cdb[5];
// int data_length = GetInt16(cdb, 3);
// if (data_format == 0x00) {
// m_tap.Send(buf.data(), data_length);
// GetLogger().Trace("Transmitted " + to_string(data_length) + " byte(s) (00 format)");
// }
// else if (data_format == 0x80) {
// // The data length is specified in the first 2 bytes of the payload
// data_length = buf[1] + ((static_cast<int>(buf[0]) & 0xff) << 8);
// m_tap.Send(&(buf.data()[4]), data_length);
// GetLogger().Trace("Transmitted " + to_string(data_length) + "byte(s) (80 format)");
// }
// else {
// stringstream s;
// s << "Unknown data format: " << setfill('0') << setw(2) << hex << data_format;
// GetLogger().Warn(s.str());
// }
GetController()->SetBlocks(0);
return true;
}

View File

@ -1,9 +1,8 @@
//---------------------------------------------------------------------------
//
// SCSI Target Emulator RaSCSI (*^..^*)
// for Raspberry Pi
// SCSI Target Emulator PiSCSI for Raspberry Pi
//
// Copyright (C) 2020-2021 akuker
// Copyright (C) 2020-2023 akuker
// Copyright (C) 2020 joshua stein <jcs@jcs.org>
//
// Licensed under the BSD 3-Clause License.
@ -19,11 +18,11 @@
//---------------------------------------------------------------------------
#pragma once
#include "os.h"
#include "disk.h"
#include "interfaces/byte_writer.h"
#include "primary_device.h"
#include <map>
#include <string>
#include "../rascsi.h"
#include <linux/fb.h>
//===========================================================================
@ -31,24 +30,24 @@
// Radius PowerView
//
//===========================================================================
class SCSIPowerView: public Disk
class SCSIPowerView : public PrimaryDevice, public ByteWriter
{
private:
typedef struct _command_t {
const char* name;
void (SCSIPowerView::*execute)(SASIDEV *);
// typedef struct _command_t {
// const char* name;
// void (SCSIPowerView::*execute)(SASIDEV *);
_command_t(const char* _name, void (SCSIPowerView::*_execute)(SASIDEV *)) : name(_name), execute(_execute) { };
} command_t;
std::map<SCSIDEV::scsi_command, command_t*> commands;
// _command_t(const char* _name, void (SCSIPowerView::*_execute)(SASIDEV *)) : name(_name), execute(_execute) { };
// } command_t;
// std::map<SCSIDEV::scsi_command, command_t*> commands;
SASIDEV::ctrl_t *ctrl;
// SASIDEV::ctrl_t *ctrl;
enum eColorDepth_t : uint16_t {eColorsNone=0x0000, eColorsBW=0x0001, eColors16=0x0010, eColors256=0x0100};
void AddCommand(SCSIDEV::scsi_command, const char*, void (SCSIPowerView::*)(SASIDEV *));
// void AddCommand(SCSIDEV::scsi_command, const char*, void (SCSIPowerView::*)(SASIDEV *));
// Largest framebuffer supported by the Radius PowerView is 800x600 at 256 colors (1 bytes per pixel)
// Double it for now, because memory is cheap....
@ -57,32 +56,47 @@ private:
void fbcon_cursor(bool blank);
void fbcon_blank(bool blank);
void fbcon_text(char* message);
void fbcon_text(const char* message);
public:
SCSIPowerView();
~SCSIPowerView();
bool Init(const map<string, string>&) override;
explicit SCSIPowerView(int);
~SCSIPowerView() override;
bool Init(const unordered_map<string, string>&) override;
bool HwInit();
// Commands
vector<uint8_t> InquiryInternal() const override;
// int Read(const vector<int>&, vector<uint8_t>&, uint64_t);
bool WriteBytes(const vector<int>&, vector<uint8_t>&, uint32_t) override;
// int RetrieveStats(const vector<int>&, vector<uint8_t>&) const;
// void TestUnitReady() override;
// void Read6();
// void Write6() const;
// // Commands
int Inquiry(const DWORD *cdb, BYTE *buffer) override;
bool WriteFrameBuffer(const DWORD *cdb, const BYTE *buf, const DWORD length);
bool WriteColorPalette(const DWORD *cdb, const BYTE *buf, const DWORD length);
bool WriteConfiguration(const DWORD *cdb, const BYTE *buf, const DWORD length);
bool WriteUnknownCC(const DWORD *cdb, const BYTE *buf, const DWORD length);
// old..... int Inquiry(const uint32_t *cdb, uint8_t *buffer) override;
bool WriteFrameBuffer();
bool WriteColorPalette();
bool WriteConfiguration();
bool WriteUnknownCC();
void CmdReadConfig(SASIDEV *controller);
void CmdWriteConfig(SASIDEV *controller);
void CmdWriteFramebuffer(SASIDEV *controller);
void CmdWriteColorPalette(SASIDEV *controller);
void UnknownCommandCC(SASIDEV *controller);
bool Dispatch(SCSIDEV *) override;
void CmdReadConfig();
void CmdWriteConfig();
void CmdWriteFramebuffer();
void CmdWriteColorPalette();
void UnknownCommandCC();
private:
void ClearFrameBuffer(DWORD blank_color);
void ClearFrameBuffer(uint32_t blank_color);
// Default to the lowest resolution supported by the PowerView (640x400)
uint32_t screen_width_px = 640;
@ -93,15 +107,15 @@ private:
struct fb_fix_screeninfo fbfixinfo;
// The maximum color depth is 16 bits
BYTE color_palette[0x10000];
int color_palette_length = 0;
uint8_t color_palette[0x10000];
// int color_palette_length = 0;
BYTE unknown_cc_data[0x10000];
uint8_t unknown_cc_data[0x10000];
int unknown_cc_data_length = 0;
static const BYTE default_color_palette_bw[8];
static const BYTE default_color_palette_16[64];
static const BYTE default_color_palette_256[1024];
static const uint8_t default_color_palette_bw[8];
static const uint8_t default_color_palette_16[64];
static const uint8_t default_color_palette_256[1024];
int fbfd;
char *fb;
@ -109,12 +123,12 @@ private:
int fbbpp;
// Hard-coded inquiry response to match the real PowerView
static const BYTE m_inquiry_response[];
static const uint8_t m_inquiry_response[];
static unsigned char reverse_table[256];
DWORD framebuffer_black;
DWORD framebuffer_blue;
DWORD framebuffer_yellow;
DWORD framebuffer_red;
uint32_t framebuffer_black;
uint32_t framebuffer_blue;
uint32_t framebuffer_yellow;
uint32_t framebuffer_red;
};

View File

@ -1,9 +1,8 @@
//---------------------------------------------------------------------------
//
// SCSI Target Emulator RaSCSI (*^..^*)
// for Raspberry Pi
// SCSI Target Emulator PiSCSI for Raspberry Pi
//
// Copyright (C) 2021 akuker
// Copyright (C) 2021-2023 akuker
//
// Licensed under the BSD 3-Clause License.
// See LICENSE file in the project root folder.
@ -13,83 +12,71 @@
//---------------------------------------------------------------------------
#include "scsi_powerview.h"
#include <cstdint>
const BYTE SCSIPowerView::default_color_palette_bw[8] = {
0x00, 0x00, 0x00, 0x00,
0xFF, 0xFF, 0xFF, 0xFF
};
const uint8_t SCSIPowerView::default_color_palette_bw[8] = {0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF};
const BYTE SCSIPowerView::default_color_palette_16[64] = {
const uint8_t SCSIPowerView::default_color_palette_16[64] = {
0x00, 0xFF, 0xFF, 0xFF, 0x01, 0xFC, 0xF3, 0x05, 0x02, 0xFF, 0x64, 0x02, 0x03, 0xDD, 0x08, 0x06,
0x04, 0xF2, 0x08, 0x84, 0x05, 0x46, 0x00, 0xA5, 0x06, 0x00, 0x00, 0xD4, 0x07, 0x02, 0xAB, 0xEA,
0x08, 0x1F, 0xB7, 0x14, 0x09, 0x00, 0x64, 0x11, 0x0A, 0x56, 0x2C, 0x05, 0x0B, 0x90, 0x71, 0x3A,
0x0C, 0xC0, 0xC0, 0xC0, 0x0D, 0x80, 0x80, 0x80, 0x0E, 0x20, 0x20, 0x20, 0x0F, 0x00, 0x00, 0x00,
};
const BYTE SCSIPowerView::default_color_palette_256[1024] = {
const uint8_t SCSIPowerView::default_color_palette_256[1024] = {
0x00, 0xFF, 0xFF, 0xFF, 0x01, 0xFF, 0xFF, 0xCC, 0x02, 0xFF, 0xFF, 0x99, 0x03, 0xFF, 0xFF, 0x66,
0x04, 0xFF, 0xFF, 0x33, 0x05, 0xFF, 0xFF, 0x00, 0x06, 0xFF, 0xCC, 0xFF, 0x07, 0xFF, 0xCC, 0xCC,
0x08, 0xFF, 0xCC, 0x99, 0x09, 0xFF, 0xCC, 0x66, 0x0A, 0xFF, 0xCC, 0x33, 0x0B, 0xFF, 0xCC, 0x00,
0x0C, 0xFF, 0x99, 0xFF, 0x0D, 0xFF, 0x99, 0xCC, 0x0E, 0xFF, 0x99, 0x99, 0x0F, 0xFF, 0x99, 0x66,
0x10, 0xFF, 0x99, 0x33, 0x11, 0xFF, 0x99, 0x00, 0x12, 0xFF, 0x66, 0xFF, 0x13, 0xFF, 0x66, 0xCC,
0x14, 0xFF, 0x66, 0x99, 0x15, 0xFF, 0x66, 0x66, 0x16, 0xFF, 0x66, 0x33, 0x17, 0xFF, 0x66, 0x00,
0x18, 0xFF, 0x33, 0xFF, 0x19, 0xFF, 0x33, 0xCC, 0x1A, 0xFF, 0x33, 0x99, 0x1B, 0xFF, 0x33, 0x66,
0x1C, 0xFF, 0x33, 0x33, 0x1D, 0xFF, 0x33, 0x00, 0x1E, 0xFF, 0x00, 0xFF, 0x1F, 0xFF, 0x00, 0xCC,
0x20, 0xFF, 0x00, 0x99, 0x21, 0xFF, 0x00, 0x66, 0x22, 0xFF, 0x00, 0x33, 0x23, 0xFF, 0x00, 0x00,
0x24, 0xCC, 0xFF, 0xFF, 0x25, 0xCC, 0xFF, 0xCC, 0x26, 0xCC, 0xFF, 0x99, 0x27, 0xCC, 0xFF, 0x66,
0x28, 0xCC, 0xFF, 0x33, 0x29, 0xCC, 0xFF, 0x00, 0x2A, 0xCC, 0xCC, 0xFF, 0x2B, 0xCC, 0xCC, 0xCC,
0x2C, 0xCC, 0xCC, 0x99, 0x2D, 0xCC, 0xCC, 0x66, 0x2E, 0xCC, 0xCC, 0x33, 0x2F, 0xCC, 0xCC, 0x00,
0x30, 0xCC, 0x99, 0xFF, 0x31, 0xCC, 0x99, 0xCC, 0x32, 0xCC, 0x99, 0x99, 0x33, 0xCC, 0x99, 0x66,
0x34, 0xCC, 0x99, 0x33, 0x35, 0xCC, 0x99, 0x00, 0x36, 0xCC, 0x66, 0xFF, 0x37, 0xCC, 0x66, 0xCC,
0x38, 0xCC, 0x66, 0x99, 0x39, 0xCC, 0x66, 0x66, 0x3A, 0xCC, 0x66, 0x33, 0x3B, 0xCC, 0x66, 0x00,
0x3C, 0xCC, 0x33, 0xFF, 0x3D, 0xCC, 0x33, 0xCC, 0x3E, 0xCC, 0x33, 0x99, 0x3F, 0xCC, 0x33, 0x66,
0x40, 0xCC, 0x33, 0x33, 0x41, 0xCC, 0x33, 0x00, 0x42, 0xCC, 0x00, 0xFF, 0x43, 0xCC, 0x00, 0xCC,
0x44, 0xCC, 0x00, 0x99, 0x45, 0xCC, 0x00, 0x66, 0x46, 0xCC, 0x00, 0x33, 0x47, 0xCC, 0x00, 0x00,
0x48, 0x99, 0xFF, 0xFF, 0x49, 0x99, 0xFF, 0xCC, 0x4A, 0x99, 0xFF, 0x99, 0x4B, 0x99, 0xFF, 0x66,
0x4C, 0x99, 0xFF, 0x33, 0x4D, 0x99, 0xFF, 0x00, 0x4E, 0x99, 0xCC, 0xFF, 0x4F, 0x99, 0xCC, 0xCC,
0x50, 0x99, 0xCC, 0x99, 0x51, 0x99, 0xCC, 0x66, 0x52, 0x99, 0xCC, 0x33, 0x53, 0x99, 0xCC, 0x00,
0x54, 0x99, 0x99, 0xFF, 0x55, 0x99, 0x99, 0xCC, 0x56, 0x99, 0x99, 0x99, 0x57, 0x99, 0x99, 0x66,
0x58, 0x99, 0x99, 0x33, 0x59, 0x99, 0x99, 0x00, 0x5A, 0x99, 0x66, 0xFF, 0x5B, 0x99, 0x66, 0xCC,
0x5C, 0x99, 0x66, 0x99, 0x5D, 0x99, 0x66, 0x66, 0x5E, 0x99, 0x66, 0x33, 0x5F, 0x99, 0x66, 0x00,
0x60, 0x99, 0x33, 0xFF, 0x61, 0x99, 0x33, 0xCC, 0x62, 0x99, 0x33, 0x99, 0x63, 0x99, 0x33, 0x66,
0x64, 0x99, 0x33, 0x33, 0x65, 0x99, 0x33, 0x00, 0x66, 0x99, 0x00, 0xFF, 0x67, 0x99, 0x00, 0xCC,
0x68, 0x99, 0x00, 0x99, 0x69, 0x99, 0x00, 0x66, 0x6A, 0x99, 0x00, 0x33, 0x6B, 0x99, 0x00, 0x00,
0x6C, 0x66, 0xFF, 0xFF, 0x6D, 0x66, 0xFF, 0xCC, 0x6E, 0x66, 0xFF, 0x99, 0x6F, 0x66, 0xFF, 0x66,
0x70, 0x66, 0xFF, 0x33, 0x71, 0x66, 0xFF, 0x00, 0x72, 0x66, 0xCC, 0xFF, 0x73, 0x66, 0xCC, 0xCC,
0x74, 0x66, 0xCC, 0x99, 0x75, 0x66, 0xCC, 0x66, 0x76, 0x66, 0xCC, 0x33, 0x77, 0x66, 0xCC, 0x00,
0x78, 0x66, 0x99, 0xFF, 0x79, 0x66, 0x99, 0xCC, 0x7A, 0x66, 0x99, 0x99, 0x7B, 0x66, 0x99, 0x66,
0x7C, 0x66, 0x99, 0x33, 0x7D, 0x66, 0x99, 0x00, 0x7E, 0x66, 0x66, 0xFF, 0x7F, 0x66, 0x66, 0xCC,
0x80, 0x66, 0x66, 0x99, 0x81, 0x66, 0x66, 0x66, 0x82, 0x66, 0x66, 0x33, 0x83, 0x66, 0x66, 0x00,
0x84, 0x66, 0x33, 0xFF, 0x85, 0x66, 0x33, 0xCC, 0x86, 0x66, 0x33, 0x99, 0x87, 0x66, 0x33, 0x66,
0x88, 0x66, 0x33, 0x33, 0x89, 0x66, 0x33, 0x00, 0x8A, 0x66, 0x00, 0xFF, 0x8B, 0x66, 0x00, 0xCC,
0x8C, 0x66, 0x00, 0x99, 0x8D, 0x66, 0x00, 0x66, 0x8E, 0x66, 0x00, 0x33, 0x8F, 0x66, 0x00, 0x00,
0x90, 0x33, 0xFF, 0xFF, 0x91, 0x33, 0xFF, 0xCC, 0x92, 0x33, 0xFF, 0x99, 0x93, 0x33, 0xFF, 0x66,
0x94, 0x33, 0xFF, 0x33, 0x95, 0x33, 0xFF, 0x00, 0x96, 0x33, 0xCC, 0xFF, 0x97, 0x33, 0xCC, 0xCC,
0x98, 0x33, 0xCC, 0x99, 0x99, 0x33, 0xCC, 0x66, 0x9A, 0x33, 0xCC, 0x33, 0x9B, 0x33, 0xCC, 0x00,
0x9C, 0x33, 0x99, 0xFF, 0x9D, 0x33, 0x99, 0xCC, 0x9E, 0x33, 0x99, 0x99, 0x9F, 0x33, 0x99, 0x66,
0xA0, 0x33, 0x99, 0x33, 0xA1, 0x33, 0x99, 0x00, 0xA2, 0x33, 0x66, 0xFF, 0xA3, 0x33, 0x66, 0xCC,
0xA4, 0x33, 0x66, 0x99, 0xA5, 0x33, 0x66, 0x66, 0xA6, 0x33, 0x66, 0x33, 0xA7, 0x33, 0x66, 0x00,
0xA8, 0x33, 0x33, 0xFF, 0xA9, 0x33, 0x33, 0xCC, 0xAA, 0x33, 0x33, 0x99, 0xAB, 0x33, 0x33, 0x66,
0xAC, 0x33, 0x33, 0x33, 0xAD, 0x33, 0x33, 0x00, 0xAE, 0x33, 0x00, 0xFF, 0xAF, 0x33, 0x00, 0xCC,
0xB0, 0x33, 0x00, 0x99, 0xB1, 0x33, 0x00, 0x66, 0xB2, 0x33, 0x00, 0x33, 0xB3, 0x33, 0x00, 0x00,
0xB4, 0x00, 0xFF, 0xFF, 0xB5, 0x00, 0xFF, 0xCC, 0xB6, 0x00, 0xFF, 0x99, 0xB7, 0x00, 0xFF, 0x66,
0xB8, 0x00, 0xFF, 0x33, 0xB9, 0x00, 0xFF, 0x00, 0xBA, 0x00, 0xCC, 0xFF, 0xBB, 0x00, 0xCC, 0xCC,
0xBC, 0x00, 0xCC, 0x99, 0xBD, 0x00, 0xCC, 0x66, 0xBE, 0x00, 0xCC, 0x33, 0xBF, 0x00, 0xCC, 0x00,
0xC0, 0x00, 0x99, 0xFF, 0xC1, 0x00, 0x99, 0xCC, 0xC2, 0x00, 0x99, 0x99, 0xC3, 0x00, 0x99, 0x66,
0xC4, 0x00, 0x99, 0x33, 0xC5, 0x00, 0x99, 0x00, 0xC6, 0x00, 0x66, 0xFF, 0xC7, 0x00, 0x66, 0xCC,
0xC8, 0x00, 0x66, 0x99, 0xC9, 0x00, 0x66, 0x66, 0xCA, 0x00, 0x66, 0x33, 0xCB, 0x00, 0x66, 0x00,
0xCC, 0x00, 0x33, 0xFF, 0xCD, 0x00, 0x33, 0xCC, 0xCE, 0x00, 0x33, 0x99, 0xCF, 0x00, 0x33, 0x66,
0xD0, 0x00, 0x33, 0x33, 0xD1, 0x00, 0x33, 0x00, 0xD2, 0x00, 0x00, 0xFF, 0xD3, 0x00, 0x00, 0xCC,
0xD4, 0x00, 0x00, 0x99, 0xD5, 0x00, 0x00, 0x66, 0xD6, 0x00, 0x00, 0x33, 0xD7, 0xEE, 0x00, 0x00,
0xD8, 0xDD, 0x00, 0x00, 0xD9, 0xBB, 0x00, 0x00, 0xDA, 0xAA, 0x00, 0x00, 0xDB, 0x88, 0x00, 0x00,
0xDC, 0x77, 0x00, 0x00, 0xDD, 0x55, 0x00, 0x00, 0xDE, 0x44, 0x00, 0x00, 0xDF, 0x22, 0x00, 0x00,
0xE0, 0x11, 0x00, 0x00, 0xE1, 0x00, 0xEE, 0x00, 0xE2, 0x00, 0xDD, 0x00, 0xE3, 0x00, 0xBB, 0x00,
0xE4, 0x00, 0xAA, 0x00, 0xE5, 0x00, 0x88, 0x00, 0xE6, 0x00, 0x77, 0x00, 0xE7, 0x00, 0x55, 0x00,
0xE8, 0x00, 0x44, 0x00, 0xE9, 0x00, 0x22, 0x00, 0xEA, 0x00, 0x11, 0x00, 0xEB, 0x00, 0x00, 0xEE,
0xEC, 0x00, 0x00, 0xDD, 0xED, 0x00, 0x00, 0xBB, 0xEE, 0x00, 0x00, 0xAA, 0xEF, 0x00, 0x00, 0x88,
0xF0, 0x00, 0x00, 0x77, 0xF1, 0x00, 0x00, 0x55, 0xF2, 0x00, 0x00, 0x44, 0xF3, 0x00, 0x00, 0x22,
0xF4, 0x00, 0x00, 0x11, 0xF5, 0xEE, 0xEE, 0xEE, 0xF6, 0xDD, 0xDD, 0xDD, 0xF7, 0xBB, 0xBB, 0xBB,
0xF8, 0xAA, 0xAA, 0xAA, 0xF9, 0x88, 0x88, 0x88, 0xFA, 0x77, 0x77, 0x77, 0xFB, 0x55, 0x55, 0x55,
0xFC, 0x44, 0x44, 0x44, 0xFD, 0x22, 0x22, 0x22, 0xFE, 0x11, 0x11, 0x11, 0xFF, 0x00, 0x00, 0x00,
0x00, 0xFF, 0xFF, 0xFF, 0x01, 0xFF, 0xFF, 0xCC, 0x02, 0xFF, 0xFF, 0x99, 0x03, 0xFF, 0xFF, 0x66, 0x04, 0xFF, 0xFF,
0x33, 0x05, 0xFF, 0xFF, 0x00, 0x06, 0xFF, 0xCC, 0xFF, 0x07, 0xFF, 0xCC, 0xCC, 0x08, 0xFF, 0xCC, 0x99, 0x09, 0xFF,
0xCC, 0x66, 0x0A, 0xFF, 0xCC, 0x33, 0x0B, 0xFF, 0xCC, 0x00, 0x0C, 0xFF, 0x99, 0xFF, 0x0D, 0xFF, 0x99, 0xCC, 0x0E,
0xFF, 0x99, 0x99, 0x0F, 0xFF, 0x99, 0x66, 0x10, 0xFF, 0x99, 0x33, 0x11, 0xFF, 0x99, 0x00, 0x12, 0xFF, 0x66, 0xFF,
0x13, 0xFF, 0x66, 0xCC, 0x14, 0xFF, 0x66, 0x99, 0x15, 0xFF, 0x66, 0x66, 0x16, 0xFF, 0x66, 0x33, 0x17, 0xFF, 0x66,
0x00, 0x18, 0xFF, 0x33, 0xFF, 0x19, 0xFF, 0x33, 0xCC, 0x1A, 0xFF, 0x33, 0x99, 0x1B, 0xFF, 0x33, 0x66, 0x1C, 0xFF,
0x33, 0x33, 0x1D, 0xFF, 0x33, 0x00, 0x1E, 0xFF, 0x00, 0xFF, 0x1F, 0xFF, 0x00, 0xCC, 0x20, 0xFF, 0x00, 0x99, 0x21,
0xFF, 0x00, 0x66, 0x22, 0xFF, 0x00, 0x33, 0x23, 0xFF, 0x00, 0x00, 0x24, 0xCC, 0xFF, 0xFF, 0x25, 0xCC, 0xFF, 0xCC,
0x26, 0xCC, 0xFF, 0x99, 0x27, 0xCC, 0xFF, 0x66, 0x28, 0xCC, 0xFF, 0x33, 0x29, 0xCC, 0xFF, 0x00, 0x2A, 0xCC, 0xCC,
0xFF, 0x2B, 0xCC, 0xCC, 0xCC, 0x2C, 0xCC, 0xCC, 0x99, 0x2D, 0xCC, 0xCC, 0x66, 0x2E, 0xCC, 0xCC, 0x33, 0x2F, 0xCC,
0xCC, 0x00, 0x30, 0xCC, 0x99, 0xFF, 0x31, 0xCC, 0x99, 0xCC, 0x32, 0xCC, 0x99, 0x99, 0x33, 0xCC, 0x99, 0x66, 0x34,
0xCC, 0x99, 0x33, 0x35, 0xCC, 0x99, 0x00, 0x36, 0xCC, 0x66, 0xFF, 0x37, 0xCC, 0x66, 0xCC, 0x38, 0xCC, 0x66, 0x99,
0x39, 0xCC, 0x66, 0x66, 0x3A, 0xCC, 0x66, 0x33, 0x3B, 0xCC, 0x66, 0x00, 0x3C, 0xCC, 0x33, 0xFF, 0x3D, 0xCC, 0x33,
0xCC, 0x3E, 0xCC, 0x33, 0x99, 0x3F, 0xCC, 0x33, 0x66, 0x40, 0xCC, 0x33, 0x33, 0x41, 0xCC, 0x33, 0x00, 0x42, 0xCC,
0x00, 0xFF, 0x43, 0xCC, 0x00, 0xCC, 0x44, 0xCC, 0x00, 0x99, 0x45, 0xCC, 0x00, 0x66, 0x46, 0xCC, 0x00, 0x33, 0x47,
0xCC, 0x00, 0x00, 0x48, 0x99, 0xFF, 0xFF, 0x49, 0x99, 0xFF, 0xCC, 0x4A, 0x99, 0xFF, 0x99, 0x4B, 0x99, 0xFF, 0x66,
0x4C, 0x99, 0xFF, 0x33, 0x4D, 0x99, 0xFF, 0x00, 0x4E, 0x99, 0xCC, 0xFF, 0x4F, 0x99, 0xCC, 0xCC, 0x50, 0x99, 0xCC,
0x99, 0x51, 0x99, 0xCC, 0x66, 0x52, 0x99, 0xCC, 0x33, 0x53, 0x99, 0xCC, 0x00, 0x54, 0x99, 0x99, 0xFF, 0x55, 0x99,
0x99, 0xCC, 0x56, 0x99, 0x99, 0x99, 0x57, 0x99, 0x99, 0x66, 0x58, 0x99, 0x99, 0x33, 0x59, 0x99, 0x99, 0x00, 0x5A,
0x99, 0x66, 0xFF, 0x5B, 0x99, 0x66, 0xCC, 0x5C, 0x99, 0x66, 0x99, 0x5D, 0x99, 0x66, 0x66, 0x5E, 0x99, 0x66, 0x33,
0x5F, 0x99, 0x66, 0x00, 0x60, 0x99, 0x33, 0xFF, 0x61, 0x99, 0x33, 0xCC, 0x62, 0x99, 0x33, 0x99, 0x63, 0x99, 0x33,
0x66, 0x64, 0x99, 0x33, 0x33, 0x65, 0x99, 0x33, 0x00, 0x66, 0x99, 0x00, 0xFF, 0x67, 0x99, 0x00, 0xCC, 0x68, 0x99,
0x00, 0x99, 0x69, 0x99, 0x00, 0x66, 0x6A, 0x99, 0x00, 0x33, 0x6B, 0x99, 0x00, 0x00, 0x6C, 0x66, 0xFF, 0xFF, 0x6D,
0x66, 0xFF, 0xCC, 0x6E, 0x66, 0xFF, 0x99, 0x6F, 0x66, 0xFF, 0x66, 0x70, 0x66, 0xFF, 0x33, 0x71, 0x66, 0xFF, 0x00,
0x72, 0x66, 0xCC, 0xFF, 0x73, 0x66, 0xCC, 0xCC, 0x74, 0x66, 0xCC, 0x99, 0x75, 0x66, 0xCC, 0x66, 0x76, 0x66, 0xCC,
0x33, 0x77, 0x66, 0xCC, 0x00, 0x78, 0x66, 0x99, 0xFF, 0x79, 0x66, 0x99, 0xCC, 0x7A, 0x66, 0x99, 0x99, 0x7B, 0x66,
0x99, 0x66, 0x7C, 0x66, 0x99, 0x33, 0x7D, 0x66, 0x99, 0x00, 0x7E, 0x66, 0x66, 0xFF, 0x7F, 0x66, 0x66, 0xCC, 0x80,
0x66, 0x66, 0x99, 0x81, 0x66, 0x66, 0x66, 0x82, 0x66, 0x66, 0x33, 0x83, 0x66, 0x66, 0x00, 0x84, 0x66, 0x33, 0xFF,
0x85, 0x66, 0x33, 0xCC, 0x86, 0x66, 0x33, 0x99, 0x87, 0x66, 0x33, 0x66, 0x88, 0x66, 0x33, 0x33, 0x89, 0x66, 0x33,
0x00, 0x8A, 0x66, 0x00, 0xFF, 0x8B, 0x66, 0x00, 0xCC, 0x8C, 0x66, 0x00, 0x99, 0x8D, 0x66, 0x00, 0x66, 0x8E, 0x66,
0x00, 0x33, 0x8F, 0x66, 0x00, 0x00, 0x90, 0x33, 0xFF, 0xFF, 0x91, 0x33, 0xFF, 0xCC, 0x92, 0x33, 0xFF, 0x99, 0x93,
0x33, 0xFF, 0x66, 0x94, 0x33, 0xFF, 0x33, 0x95, 0x33, 0xFF, 0x00, 0x96, 0x33, 0xCC, 0xFF, 0x97, 0x33, 0xCC, 0xCC,
0x98, 0x33, 0xCC, 0x99, 0x99, 0x33, 0xCC, 0x66, 0x9A, 0x33, 0xCC, 0x33, 0x9B, 0x33, 0xCC, 0x00, 0x9C, 0x33, 0x99,
0xFF, 0x9D, 0x33, 0x99, 0xCC, 0x9E, 0x33, 0x99, 0x99, 0x9F, 0x33, 0x99, 0x66, 0xA0, 0x33, 0x99, 0x33, 0xA1, 0x33,
0x99, 0x00, 0xA2, 0x33, 0x66, 0xFF, 0xA3, 0x33, 0x66, 0xCC, 0xA4, 0x33, 0x66, 0x99, 0xA5, 0x33, 0x66, 0x66, 0xA6,
0x33, 0x66, 0x33, 0xA7, 0x33, 0x66, 0x00, 0xA8, 0x33, 0x33, 0xFF, 0xA9, 0x33, 0x33, 0xCC, 0xAA, 0x33, 0x33, 0x99,
0xAB, 0x33, 0x33, 0x66, 0xAC, 0x33, 0x33, 0x33, 0xAD, 0x33, 0x33, 0x00, 0xAE, 0x33, 0x00, 0xFF, 0xAF, 0x33, 0x00,
0xCC, 0xB0, 0x33, 0x00, 0x99, 0xB1, 0x33, 0x00, 0x66, 0xB2, 0x33, 0x00, 0x33, 0xB3, 0x33, 0x00, 0x00, 0xB4, 0x00,
0xFF, 0xFF, 0xB5, 0x00, 0xFF, 0xCC, 0xB6, 0x00, 0xFF, 0x99, 0xB7, 0x00, 0xFF, 0x66, 0xB8, 0x00, 0xFF, 0x33, 0xB9,
0x00, 0xFF, 0x00, 0xBA, 0x00, 0xCC, 0xFF, 0xBB, 0x00, 0xCC, 0xCC, 0xBC, 0x00, 0xCC, 0x99, 0xBD, 0x00, 0xCC, 0x66,
0xBE, 0x00, 0xCC, 0x33, 0xBF, 0x00, 0xCC, 0x00, 0xC0, 0x00, 0x99, 0xFF, 0xC1, 0x00, 0x99, 0xCC, 0xC2, 0x00, 0x99,
0x99, 0xC3, 0x00, 0x99, 0x66, 0xC4, 0x00, 0x99, 0x33, 0xC5, 0x00, 0x99, 0x00, 0xC6, 0x00, 0x66, 0xFF, 0xC7, 0x00,
0x66, 0xCC, 0xC8, 0x00, 0x66, 0x99, 0xC9, 0x00, 0x66, 0x66, 0xCA, 0x00, 0x66, 0x33, 0xCB, 0x00, 0x66, 0x00, 0xCC,
0x00, 0x33, 0xFF, 0xCD, 0x00, 0x33, 0xCC, 0xCE, 0x00, 0x33, 0x99, 0xCF, 0x00, 0x33, 0x66, 0xD0, 0x00, 0x33, 0x33,
0xD1, 0x00, 0x33, 0x00, 0xD2, 0x00, 0x00, 0xFF, 0xD3, 0x00, 0x00, 0xCC, 0xD4, 0x00, 0x00, 0x99, 0xD5, 0x00, 0x00,
0x66, 0xD6, 0x00, 0x00, 0x33, 0xD7, 0xEE, 0x00, 0x00, 0xD8, 0xDD, 0x00, 0x00, 0xD9, 0xBB, 0x00, 0x00, 0xDA, 0xAA,
0x00, 0x00, 0xDB, 0x88, 0x00, 0x00, 0xDC, 0x77, 0x00, 0x00, 0xDD, 0x55, 0x00, 0x00, 0xDE, 0x44, 0x00, 0x00, 0xDF,
0x22, 0x00, 0x00, 0xE0, 0x11, 0x00, 0x00, 0xE1, 0x00, 0xEE, 0x00, 0xE2, 0x00, 0xDD, 0x00, 0xE3, 0x00, 0xBB, 0x00,
0xE4, 0x00, 0xAA, 0x00, 0xE5, 0x00, 0x88, 0x00, 0xE6, 0x00, 0x77, 0x00, 0xE7, 0x00, 0x55, 0x00, 0xE8, 0x00, 0x44,
0x00, 0xE9, 0x00, 0x22, 0x00, 0xEA, 0x00, 0x11, 0x00, 0xEB, 0x00, 0x00, 0xEE, 0xEC, 0x00, 0x00, 0xDD, 0xED, 0x00,
0x00, 0xBB, 0xEE, 0x00, 0x00, 0xAA, 0xEF, 0x00, 0x00, 0x88, 0xF0, 0x00, 0x00, 0x77, 0xF1, 0x00, 0x00, 0x55, 0xF2,
0x00, 0x00, 0x44, 0xF3, 0x00, 0x00, 0x22, 0xF4, 0x00, 0x00, 0x11, 0xF5, 0xEE, 0xEE, 0xEE, 0xF6, 0xDD, 0xDD, 0xDD,
0xF7, 0xBB, 0xBB, 0xBB, 0xF8, 0xAA, 0xAA, 0xAA, 0xF9, 0x88, 0x88, 0x88, 0xFA, 0x77, 0x77, 0x77, 0xFB, 0x55, 0x55,
0x55, 0xFC, 0x44, 0x44, 0x44, 0xFD, 0x22, 0x22, 0x22, 0xFE, 0x11, 0x11, 0x11, 0xFF, 0x00, 0x00, 0x00,
};

View File

@ -41,6 +41,8 @@ enum PbDeviceType {
SCHS = 8;
// Printer device
SCLP = 9;
// PowerView device
SCPV = 10;
}
// piscsi remote operations, returning PbResult

View File

@ -1,12 +1,12 @@
make all -j4 DEBUG=1
sudo systemctl stop rascsi
sudo systemctl stop piscsi
sudo make install
sudo systemctl start rascsi
sudo systemctl start piscsi
sleep 1
rasctl -c attach -i 4 -f powerview
#rasctl -c attach -i 0 -f /home/pi/images/RaSCSI-BootstrapV3.hda
#rasctl -c attach -i 0 -f /home/pi/images/claris_works.hda
rasctl -l
tail -f /var/log/rascsi.log
tail -f /var/log/piscsi.log

View File

@ -179,5 +179,11 @@ static const unordered_map<scsi_command, pair<int, const char*>> command_mapping
{scsi_command::eCmdSynchronizeCache16, make_pair(16, "SynchronizeCache16")},
{scsi_command::eCmdReadCapacity16_ReadLong16, make_pair(16, "ReadCapacity16/ReadLong16")},
{scsi_command::eCmdWriteLong16, make_pair(16, "WriteLong16")},
{scsi_command::eCmdReportLuns, make_pair(12, "ReportLuns")}};
{scsi_command::eCmdReportLuns, make_pair(12, "ReportLuns")},
{scsi_command::eCmdPvReadConfig, make_pair(6, "eCmdPvReadConfig")},
{scsi_command::eCmdPvWriteConfig, make_pair(6, "eCmdPvWriteConfig")},
{scsi_command::eCmdPvWriteFrameBuffer, make_pair(6, "eCmdPvWriteFrameBuffer")},
{scsi_command::eCmdPvWriteColorPalette, make_pair(6, "eCmdPvWriteColorPalette")},
{scsi_command::eCmdUnknownPowerViewCC, make_pair(6, "eCmdUnknownPowerViewCC")}};
}; // namespace scsi_defs