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) { static void ata_save_error(struct IDEUnit *unit) {
unit->last_error[0] = unit->drive->error_features[0]; unit->last_error[0] = *unit->drive->error_features;
unit->last_error[1] = unit->drive->lbaHigh[0]; unit->last_error[1] = *unit->drive->lbaHigh;
unit->last_error[2] = unit->drive->lbaMid[0]; unit->last_error[2] = *unit->drive->lbaMid;
unit->last_error[3] = unit->drive->lbaLow[0]; unit->last_error[3] = *unit->drive->lbaLow;
unit->last_error[4] = unit->drive->status_command[0]; unit->last_error[4] = *unit->drive->status_command;
unit->last_error[5] = unit->drive->devHead[0]; 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->lbaMid = 0;
*unit->drive->lbaHigh = 0; *unit->drive->lbaHigh = 0;
*unit->drive->error_features = 0; *unit->drive->error_features = 0;
*unit->drive->devHead = drvSel;
*unit->drive->status_command = ATA_CMD_IDENTIFY; *unit->drive->status_command = ATA_CMD_IDENTIFY;
if (ata_check_error(unit) || !ata_wait_drq(unit,500,false)) { 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) { if (buffer) {
UWORD read_data; UWORD read_data;
for (int i=0; i<256; i++) { 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. // Interface is byte-swapped, so swap the identify data back.
buffer[i] = ((read_data >> 8) | (read_data << 8)); buffer[i] = ((read_data >> 8) | (read_data << 8));
} }
@ -270,8 +271,20 @@ bool ata_init_unit(struct IDEUnit *unit) {
bool dev_found = false; bool dev_found = false;
offset = (unit->channel == 0) ? CHANNEL_0 : CHANNEL_1; 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 *unit->shadowDevHead = *unit->drive->devHead = (unit->primary) ? 0xE0 : 0xF0; // Select drive
for (int i=0; i<(8*NEXT_REG); i+=NEXT_REG) { 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" #error "MAX_TRANSFER_SECTORS cannot be larger than 256"
#endif #endif
#define CHANNEL_0 0x1000 #define CHANNEL_0 0x1000
#define CHANNEL_1 0x2000 #define CHANNEL_1 0x2000
#define IDE_CSMASK 0x0000
#define NEXT_REG 0x200 #define NEXT_REG 0x200
// BYTE Offsets // BYTE Offsets
#define ata_reg_data 0x000 #define ata_reg_data 0*NEXT_REG + IDE_CSMASK
#define ata_reg_error 0x200 #define ata_reg_error 1*NEXT_REG + IDE_CSMASK
#define ata_reg_features 0x200 #define ata_reg_features 1*NEXT_REG + IDE_CSMASK
#define ata_reg_sectorCount 0x400 #define ata_reg_sectorCount 2*NEXT_REG + IDE_CSMASK
#define ata_reg_lbaLow 0x600 #define ata_reg_lbaLow 3*NEXT_REG + IDE_CSMASK
#define ata_reg_lbaMid 0x800 #define ata_reg_lbaMid 4*NEXT_REG + IDE_CSMASK
#define ata_reg_lbaHigh 0xA00 #define ata_reg_lbaHigh 5*NEXT_REG + IDE_CSMASK
#define ata_reg_devHead 0xC00 #define ata_reg_devHead 6*NEXT_REG + IDE_CSMASK
#define ata_reg_status 0xE00 #define ata_reg_status 7*NEXT_REG + IDE_CSMASK
#define ata_reg_command 0xE00 #define ata_reg_command 7*NEXT_REG + IDE_CSMASK
#define ata_reg_altStatus 0x1C00 #define ata_reg_altStatus 6*NEXT_REG + IDE_CSMASK
#define drv_sel_secondary (1<<4) #define drv_sel_secondary (1<<4)

View File

@ -206,7 +206,7 @@ bool atapi_identify(struct IDEUnit *unit, UWORD *buffer) {
if (buffer) { if (buffer) {
UWORD read_data; UWORD read_data;
for (int i=0; i<256; i++) { 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)); 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 * To use this code with other boards you may need to adjust these sizes
*/ */
struct Drive { struct Drive {
UWORD data[256]; UWORD* data;
UBYTE error_features[512]; UBYTE* error_features;
UBYTE sectorCount[512]; UBYTE* sectorCount;
UBYTE lbaLow[512]; UBYTE* lbaLow;
UBYTE lbaMid[512]; UBYTE* lbaMid;
UBYTE lbaHigh[512]; UBYTE* lbaHigh;
UBYTE devHead[512]; UBYTE* devHead;
UBYTE status_command[512]; UBYTE* status_command;
}; };
struct IDEUnit { 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_ID_STRING "lide " XSTR(DEVICE_VERSION) "." XSTR(DEVICE_REVISION) " (" XSTR(BUILD_DATE) ") " XSTR(GIT_REF)
#define DEVICE_VERSION 40 #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. */ #define DEVICE_PRIORITY 0 /* Most people will not need a priority and should leave it at zero. */
#endif #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 // Detect if there are 1 or 2 IDE channels on this board
// 2 channel boards use the CS2 decode for the second channel // 2 channel boards use the CS2 decode for the second channel
volatile UBYTE *status = cd->cd_BoardAddr + CHANNEL_0 + ata_reg_status; 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 // 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 // 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); ObtainSemaphore(&itask->dev->ulSem);
Remove((struct Node *)unit); Remove((struct Node *)unit);
ReleaseSemaphore(&itask->dev->ulSem); ReleaseSemaphore(&itask->dev->ulSem);
FreeMem(unit->drive,sizeof(struct Drive));
FreeMem(unit,sizeof(struct IDEUnit)); FreeMem(unit,sizeof(struct IDEUnit));
} }
} }