buffer alignment rework

This commit is contained in:
MHeinrichs 2024-11-13 22:18:00 +01:00 committed by Matt Harlum
parent 84b3399a76
commit 8e253bcc42
6 changed files with 48 additions and 33 deletions

31
ata.c
View File

@ -52,12 +52,12 @@ static void __attribute__((always_inline)) ata_status_reg_delay(struct IDEUnit *
*
*/
static void ata_save_error(struct IDEUnit *unit) {
unit->last_error[0] = unit->drive->error_features[0];
unit->last_error[1] = unit->drive->lbaHigh[0];
unit->last_error[2] = unit->drive->lbaMid[0];
unit->last_error[3] = unit->drive->lbaLow[0];
unit->last_error[4] = unit->drive->status_command[0];
unit->last_error[5] = unit->drive->devHead[0];
unit->last_error[0] = *unit->drive->error_features;
unit->last_error[1] = *unit->drive->lbaHigh;
unit->last_error[2] = *unit->drive->lbaMid;
unit->last_error[3] = *unit->drive->lbaLow;
unit->last_error[4] = *unit->drive->status_command;
unit->last_error[5] = *unit->drive->devHead;
}
/**
@ -204,6 +204,7 @@ bool ata_identify(struct IDEUnit *unit, UWORD *buffer)
*unit->drive->lbaMid = 0;
*unit->drive->lbaHigh = 0;
*unit->drive->error_features = 0;
*unit->drive->devHead = drvSel;
*unit->drive->status_command = ATA_CMD_IDENTIFY;
if (ata_check_error(unit) || !ata_wait_drq(unit,500,false)) {
@ -217,7 +218,7 @@ bool ata_identify(struct IDEUnit *unit, UWORD *buffer)
if (buffer) {
UWORD read_data;
for (int i=0; i<256; i++) {
read_data = unit->drive->data[i];
read_data = *unit->drive->data; //autoincrement on the ide-side
// Interface is byte-swapped, so swap the identify data back.
buffer[i] = ((read_data >> 8) | (read_data << 8));
}
@ -270,8 +271,20 @@ bool ata_init_unit(struct IDEUnit *unit) {
bool dev_found = false;
offset = (unit->channel == 0) ? CHANNEL_0 : CHANNEL_1;
unit->drive = (void *)unit->cd->cd_BoardAddr + offset; // Pointer to drive base
if ((unit->drive = AllocMem(sizeof(struct Drive),MEMF_ANY|MEMF_CLEAR)) == NULL) { // Pointerholder for drive base
return false;
}
unit->drive->data = (UWORD*) ((void *)unit->cd->cd_BoardAddr + offset + ata_reg_data);
unit->drive->error_features = (UBYTE*) ((void *)unit->cd->cd_BoardAddr + offset + ata_reg_error);
unit->drive->sectorCount = (UBYTE*) ((void *)unit->cd->cd_BoardAddr + offset + ata_reg_sectorCount);
unit->drive->lbaLow = (UBYTE*) ((void *)unit->cd->cd_BoardAddr + offset + ata_reg_lbaLow);
unit->drive->lbaMid = (UBYTE*) ((void *)unit->cd->cd_BoardAddr + offset + ata_reg_lbaMid);
unit->drive->lbaHigh = (UBYTE*) ((void *)unit->cd->cd_BoardAddr + offset + ata_reg_lbaHigh);
unit->drive->devHead = (UBYTE*) ((void *)unit->cd->cd_BoardAddr + offset + ata_reg_devHead);
unit->drive->status_command = (UBYTE*) ((void *)unit->cd->cd_BoardAddr + offset + ata_reg_status);
*unit->shadowDevHead = *unit->drive->devHead = (unit->primary) ? 0xE0 : 0xF0; // Select drive
for (int i=0; i<(8*NEXT_REG); i+=NEXT_REG) {

27
ata.h
View File

@ -14,22 +14,23 @@
#error "MAX_TRANSFER_SECTORS cannot be larger than 256"
#endif
#define CHANNEL_0 0x1000
#define CHANNEL_1 0x2000
#define CHANNEL_0 0x1000
#define CHANNEL_1 0x2000
#define IDE_CSMASK 0x0000
#define NEXT_REG 0x200
// BYTE Offsets
#define ata_reg_data 0x000
#define ata_reg_error 0x200
#define ata_reg_features 0x200
#define ata_reg_sectorCount 0x400
#define ata_reg_lbaLow 0x600
#define ata_reg_lbaMid 0x800
#define ata_reg_lbaHigh 0xA00
#define ata_reg_devHead 0xC00
#define ata_reg_status 0xE00
#define ata_reg_command 0xE00
#define ata_reg_altStatus 0x1C00
#define ata_reg_data 0*NEXT_REG + IDE_CSMASK
#define ata_reg_error 1*NEXT_REG + IDE_CSMASK
#define ata_reg_features 1*NEXT_REG + IDE_CSMASK
#define ata_reg_sectorCount 2*NEXT_REG + IDE_CSMASK
#define ata_reg_lbaLow 3*NEXT_REG + IDE_CSMASK
#define ata_reg_lbaMid 4*NEXT_REG + IDE_CSMASK
#define ata_reg_lbaHigh 5*NEXT_REG + IDE_CSMASK
#define ata_reg_devHead 6*NEXT_REG + IDE_CSMASK
#define ata_reg_status 7*NEXT_REG + IDE_CSMASK
#define ata_reg_command 7*NEXT_REG + IDE_CSMASK
#define ata_reg_altStatus 6*NEXT_REG + IDE_CSMASK
#define drv_sel_secondary (1<<4)

View File

@ -206,7 +206,7 @@ bool atapi_identify(struct IDEUnit *unit, UWORD *buffer) {
if (buffer) {
UWORD read_data;
for (int i=0; i<256; i++) {
read_data = unit->drive->data[i];
read_data = *unit->drive->data;
buffer[i] = ((read_data >> 8) | (read_data << 8));
}
}

View File

@ -27,14 +27,14 @@ enum xfer {
* To use this code with other boards you may need to adjust these sizes
*/
struct Drive {
UWORD data[256];
UBYTE error_features[512];
UBYTE sectorCount[512];
UBYTE lbaLow[512];
UBYTE lbaMid[512];
UBYTE lbaHigh[512];
UBYTE devHead[512];
UBYTE status_command[512];
UWORD* data;
UBYTE* error_features;
UBYTE* sectorCount;
UBYTE* lbaLow;
UBYTE* lbaMid;
UBYTE* lbaHigh;
UBYTE* devHead;
UBYTE* status_command;
};
struct IDEUnit {
@ -120,7 +120,7 @@ struct IDETask {
#define DEVICE_ID_STRING "lide " XSTR(DEVICE_VERSION) "." XSTR(DEVICE_REVISION) " (" XSTR(BUILD_DATE) ") " XSTR(GIT_REF)
#define DEVICE_VERSION 40
#define DEVICE_REVISION 9
#define DEVICE_REVISION 10
#define DEVICE_PRIORITY 0 /* Most people will not need a priority and should leave it at zero. */
#endif

View File

@ -304,7 +304,7 @@ static BYTE detectChannels(struct ConfigDev *cd) {
// Detect if there are 1 or 2 IDE channels on this board
// 2 channel boards use the CS2 decode for the second channel
volatile UBYTE *status = cd->cd_BoardAddr + CHANNEL_0 + ata_reg_status;
volatile UBYTE *alt_status = cd->cd_BoardAddr + CHANNEL_0 + ata_reg_altStatus;
volatile UBYTE *alt_status = cd->cd_BoardAddr + CHANNEL_1 + ata_reg_altStatus;
// Try a couple of times with a small delay
// Some drives have been seen to be quite slow at resetting, and interfere with the channel detection unless there's a delay

View File

@ -527,6 +527,7 @@ static void cleanup(struct IDETask *itask) {
ObtainSemaphore(&itask->dev->ulSem);
Remove((struct Node *)unit);
ReleaseSemaphore(&itask->dev->ulSem);
FreeMem(unit->drive,sizeof(struct Drive));
FreeMem(unit,sizeof(struct IDEUnit));
}
}