* Add natfeat debugprintf support (dumps to the emu's stdout).
* Add XHDI disk support, unfinished. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@23592 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -53,6 +53,9 @@ dprintf(const char *format, ...)
|
|||||||
|
|
||||||
Bconput(DEV_AUX, buffer);
|
Bconput(DEV_AUX, buffer);
|
||||||
|
|
||||||
|
// send to the emulator's stdout if available
|
||||||
|
nat_feat_debugprintf(buffer);
|
||||||
|
|
||||||
//if (platform_boot_options() & BOOT_OPTION_DEBUG_OUTPUT)
|
//if (platform_boot_options() & BOOT_OPTION_DEBUG_OUTPUT)
|
||||||
Bconput(DEV_CONSOLE, buffer);
|
Bconput(DEV_CONSOLE, buffer);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ extern uint32 gBootPartitionOffset;
|
|||||||
#define SCRATCH_SIZE (2*4096)
|
#define SCRATCH_SIZE (2*4096)
|
||||||
static uint8 gScratchBuffer[4096];
|
static uint8 gScratchBuffer[4096];
|
||||||
|
|
||||||
static const uint16 kParametersSizeVersion1 = sizeof(struct tosbpb);
|
static const uint16 kParametersSizeVersion1 = sizeof(struct tos_bpb);
|
||||||
static const uint16 kParametersSizeVersion2 = 0x1e;
|
static const uint16 kParametersSizeVersion2 = 0x1e;
|
||||||
static const uint16 kParametersSizeVersion3 = 0x42;
|
static const uint16 kParametersSizeVersion3 = 0x42;
|
||||||
|
|
||||||
@@ -39,7 +39,7 @@ static const uint16 kDevicePathSignature = 0xbedd;
|
|||||||
|
|
||||||
//XXX clean this up!
|
//XXX clean this up!
|
||||||
struct drive_parameters {
|
struct drive_parameters {
|
||||||
struct tosbpb bpb;
|
struct tos_bpb bpb;
|
||||||
uint16 parameters_size;
|
uint16 parameters_size;
|
||||||
uint16 flags;
|
uint16 flags;
|
||||||
uint32 cylinders;
|
uint32 cylinders;
|
||||||
@@ -115,25 +115,22 @@ class BlockHandle : public Handle {
|
|||||||
BlockHandle(int handle);
|
BlockHandle(int handle);
|
||||||
virtual ~BlockHandle();
|
virtual ~BlockHandle();
|
||||||
|
|
||||||
status_t InitCheck() const;
|
|
||||||
|
|
||||||
virtual ssize_t ReadAt(void *cookie, off_t pos, void *buffer, size_t bufferSize);
|
virtual ssize_t ReadAt(void *cookie, off_t pos, void *buffer, size_t bufferSize);
|
||||||
virtual ssize_t WriteAt(void *cookie, off_t pos, const void *buffer, size_t bufferSize);
|
virtual ssize_t WriteAt(void *cookie, off_t pos, const void *buffer, size_t bufferSize);
|
||||||
|
|
||||||
virtual off_t Size() const;
|
virtual off_t Size() const { return fSize; };
|
||||||
|
|
||||||
uint32 BlockSize() const { return fBlockSize; }
|
uint32 BlockSize() const { return fBlockSize; }
|
||||||
|
|
||||||
status_t FillIdentifier();
|
|
||||||
|
|
||||||
bool HasParameters() const { return fHasParameters; }
|
bool HasParameters() const { return fHasParameters; }
|
||||||
const drive_parameters &Parameters() const { return fParameters; }
|
const drive_parameters &Parameters() const { return fParameters; }
|
||||||
|
|
||||||
disk_identifier &Identifier() { return fIdentifier; }
|
disk_identifier &Identifier() { return fIdentifier; }
|
||||||
uint8 DriveID() const { return fHandle; }
|
uint8 DriveID() const { return fHandle; }
|
||||||
|
|
||||||
|
virtual ssize_t ReadBlocks(void *buffer, off_t first, int32 count);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
status_t ReadBPB(struct tosbpb *bpb);
|
|
||||||
uint64 fSize;
|
uint64 fSize;
|
||||||
uint32 fBlockSize;
|
uint32 fBlockSize;
|
||||||
bool fHasParameters;
|
bool fHasParameters;
|
||||||
@@ -142,15 +139,44 @@ class BlockHandle : public Handle {
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class BIOSDrive : public BlockHandle {
|
||||||
|
public:
|
||||||
|
BIOSDrive(int handle);
|
||||||
|
virtual ~BIOSDrive();
|
||||||
|
|
||||||
|
status_t FillIdentifier();
|
||||||
|
|
||||||
|
virtual ssize_t ReadBlocks(void *buffer, off_t first, int32 count);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
status_t ReadBPB(struct tos_bpb *bpb);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class XHDIDrive : public BlockHandle {
|
||||||
|
public:
|
||||||
|
XHDIDrive(int handle/*, uint16 major, uint16 minor ??*/);
|
||||||
|
virtual ~XHDIDrive();
|
||||||
|
|
||||||
|
status_t FillIdentifier();
|
||||||
|
|
||||||
|
virtual ssize_t ReadBlocks(void *buffer, off_t first, int32 count);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
uint16 fMajor;
|
||||||
|
uint16 fMinor;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
static bool sBlockDevicesAdded = false;
|
static bool sBlockDevicesAdded = false;
|
||||||
|
|
||||||
|
|
||||||
static status_t
|
static status_t
|
||||||
read_bpb(uint8 drive, struct tosbpb *bpb)
|
read_bpb(uint8 drive, struct tos_bpb *bpb)
|
||||||
{
|
{
|
||||||
struct tosbpb *p;
|
struct tos_bpb *p;
|
||||||
p = Getbpb(drive);
|
p = Getbpb(drive);
|
||||||
memcpy(bpb, p, sizeof(struct tosbpb));
|
memcpy(bpb, p, sizeof(struct tos_bpb));
|
||||||
/* Getbpb is buggy so we must force a media change */
|
/* Getbpb is buggy so we must force a media change */
|
||||||
//XXX: docs seems to assume we should loop until it works
|
//XXX: docs seems to assume we should loop until it works
|
||||||
Mediach(drive);
|
Mediach(drive);
|
||||||
@@ -401,6 +427,7 @@ add_block_devices(NodeList *devicesList, bool identifierMissing)
|
|||||||
return B_OK;
|
return B_OK;
|
||||||
|
|
||||||
map = Drvmap();
|
map = Drvmap();
|
||||||
|
dprintf("Drvmap(): 0x%08lx\n", map);
|
||||||
for (driveID = 0; driveID < 32; driveID++) {
|
for (driveID = 0; driveID < 32; driveID++) {
|
||||||
bool present = map & 0x1;
|
bool present = map & 0x1;
|
||||||
map >>= 1;
|
map >>= 1;
|
||||||
@@ -443,7 +470,108 @@ BlockHandle::BlockHandle(int handle)
|
|||||||
: Handle(handle)
|
: Handle(handle)
|
||||||
{
|
{
|
||||||
TRACE(("drive ID %u\n", fHandle));
|
TRACE(("drive ID %u\n", fHandle));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
BlockHandle::~BlockHandle()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
BlockHandle::InitCheck() const
|
||||||
|
{
|
||||||
|
return fSize > 0 ? B_OK : B_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ssize_t
|
||||||
|
BlockHandle::ReadAt(void *cookie, off_t pos, void *buffer, size_t bufferSize)
|
||||||
|
{
|
||||||
|
ssize_t ret;
|
||||||
|
uint32 offset = pos % fBlockSize;
|
||||||
|
pos /= fBlockSize;
|
||||||
|
|
||||||
|
uint32 blocksLeft = (bufferSize + offset + fBlockSize - 1) / fBlockSize;
|
||||||
|
int32 totalBytesRead = 0;
|
||||||
|
|
||||||
|
//TRACE(("BIOS reads %lu bytes from %Ld (offset = %lu), drive %u\n",
|
||||||
|
// blocksLeft * fBlockSize, pos * fBlockSize, offset, fDriveID));
|
||||||
|
|
||||||
|
// read partial block
|
||||||
|
if (offset) {
|
||||||
|
ret = Rwabs(RW_READ | RW_NOTRANSLATE, gScratchBuffer, fBlockSize/256, -1, fHandle, pos * fBlockSize/256);
|
||||||
|
if (ret < 0)
|
||||||
|
return toserror(ret);
|
||||||
|
totalBytesRead += fBlockSize - offset;
|
||||||
|
memcpy(buffer, gScratchBuffer + offset, totalBytesRead);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32 scratchSize = SCRATCH_SIZE / fBlockSize;
|
||||||
|
|
||||||
|
while (blocksLeft > 0) {
|
||||||
|
uint32 blocksRead = blocksLeft;
|
||||||
|
if (blocksRead > scratchSize)
|
||||||
|
blocksRead = scratchSize;
|
||||||
|
|
||||||
|
ret = ReadBlocks(gScratchBuffer, pos, blocksRead);
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
uint32 bytesRead = fBlockSize * blocksRead - offset;
|
||||||
|
// copy no more than bufferSize bytes
|
||||||
|
if (bytesRead > bufferSize)
|
||||||
|
bytesRead = bufferSize;
|
||||||
|
|
||||||
|
memcpy(buffer, (void *)(gScratchBuffer + offset), bytesRead);
|
||||||
|
pos += blocksRead;
|
||||||
|
offset = 0;
|
||||||
|
blocksLeft -= blocksRead;
|
||||||
|
bufferSize -= bytesRead;
|
||||||
|
buffer = (void *)((addr_t)buffer + bytesRead);
|
||||||
|
totalBytesRead += bytesRead;
|
||||||
|
}
|
||||||
|
|
||||||
|
return totalBytesRead;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ssize_t
|
||||||
|
BlockHandle::WriteAt(void *cookie, off_t pos, const void *buffer, size_t bufferSize)
|
||||||
|
{
|
||||||
|
// we don't have to know how to write
|
||||||
|
return B_NOT_ALLOWED;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ssize_t
|
||||||
|
BlockHandle::ReadBlocks(void *buffer, off_t first, int32 count)
|
||||||
|
{
|
||||||
|
return B_NOT_ALLOWED;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*status_t
|
||||||
|
BlockHandle::FillIdentifier()
|
||||||
|
{
|
||||||
|
return B_NOT_ALLOWED;
|
||||||
|
}*/
|
||||||
|
|
||||||
|
// #pragma mark -
|
||||||
|
|
||||||
|
/*
|
||||||
|
* BIOS based disk access.
|
||||||
|
* Only for fallback from missing XHDI.
|
||||||
|
* XXX: This is broken!
|
||||||
|
* XXX: check for physical drives in PUN_INFO
|
||||||
|
* XXX: at least try to use MetaDOS calls instead.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
BIOSDrive::BIOSDrive(int handle)
|
||||||
|
: BlockHandle(handle)
|
||||||
|
{
|
||||||
/* first check if the drive exists */
|
/* first check if the drive exists */
|
||||||
/* note floppy B can be reported present anyway... */
|
/* note floppy B can be reported present anyway... */
|
||||||
uint32 map = Drvmap();
|
uint32 map = Drvmap();
|
||||||
@@ -498,20 +626,13 @@ BlockHandle::BlockHandle(int handle)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
BlockHandle::~BlockHandle()
|
BIOSDrive::~BIOSDrive()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
status_t
|
|
||||||
BlockHandle::InitCheck() const
|
|
||||||
{
|
|
||||||
return fSize > 0 ? B_OK : B_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
ssize_t
|
ssize_t
|
||||||
BlockHandle::ReadAt(void *cookie, off_t pos, void *buffer, size_t bufferSize)
|
BIOSDrive::ReadAt(void *cookie, off_t pos, void *buffer, size_t bufferSize)
|
||||||
{
|
{
|
||||||
int32 ret;
|
int32 ret;
|
||||||
int sectorsPerBlocks = (fBlockSize / 256);
|
int sectorsPerBlocks = (fBlockSize / 256);
|
||||||
@@ -566,22 +687,15 @@ BlockHandle::ReadAt(void *cookie, off_t pos, void *buffer, size_t bufferSize)
|
|||||||
|
|
||||||
|
|
||||||
ssize_t
|
ssize_t
|
||||||
BlockHandle::WriteAt(void *cookie, off_t pos, const void *buffer, size_t bufferSize)
|
BIOSDrive::WriteAt(void *cookie, off_t pos, const void *buffer, size_t bufferSize)
|
||||||
{
|
{
|
||||||
// we don't have to know how to write
|
// we don't have to know how to write
|
||||||
return B_NOT_ALLOWED;
|
return B_NOT_ALLOWED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
off_t
|
|
||||||
BlockHandle::Size() const
|
|
||||||
{
|
|
||||||
return fSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
BlockHandle::FillIdentifier()
|
BIOSDrive::FillIdentifier()
|
||||||
{
|
{
|
||||||
#if 0
|
#if 0
|
||||||
if (HasParameters()) {
|
if (HasParameters()) {
|
||||||
@@ -621,6 +735,127 @@ BlockHandle::FillIdentifier()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ssize_t
|
||||||
|
BIOSDrive::ReadBlocks(void *buffer, off_t first, int32 count)
|
||||||
|
{
|
||||||
|
int sectorsPerBlocks = (fBlockSize / 256);
|
||||||
|
int32 ret;
|
||||||
|
// XXX: check for AHDI 3.0 before using long recno!!!
|
||||||
|
ret = Rwabs(RW_READ | RW_NOTRANSLATE, buffer, sectorsPerBlocks, -1, fHandle, first * sectorsPerBlocks);
|
||||||
|
if (ret < 0)
|
||||||
|
return toserror(ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// #pragma mark -
|
||||||
|
|
||||||
|
/*
|
||||||
|
* XHDI based devices
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
XHDIDrive::XHDIDrive(int handle)
|
||||||
|
: BlockHandle(handle)
|
||||||
|
{
|
||||||
|
/* first check if the drive exists */
|
||||||
|
/* note floppy B can be reported present anyway... */
|
||||||
|
uint32 map = Drvmap();
|
||||||
|
if (!(map & (1 << fHandle))) {
|
||||||
|
fSize = 0LL;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
//XXX: check size
|
||||||
|
|
||||||
|
if (get_drive_parameters(fHandle, &fParameters) != B_OK) {
|
||||||
|
dprintf("getting drive parameters for: %u failed!\n", fHandle);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
fBlockSize = 512;
|
||||||
|
fSize = fParameters.sectors * fBlockSize;
|
||||||
|
fHasParameters = false;
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
if (get_ext_drive_parameters(driveID, &fParameters) != B_OK) {
|
||||||
|
// old style CHS support
|
||||||
|
|
||||||
|
if (get_drive_parameters(driveID, &fParameters) != B_OK) {
|
||||||
|
dprintf("getting drive parameters for: %u failed!\n", fDriveID);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
TRACE((" cylinders: %lu, heads: %lu, sectors: %lu, bytes_per_sector: %u\n",
|
||||||
|
fParameters.cylinders, fParameters.heads, fParameters.sectors_per_track,
|
||||||
|
fParameters.bytes_per_sector));
|
||||||
|
TRACE((" total sectors: %Ld\n", fParameters.sectors));
|
||||||
|
|
||||||
|
fBlockSize = 512;
|
||||||
|
fSize = fParameters.sectors * fBlockSize;
|
||||||
|
fLBA = false;
|
||||||
|
fHasParameters = false;
|
||||||
|
} else {
|
||||||
|
TRACE(("size: %x\n", fParameters.parameters_size));
|
||||||
|
TRACE(("drive_path_signature: %x\n", fParameters.device_path_signature));
|
||||||
|
TRACE(("host bus: \"%s\", interface: \"%s\"\n", fParameters.host_bus,
|
||||||
|
fParameters.interface_type));
|
||||||
|
TRACE(("cylinders: %lu, heads: %lu, sectors: %lu, bytes_per_sector: %u\n",
|
||||||
|
fParameters.cylinders, fParameters.heads, fParameters.sectors_per_track,
|
||||||
|
fParameters.bytes_per_sector));
|
||||||
|
TRACE(("total sectors: %Ld\n", fParameters.sectors));
|
||||||
|
|
||||||
|
fBlockSize = fParameters.bytes_per_sector;
|
||||||
|
fSize = fParameters.sectors * fBlockSize;
|
||||||
|
fLBA = true;
|
||||||
|
fHasParameters = true;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
XHDIDrive::~XHDIDrive()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
XHDIDrive::FillIdentifier()
|
||||||
|
{
|
||||||
|
|
||||||
|
fIdentifier.bus_type = UNKNOWN_BUS;
|
||||||
|
fIdentifier.device_type = UNKNOWN_DEVICE;
|
||||||
|
fIdentifier.device.unknown.size = Size();
|
||||||
|
#if 0
|
||||||
|
// cf. http://toshyp.atari.org/010008.htm#XHDI-Terminologie
|
||||||
|
if (fMajor >= 8 && fMajor <= 15) { // scsi
|
||||||
|
fIdentifier.device_type = SCSI_DEVICE;
|
||||||
|
fIdentifier.device.scsi.logical_unit = fMinor;
|
||||||
|
//XXX: where am I supposed to put the ID ???
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
for (int32 i = 0; i < NUM_DISK_CHECK_SUMS; i++) {
|
||||||
|
fIdentifier.device.unknown.check_sums[i].offset = -1;
|
||||||
|
fIdentifier.device.unknown.check_sums[i].sum = 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return B_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ssize_t
|
||||||
|
XHDIDrive::ReadBlocks(void *buffer, off_t first, int32 count)
|
||||||
|
{
|
||||||
|
int sectorsPerBlocks = (fBlockSize / 256);
|
||||||
|
int32 ret;
|
||||||
|
uint16 flags = RW_READ;
|
||||||
|
//ret = XHReadWrite(fMajor, fMinor, flags, buffer, (uint32)first, (uint16)count, buffer);
|
||||||
|
if (ret < 0)
|
||||||
|
return toserror(ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// #pragma mark -
|
// #pragma mark -
|
||||||
|
|||||||
@@ -118,6 +118,9 @@ _start(void)
|
|||||||
// call C++ constructors before doing anything else
|
// call C++ constructors before doing anything else
|
||||||
|
|
||||||
args.heap_size = HEAP_SIZE;
|
args.heap_size = HEAP_SIZE;
|
||||||
|
|
||||||
|
// so we can dprintf
|
||||||
|
init_nat_features();
|
||||||
|
|
||||||
//serial_init();
|
//serial_init();
|
||||||
console_init();
|
console_init();
|
||||||
|
|||||||
@@ -12,6 +12,9 @@
|
|||||||
|
|
||||||
#include <Errors.h>
|
#include <Errors.h>
|
||||||
|
|
||||||
|
void *gXHDIEntryPoint = NULL;
|
||||||
|
NatFeatCookie *gNatFeatCookie = NULL;
|
||||||
|
int32 gDebugPrintfNatFeatID = 0;
|
||||||
|
|
||||||
/*! Maps TOS error codes to native errors
|
/*! Maps TOS error codes to native errors
|
||||||
*/
|
*/
|
||||||
@@ -103,6 +106,60 @@ toserror(int32 err)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*! Maps XHDI error codes to native errors
|
||||||
|
* cf. http://toshyp.atari.org/010008.htm#XHDI_20error_20codes
|
||||||
|
*/
|
||||||
|
status_t
|
||||||
|
xhdierror(int32 err)
|
||||||
|
{
|
||||||
|
if (err <= -456) {
|
||||||
|
int ide = -(err + 456);
|
||||||
|
// ide status reg
|
||||||
|
// guessed mapping
|
||||||
|
if (ide & (1 << 1)) { // track 0 not found
|
||||||
|
return B_DEV_FORMAT_ERROR;
|
||||||
|
} else if (ide & (1 << 0)) { // DAM not found
|
||||||
|
return B_DEV_FORMAT_ERROR,;
|
||||||
|
} else if (ide & (1 << 4)) { // ID field not found
|
||||||
|
return B_DEV_ID_ERROR;
|
||||||
|
} else if (ide & (1 << 7)) { // bad block mark
|
||||||
|
return B_DEV_FORMAT_ERROR;
|
||||||
|
} else if (ide & (1 << 6)) { // uncorrectable error
|
||||||
|
return B_DEV_UNREADABLE;
|
||||||
|
} else if (ide & (1 << 2)) { // command aborted
|
||||||
|
return EINTR;
|
||||||
|
} else if (ide & (1 << 5)) { // media change
|
||||||
|
return B_DEV_MEDIA_CHANGED;
|
||||||
|
} else if (ide & (1 << 3)) { // media change requested
|
||||||
|
return B_DEV_MEDIA_CHANGE_REQUESTED;
|
||||||
|
}
|
||||||
|
return B_ERROR;
|
||||||
|
} else if (err <= -200) {
|
||||||
|
/* SCSI errors */
|
||||||
|
int scsi = -(err + 200);
|
||||||
|
//XXX:
|
||||||
|
switch (scsi) {
|
||||||
|
case 0x06:
|
||||||
|
return B_DEV_FORMAT_ERROR;
|
||||||
|
case 0x10:
|
||||||
|
return B_DEV_FORMAT_ERROR;
|
||||||
|
case 0x11:
|
||||||
|
return B_DEV_UNREADABLE;
|
||||||
|
case 0x12:
|
||||||
|
return B_DEV_ID_ERROR;
|
||||||
|
case 0x13:
|
||||||
|
return B_DEV_FORMAT_ERROR;
|
||||||
|
case 0x20:
|
||||||
|
return EINTR;
|
||||||
|
case 0x28:
|
||||||
|
return B_DEV_FORMAT_ERROR;
|
||||||
|
case 0x5a:
|
||||||
|
return B_DEV_FORMAT_ERROR;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return toserror(err);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
dump_tos_cookie(const struct tos_cookie *c)
|
dump_tos_cookie(const struct tos_cookie *c)
|
||||||
{
|
{
|
||||||
@@ -121,3 +178,28 @@ dump_tos_cookies(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
init_xhdi(void)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
init_nat_features(void)
|
||||||
|
{
|
||||||
|
if (nat_features()) {
|
||||||
|
// find debugprintf id
|
||||||
|
gDebugPrintfNatFeatID = nat_feat_getid("DEBUGPRINTF");
|
||||||
|
//
|
||||||
|
}
|
||||||
|
return nat_features() ? B_OK : ENOENT;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
nat_feat_debugprintf(const char *str)
|
||||||
|
{
|
||||||
|
if (gDebugPrintfNatFeatID)
|
||||||
|
nat_feat_call(gDebugPrintfNatFeatID, 0, str);
|
||||||
|
}
|
||||||
|
|||||||
@@ -27,40 +27,40 @@ extern "C" {
|
|||||||
//#endif
|
//#endif
|
||||||
|
|
||||||
/* void (no) arg */
|
/* void (no) arg */
|
||||||
#define toscallV(trapnr, callnr) \
|
#define toscallV(trapnr, callnr) \
|
||||||
({ \
|
({ \
|
||||||
register int32 retvalue __asm__("d0"); \
|
register int32 retvalue __asm__("d0"); \
|
||||||
\
|
\
|
||||||
__asm__ volatile \
|
__asm__ volatile \
|
||||||
("/* toscall(" #trapnr ", " #callnr ") */\n \
|
("/* toscall(" #trapnr ", " #callnr ") */\n" \
|
||||||
move.w %[calln],-(%%sp)\n \
|
" move.w %[calln],-(%%sp)\n" \
|
||||||
trap %[trapn]\n \
|
" trap %[trapn]\n" \
|
||||||
add.l #2,%%sp\n" \
|
" add.l #2,%%sp\n" \
|
||||||
: "=r"(retvalue) /* output */ \
|
: "=r"(retvalue) /* output */ \
|
||||||
: [trapn]"i"(trapnr),[calln]"i"(callnr) \
|
: [trapn]"i"(trapnr),[calln]"i"(callnr) \
|
||||||
/* input */ \
|
/* input */ \
|
||||||
: TOS_CLOBBER_LIST /* clobbered regs */ \
|
: TOS_CLOBBER_LIST /* clobbered regs */ \
|
||||||
); \
|
); \
|
||||||
retvalue; \
|
retvalue; \
|
||||||
})
|
})
|
||||||
|
|
||||||
#define toscallW(trapnr, callnr, p1) \
|
#define toscallW(trapnr, callnr, p1) \
|
||||||
({ \
|
({ \
|
||||||
register int32 retvalue __asm__("d0"); \
|
register int32 retvalue __asm__("d0"); \
|
||||||
int16 _p1 = (int16)(p1); \
|
int16 _p1 = (int16)(p1); \
|
||||||
\
|
\
|
||||||
__asm__ volatile \
|
__asm__ volatile \
|
||||||
("/* toscall(" #trapnr ", " #callnr ") */\n \
|
("/* toscall(" #trapnr ", " #callnr ") */\n" \
|
||||||
move.w %1,-(%%sp) \n \
|
" move.w %1,-(%%sp) \n" \
|
||||||
move.w %[calln],-(%%sp)\n \
|
" move.w %[calln],-(%%sp)\n" \
|
||||||
trap %[trapn]\n \
|
" trap %[trapn]\n" \
|
||||||
add.l #4,%%sp \n " \
|
" add.l #4,%%sp \n" \
|
||||||
: "=r"(retvalue) /* output */ \
|
: "=r"(retvalue) /* output */ \
|
||||||
: "r"(_p1), /* input */ \
|
: "r"(_p1), /* input */ \
|
||||||
[trapn]"i"(trapnr),[calln]"i"(callnr) \
|
[trapn]"i"(trapnr),[calln]"i"(callnr) \
|
||||||
: TOS_CLOBBER_LIST /* clobbered regs */ \
|
: TOS_CLOBBER_LIST /* clobbered regs */ \
|
||||||
); \
|
); \
|
||||||
retvalue; \
|
retvalue; \
|
||||||
})
|
})
|
||||||
|
|
||||||
#define toscallL(trapnr, callnr, p1) \
|
#define toscallL(trapnr, callnr, p1) \
|
||||||
@@ -182,7 +182,7 @@ extern "C" {
|
|||||||
|
|
||||||
// cf. http://www.fortunecity.com/skyscraper/apple/308/html/bios.htm
|
// cf. http://www.fortunecity.com/skyscraper/apple/308/html/bios.htm
|
||||||
|
|
||||||
struct tosbpb {
|
struct tos_bpb {
|
||||||
int16 recsiz;
|
int16 recsiz;
|
||||||
int16 clsiz;
|
int16 clsiz;
|
||||||
int16 clsizb;
|
int16 clsizb;
|
||||||
@@ -194,6 +194,18 @@ struct tosbpb {
|
|||||||
int16 bflags;
|
int16 bflags;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct tos_pun_info {
|
||||||
|
int16 puns;
|
||||||
|
uint8 pun[16];
|
||||||
|
int32 part_start[16]; // unsigned ??
|
||||||
|
uint32 p_cookie;
|
||||||
|
struct tos_pun_info *p_cooptr; // points to itself
|
||||||
|
uint16 p_version;
|
||||||
|
uint16 p_max_sector;
|
||||||
|
int32 reserved[16];
|
||||||
|
};
|
||||||
|
#define PUN_INFO ((struct tos_pun_info *)0x516L)
|
||||||
|
|
||||||
|
|
||||||
//#define Getmpb() toscallV(BIOS_TRAP, 0)
|
//#define Getmpb() toscallV(BIOS_TRAP, 0)
|
||||||
#define Bconstat(dev) toscallW(BIOS_TRAP, 1, (uint16)dev)
|
#define Bconstat(dev) toscallW(BIOS_TRAP, 1, (uint16)dev)
|
||||||
@@ -202,7 +214,7 @@ struct tosbpb {
|
|||||||
#define Rwabs(mode, buf, count, recno, dev, lrecno) toscallWPWWWL(BIOS_TRAP, 4, (int16)mode, (void *)buf, (int16)count, (int16)recno, (uint16)dev, (int32)lrecno)
|
#define Rwabs(mode, buf, count, recno, dev, lrecno) toscallWPWWWL(BIOS_TRAP, 4, (int16)mode, (void *)buf, (int16)count, (int16)recno, (uint16)dev, (int32)lrecno)
|
||||||
//#define Setexc() toscallV(BIOS_TRAP, 5, )
|
//#define Setexc() toscallV(BIOS_TRAP, 5, )
|
||||||
#define Tickcal() toscallV(BIOS_TRAP, 6)
|
#define Tickcal() toscallV(BIOS_TRAP, 6)
|
||||||
#define Getbpb(dev) (struct tosbpb *)toscallW(BIOS_TRAP, 7, (uint16)dev)
|
#define Getbpb(dev) (struct tos_bpb *)toscallW(BIOS_TRAP, 7, (uint16)dev)
|
||||||
#define Bcostat(dev) toscallW(BIOS_TRAP, 8, (uint16)dev)
|
#define Bcostat(dev) toscallW(BIOS_TRAP, 8, (uint16)dev)
|
||||||
#define Mediach(dev) toscallW(BIOS_TRAP, 9, (int16)dev)
|
#define Mediach(dev) toscallW(BIOS_TRAP, 9, (int16)dev)
|
||||||
#define Drvmap() (uint32)toscallV(BIOS_TRAP, 10)
|
#define Drvmap() (uint32)toscallV(BIOS_TRAP, 10)
|
||||||
@@ -312,12 +324,119 @@ static inline int Bconputs(int16 handle, const char *string)
|
|||||||
|
|
||||||
#ifndef __ASSEMBLER__
|
#ifndef __ASSEMBLER__
|
||||||
|
|
||||||
|
/*
|
||||||
|
* MetaDOS XBIOS calls
|
||||||
|
*/
|
||||||
|
|
||||||
|
//#define _DISABLE 0
|
||||||
|
|
||||||
|
#ifndef __ASSEMBLER__
|
||||||
|
|
||||||
|
#define Metainit(buf) toscallP(XBIOS_TRAP, 48, (void *)buf)
|
||||||
|
#define Metaopen(drive, p) toscall>P(XBIOS_TRAP, 48, (void *)buf)
|
||||||
|
#define Metaclose(drive) toscallW(XBIOS_TRAP, 50, (int16)drive)
|
||||||
|
#define Metagettoc(drive, flag, p) toscallW(XBIOS_TRAP, 62, (int16)drive, (int16)flag, (void *)p)
|
||||||
|
#define Metadiscinfo(drive, p) toscallWP(XBIOS_TRAP, 63, (int16)drive, (void *)p)
|
||||||
|
#define Metaioctl(drive, magic, op, buf) toscallWLWP(XBIOS_TRAP, 55, (int16)drive, (int32)magic, (int16)op, )
|
||||||
|
//#define Meta(drive) toscallW(XBIOS_TRAP, 50, (int16)drive)
|
||||||
|
//#define Meta(drive) toscallW(XBIOS_TRAP, 50, (int16)drive)
|
||||||
|
//#define Meta(drive) toscallW(XBIOS_TRAP, 50, (int16)drive)
|
||||||
|
|
||||||
|
#endif /* __ASSEMBLER__ */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* XHDI support
|
||||||
|
* see http://toshyp.atari.org/010008.htm
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define XHDI_COOKIE 'XHDI'
|
||||||
|
#define XHDI_MAGIC 0x27011992
|
||||||
|
#define XHDI_CLOBBER_LIST /* only d0 */
|
||||||
|
|
||||||
|
#define XH_TARGET_STOPPABLE 0x00000001L
|
||||||
|
#define XH_TARGET_REMOVABLE 0x00000002L
|
||||||
|
#define XH_TARGET_LOCKABLE 0x00000004L
|
||||||
|
#define XH_TARGET_EJECTABLE 0x00000008L
|
||||||
|
#define XH_TARGET_LOCKED 0x20000000L
|
||||||
|
#define XH_TARGET_STOPPED 0x40000000L
|
||||||
|
#define XH_TARGET_RESERVED 0x80000000L
|
||||||
|
|
||||||
|
#ifndef __ASSEMBLER__
|
||||||
|
|
||||||
|
/* pointer to the XHDI dispatch function */
|
||||||
|
extern void *gXHDIEntryPoint;
|
||||||
|
|
||||||
|
/* void (no) arg */
|
||||||
|
#define xhdicallV(callnr) \
|
||||||
|
({ \
|
||||||
|
register int32 retvalue __asm__("d0"); \
|
||||||
|
\
|
||||||
|
__asm__ volatile \
|
||||||
|
("/* xhdicall(" #callnr ") */\n" \
|
||||||
|
" move.w %[calln],-(%%sp)\n" \
|
||||||
|
" call (%[entry])\n" \
|
||||||
|
" add.l #2,%%sp\n" \
|
||||||
|
: "=r"(retvalue) /* output */ \
|
||||||
|
: /* input */ \
|
||||||
|
[entry]"a"(gXHDIEntryPoint), \
|
||||||
|
[calln]"i"(callnr) \
|
||||||
|
: XHDI_CLOBBER_LIST /* clobbered regs */ \
|
||||||
|
); \
|
||||||
|
retvalue; \
|
||||||
|
})
|
||||||
|
|
||||||
|
#define xhdicallW(callnr, p1) \
|
||||||
|
({ \
|
||||||
|
register int32 retvalue __asm__("d0"); \
|
||||||
|
int16 _p1 = (int16)(p1); \
|
||||||
|
\
|
||||||
|
__asm__ volatile \
|
||||||
|
("/* xhdicall(" #callnr ") */\n" \
|
||||||
|
" move.w %1,-(%%sp) \n" \
|
||||||
|
" move.w %[calln],-(%%sp)\n" \
|
||||||
|
" call (%[entry])\n" \
|
||||||
|
" add.l #4,%%sp \n" \
|
||||||
|
: "=r"(retvalue) /* output */ \
|
||||||
|
: "r"(_p1), /* input */ \
|
||||||
|
[entry]"a"(gXHDIEntryPoint), \
|
||||||
|
[calln]"i"(callnr) \
|
||||||
|
: XHDI_CLOBBER_LIST /* clobbered regs */ \
|
||||||
|
); \
|
||||||
|
retvalue; \
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
#define XHGetVersion() (uint16)xhdicallV(0)
|
||||||
|
#define XHInqTarget(major, minor, bsize, flags, pname) xhdicallWWPPP(1, (uint16)major, (uint16)minor, (uint32 *)bsize, (uint32 *)flags, (char *)pname)
|
||||||
|
//XHReserve 2
|
||||||
|
//#define XHLock() 3
|
||||||
|
//#define XHStop() 4
|
||||||
|
#define XHEject(major, minor, doeject, key) xhdicallWWWW(5, (uint16)major, (uint16)minor, (uint16)doeject, (uint16)key)
|
||||||
|
#define XHDrvMap() xhdicallV(6)
|
||||||
|
//#define XHInqDev(dev,) xhdicall(7,)
|
||||||
|
//XHInqDriver 8
|
||||||
|
//XHNewCookie 9
|
||||||
|
#define XHReadWrite(major, minor, rwflags, recno, count, buf) xhdicalWWWLWP(10, (uint16)major, (uint16)minor, (uint16)rwflags, (uint32)recno, (uint16)count, (void *)buf)
|
||||||
|
#define XHInqTarget2(major, minor, bsize, flags, pname, pnlen) xhdicallWWPPPW(11, (uint16)major, (uint16)minor, (uint32 *)bsize, (uint32 *)flags, (char *)pname, (uint16)pnlen)
|
||||||
|
//XHInqDev2 12
|
||||||
|
//XHDriverSpecial 13
|
||||||
|
#define XHGetCapacity(major, minor, blocks, blocksize) xhdicall(14, (uint16)major, (uint16)minor, (uint32 *)blocks, (uint32 *)blocksize)
|
||||||
|
//#define XHMediumChanged() 15
|
||||||
|
//XHMiNTInfo 16
|
||||||
|
//XHDosLimits 17
|
||||||
|
//XHLastAccess 18
|
||||||
|
//SHReaccess 19
|
||||||
|
|
||||||
|
#endif /* __ASSEMBLER__ */
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* error mapping
|
* error mapping
|
||||||
* in debug.c
|
* in debug.c
|
||||||
*/
|
*/
|
||||||
|
|
||||||
extern status_t toserror(int32 err);
|
extern status_t toserror(int32 err);
|
||||||
|
extern status_t xhdierror(int32 err);
|
||||||
extern void dump_tos_cookies(void);
|
extern void dump_tos_cookies(void);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -374,10 +493,6 @@ static inline const struct tos_osheader *tos_get_osheader()
|
|||||||
|
|
||||||
#endif /* __ASSEMBLER__ */
|
#endif /* __ASSEMBLER__ */
|
||||||
|
|
||||||
/*
|
|
||||||
* XHDI
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* ARAnyM Native Features
|
* ARAnyM Native Features
|
||||||
*/
|
*/
|
||||||
@@ -388,18 +503,21 @@ static inline const struct tos_osheader *tos_get_osheader()
|
|||||||
#ifndef __ASSEMBLER__
|
#ifndef __ASSEMBLER__
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
long magic;
|
uint32 magic;
|
||||||
long (*nfGetID) (const char *);
|
int32 (*nfGetID) (const char *);
|
||||||
long (*nfCall) (long ID, ...);
|
int32 (*nfCall) (int32 ID, ...);
|
||||||
} NatFeatCookie;
|
} NatFeatCookie;
|
||||||
|
|
||||||
extern NatFeatCookie *gNatFeatCookie;
|
extern NatFeatCookie *gNatFeatCookie;
|
||||||
|
extern int32 gDebugPrintfNatFeatID;
|
||||||
|
|
||||||
static inline NatFeatCookie *nat_features(void)
|
static inline NatFeatCookie *nat_features(void)
|
||||||
{
|
{
|
||||||
const struct tos_cookie *c;
|
const struct tos_cookie *c;
|
||||||
if (gNatFeatCookie == (void *)-1 || !gNatFeatCookie)
|
if (gNatFeatCookie == (void *)-1)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
if (gNatFeatCookie)
|
||||||
|
return gNatFeatCookie;
|
||||||
c = tos_find_cookie(NF_COOKIE);
|
c = tos_find_cookie(NF_COOKIE);
|
||||||
if (c) {
|
if (c) {
|
||||||
gNatFeatCookie = (NatFeatCookie *)c->pvalue;
|
gNatFeatCookie = (NatFeatCookie *)c->pvalue;
|
||||||
@@ -411,6 +529,8 @@ static inline NatFeatCookie *nat_features(void)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extern status_t init_nat_features(void);
|
||||||
|
|
||||||
static inline int32 nat_feat_getid(const char *name)
|
static inline int32 nat_feat_getid(const char *name)
|
||||||
{
|
{
|
||||||
NatFeatCookie *c = nat_features();
|
NatFeatCookie *c = nat_features();
|
||||||
@@ -429,17 +549,7 @@ static inline int32 nat_feat_getid(const char *name)
|
|||||||
ret; \
|
ret; \
|
||||||
})
|
})
|
||||||
|
|
||||||
/* XHDI NatFeat */
|
extern void nat_feat_debugprintf(const char *str);
|
||||||
|
|
||||||
#define NF_XHDI "XHDI"
|
|
||||||
|
|
||||||
#define nfxhdi(code, a...) \
|
|
||||||
({ \
|
|
||||||
gNatFeatCookie->nfCall((uint32)code, a##...); \
|
|
||||||
})
|
|
||||||
|
|
||||||
|
|
||||||
#define NFXHversion() nfxhdi(0)
|
|
||||||
|
|
||||||
#endif /* __ASSEMBLER__ */
|
#endif /* __ASSEMBLER__ */
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user