* 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);
|
||||
|
||||
// send to the emulator's stdout if available
|
||||
nat_feat_debugprintf(buffer);
|
||||
|
||||
//if (platform_boot_options() & BOOT_OPTION_DEBUG_OUTPUT)
|
||||
Bconput(DEV_CONSOLE, buffer);
|
||||
}
|
||||
|
||||
@@ -31,7 +31,7 @@ extern uint32 gBootPartitionOffset;
|
||||
#define SCRATCH_SIZE (2*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 kParametersSizeVersion3 = 0x42;
|
||||
|
||||
@@ -39,7 +39,7 @@ static const uint16 kDevicePathSignature = 0xbedd;
|
||||
|
||||
//XXX clean this up!
|
||||
struct drive_parameters {
|
||||
struct tosbpb bpb;
|
||||
struct tos_bpb bpb;
|
||||
uint16 parameters_size;
|
||||
uint16 flags;
|
||||
uint32 cylinders;
|
||||
@@ -115,25 +115,22 @@ class BlockHandle : public Handle {
|
||||
BlockHandle(int handle);
|
||||
virtual ~BlockHandle();
|
||||
|
||||
status_t InitCheck() const;
|
||||
|
||||
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 off_t Size() const;
|
||||
virtual off_t Size() const { return fSize; };
|
||||
|
||||
uint32 BlockSize() const { return fBlockSize; }
|
||||
|
||||
status_t FillIdentifier();
|
||||
|
||||
bool HasParameters() const { return fHasParameters; }
|
||||
const drive_parameters &Parameters() const { return fParameters; }
|
||||
|
||||
disk_identifier &Identifier() { return fIdentifier; }
|
||||
uint8 DriveID() const { return fHandle; }
|
||||
|
||||
virtual ssize_t ReadBlocks(void *buffer, off_t first, int32 count);
|
||||
|
||||
protected:
|
||||
status_t ReadBPB(struct tosbpb *bpb);
|
||||
uint64 fSize;
|
||||
uint32 fBlockSize;
|
||||
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 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);
|
||||
memcpy(bpb, p, sizeof(struct tosbpb));
|
||||
memcpy(bpb, p, sizeof(struct tos_bpb));
|
||||
/* Getbpb is buggy so we must force a media change */
|
||||
//XXX: docs seems to assume we should loop until it works
|
||||
Mediach(drive);
|
||||
@@ -401,6 +427,7 @@ add_block_devices(NodeList *devicesList, bool identifierMissing)
|
||||
return B_OK;
|
||||
|
||||
map = Drvmap();
|
||||
dprintf("Drvmap(): 0x%08lx\n", map);
|
||||
for (driveID = 0; driveID < 32; driveID++) {
|
||||
bool present = map & 0x1;
|
||||
map >>= 1;
|
||||
@@ -443,7 +470,108 @@ BlockHandle::BlockHandle(int handle)
|
||||
: Handle(handle)
|
||||
{
|
||||
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 */
|
||||
/* note floppy B can be reported present anyway... */
|
||||
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
|
||||
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;
|
||||
int sectorsPerBlocks = (fBlockSize / 256);
|
||||
@@ -566,22 +687,15 @@ BlockHandle::ReadAt(void *cookie, off_t pos, void *buffer, size_t bufferSize)
|
||||
|
||||
|
||||
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
|
||||
return B_NOT_ALLOWED;
|
||||
}
|
||||
|
||||
|
||||
off_t
|
||||
BlockHandle::Size() const
|
||||
{
|
||||
return fSize;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
BlockHandle::FillIdentifier()
|
||||
BIOSDrive::FillIdentifier()
|
||||
{
|
||||
#if 0
|
||||
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 -
|
||||
|
||||
@@ -118,6 +118,9 @@ _start(void)
|
||||
// call C++ constructors before doing anything else
|
||||
|
||||
args.heap_size = HEAP_SIZE;
|
||||
|
||||
// so we can dprintf
|
||||
init_nat_features();
|
||||
|
||||
//serial_init();
|
||||
console_init();
|
||||
|
||||
@@ -12,6 +12,9 @@
|
||||
|
||||
#include <Errors.h>
|
||||
|
||||
void *gXHDIEntryPoint = NULL;
|
||||
NatFeatCookie *gNatFeatCookie = NULL;
|
||||
int32 gDebugPrintfNatFeatID = 0;
|
||||
|
||||
/*! 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
|
||||
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
|
||||
|
||||
/* void (no) arg */
|
||||
#define toscallV(trapnr, callnr) \
|
||||
({ \
|
||||
#define toscallV(trapnr, callnr) \
|
||||
({ \
|
||||
register int32 retvalue __asm__("d0"); \
|
||||
\
|
||||
__asm__ volatile \
|
||||
("/* toscall(" #trapnr ", " #callnr ") */\n \
|
||||
move.w %[calln],-(%%sp)\n \
|
||||
trap %[trapn]\n \
|
||||
add.l #2,%%sp\n" \
|
||||
: "=r"(retvalue) /* output */ \
|
||||
\
|
||||
__asm__ volatile \
|
||||
("/* toscall(" #trapnr ", " #callnr ") */\n" \
|
||||
" move.w %[calln],-(%%sp)\n" \
|
||||
" trap %[trapn]\n" \
|
||||
" add.l #2,%%sp\n" \
|
||||
: "=r"(retvalue) /* output */ \
|
||||
: [trapn]"i"(trapnr),[calln]"i"(callnr) \
|
||||
/* input */ \
|
||||
/* input */ \
|
||||
: TOS_CLOBBER_LIST /* clobbered regs */ \
|
||||
); \
|
||||
retvalue; \
|
||||
); \
|
||||
retvalue; \
|
||||
})
|
||||
|
||||
#define toscallW(trapnr, callnr, p1) \
|
||||
({ \
|
||||
({ \
|
||||
register int32 retvalue __asm__("d0"); \
|
||||
int16 _p1 = (int16)(p1); \
|
||||
\
|
||||
__asm__ volatile \
|
||||
("/* toscall(" #trapnr ", " #callnr ") */\n \
|
||||
move.w %1,-(%%sp) \n \
|
||||
move.w %[calln],-(%%sp)\n \
|
||||
trap %[trapn]\n \
|
||||
add.l #4,%%sp \n " \
|
||||
: "=r"(retvalue) /* output */ \
|
||||
: "r"(_p1), /* input */ \
|
||||
int16 _p1 = (int16)(p1); \
|
||||
\
|
||||
__asm__ volatile \
|
||||
("/* toscall(" #trapnr ", " #callnr ") */\n" \
|
||||
" move.w %1,-(%%sp) \n" \
|
||||
" move.w %[calln],-(%%sp)\n" \
|
||||
" trap %[trapn]\n" \
|
||||
" add.l #4,%%sp \n" \
|
||||
: "=r"(retvalue) /* output */ \
|
||||
: "r"(_p1), /* input */ \
|
||||
[trapn]"i"(trapnr),[calln]"i"(callnr) \
|
||||
: TOS_CLOBBER_LIST /* clobbered regs */ \
|
||||
); \
|
||||
retvalue; \
|
||||
); \
|
||||
retvalue; \
|
||||
})
|
||||
|
||||
#define toscallL(trapnr, callnr, p1) \
|
||||
@@ -182,7 +182,7 @@ extern "C" {
|
||||
|
||||
// cf. http://www.fortunecity.com/skyscraper/apple/308/html/bios.htm
|
||||
|
||||
struct tosbpb {
|
||||
struct tos_bpb {
|
||||
int16 recsiz;
|
||||
int16 clsiz;
|
||||
int16 clsizb;
|
||||
@@ -194,6 +194,18 @@ struct tosbpb {
|
||||
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 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 Setexc() toscallV(BIOS_TRAP, 5, )
|
||||
#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 Mediach(dev) toscallW(BIOS_TRAP, 9, (int16)dev)
|
||||
#define Drvmap() (uint32)toscallV(BIOS_TRAP, 10)
|
||||
@@ -312,12 +324,119 @@ static inline int Bconputs(int16 handle, const char *string)
|
||||
|
||||
#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
|
||||
* in debug.c
|
||||
*/
|
||||
|
||||
extern status_t toserror(int32 err);
|
||||
extern status_t xhdierror(int32 err);
|
||||
extern void dump_tos_cookies(void);
|
||||
|
||||
/*
|
||||
@@ -374,10 +493,6 @@ static inline const struct tos_osheader *tos_get_osheader()
|
||||
|
||||
#endif /* __ASSEMBLER__ */
|
||||
|
||||
/*
|
||||
* XHDI
|
||||
*/
|
||||
|
||||
/*
|
||||
* ARAnyM Native Features
|
||||
*/
|
||||
@@ -388,18 +503,21 @@ static inline const struct tos_osheader *tos_get_osheader()
|
||||
#ifndef __ASSEMBLER__
|
||||
|
||||
typedef struct {
|
||||
long magic;
|
||||
long (*nfGetID) (const char *);
|
||||
long (*nfCall) (long ID, ...);
|
||||
uint32 magic;
|
||||
int32 (*nfGetID) (const char *);
|
||||
int32 (*nfCall) (int32 ID, ...);
|
||||
} NatFeatCookie;
|
||||
|
||||
extern NatFeatCookie *gNatFeatCookie;
|
||||
extern int32 gDebugPrintfNatFeatID;
|
||||
|
||||
static inline NatFeatCookie *nat_features(void)
|
||||
{
|
||||
const struct tos_cookie *c;
|
||||
if (gNatFeatCookie == (void *)-1 || !gNatFeatCookie)
|
||||
if (gNatFeatCookie == (void *)-1)
|
||||
return NULL;
|
||||
if (gNatFeatCookie)
|
||||
return gNatFeatCookie;
|
||||
c = tos_find_cookie(NF_COOKIE);
|
||||
if (c) {
|
||||
gNatFeatCookie = (NatFeatCookie *)c->pvalue;
|
||||
@@ -411,6 +529,8 @@ static inline NatFeatCookie *nat_features(void)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
extern status_t init_nat_features(void);
|
||||
|
||||
static inline int32 nat_feat_getid(const char *name)
|
||||
{
|
||||
NatFeatCookie *c = nat_features();
|
||||
@@ -429,17 +549,7 @@ static inline int32 nat_feat_getid(const char *name)
|
||||
ret; \
|
||||
})
|
||||
|
||||
/* XHDI NatFeat */
|
||||
|
||||
#define NF_XHDI "XHDI"
|
||||
|
||||
#define nfxhdi(code, a...) \
|
||||
({ \
|
||||
gNatFeatCookie->nfCall((uint32)code, a##...); \
|
||||
})
|
||||
|
||||
|
||||
#define NFXHversion() nfxhdi(0)
|
||||
extern void nat_feat_debugprintf(const char *str);
|
||||
|
||||
#endif /* __ASSEMBLER__ */
|
||||
|
||||
|
||||
Reference in New Issue
Block a user