FDC READ and WRITE
Basic read and write functionality. Status codes still not correct, no media change or write protect detection yet.
This commit is contained in:
parent
fcd89cc069
commit
3e7f1e9f7f
Binary file not shown.
|
@ -7,8 +7,12 @@
|
||||||
#include "simpleio.h"
|
#include "simpleio.h"
|
||||||
#include "sys_general.h"
|
#include "sys_general.h"
|
||||||
#include "syscalls.h"
|
#include "syscalls.h"
|
||||||
|
#include "types.h"
|
||||||
#include "mem_cmds.h"
|
#include "mem_cmds.h"
|
||||||
|
|
||||||
|
/* Pointer to a function taking void and returning void */
|
||||||
|
typedef void (*p_thunk)();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Print out the contents of a block of memory
|
* Print out the contents of a block of memory
|
||||||
*
|
*
|
||||||
|
@ -38,9 +42,6 @@ short mem_cmd_dump(short channel, int argc, const char * argv[]) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Pointer to a function taking void and returning void */
|
|
||||||
typedef void (*p_thunk)();
|
|
||||||
|
|
||||||
void test_thunk() {
|
void test_thunk() {
|
||||||
log(LOG_ERROR, "CALL is working.");
|
log(LOG_ERROR, "CALL is working.");
|
||||||
}
|
}
|
||||||
|
|
|
@ -412,7 +412,7 @@ short cli_test_seek(short screen, int argc, const char * argv[]) {
|
||||||
/*
|
/*
|
||||||
* Test the FDC interface by reading the MBR
|
* Test the FDC interface by reading the MBR
|
||||||
*
|
*
|
||||||
* TEST FDC [DMA]
|
* TEST FDC [<lba> [WRITE <data>]]
|
||||||
*/
|
*/
|
||||||
short cli_test_fdc(short screen, int argc, const char * argv[]) {
|
short cli_test_fdc(short screen, int argc, const char * argv[]) {
|
||||||
unsigned char buffer[512];
|
unsigned char buffer[512];
|
||||||
|
@ -422,12 +422,16 @@ short cli_test_fdc(short screen, int argc, const char * argv[]) {
|
||||||
short scancode;
|
short scancode;
|
||||||
short n = 0;
|
short n = 0;
|
||||||
short result;
|
short result;
|
||||||
|
short is_write = 0;
|
||||||
|
unsigned char data = 0xAA;
|
||||||
|
|
||||||
if (argc > 1) {
|
if (argc > 1) {
|
||||||
if ((strcmp(argv[1], "DMA") == 0) || ((strcmp(argv[1], "dma") == 0)) {
|
lba = (unsigned long)cli_eval_number(argv[1]);
|
||||||
fdc_set_dma(1);
|
if (argc > 2) {
|
||||||
|
print(screen, "Will attempt to write before reading...\n");
|
||||||
|
is_write = 1;
|
||||||
|
data = (unsigned long)cli_eval_number(argv[3]);
|
||||||
}
|
}
|
||||||
// lba = (unsigned long)cli_eval_number(argv[1]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bdev_ioctrl(BDEV_FDC, FDC_CTRL_MOTOR_ON, 0, 0);
|
bdev_ioctrl(BDEV_FDC, FDC_CTRL_MOTOR_ON, 0, 0);
|
||||||
|
@ -439,6 +443,21 @@ short cli_test_fdc(short screen, int argc, const char * argv[]) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < 512; i++) {
|
||||||
|
buffer[i] = data;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (is_write) {
|
||||||
|
n = bdev_write(BDEV_FDC, lba, buffer, 512);
|
||||||
|
if (n < 0) {
|
||||||
|
dump_buffer(screen, buffer, 512, 1);
|
||||||
|
sprintf(message, "Unable to write sector %d: %s\n", lba, err_message(n));
|
||||||
|
print(screen, message);
|
||||||
|
bdev_ioctrl(BDEV_FDC, FDC_CTRL_MOTOR_OFF, 0, 0);
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for (i = 0; i < 512; i++) {
|
for (i = 0; i < 512; i++) {
|
||||||
buffer[i] = 0xAA;
|
buffer[i] = 0xAA;
|
||||||
}
|
}
|
||||||
|
|
216
src/dev/fdc.c
216
src/dev/fdc.c
|
@ -16,6 +16,7 @@
|
||||||
#include "fdc.h"
|
#include "fdc.h"
|
||||||
#include "fdc_reg.h"
|
#include "fdc_reg.h"
|
||||||
#include "interrupt.h"
|
#include "interrupt.h"
|
||||||
|
#include "rtc_reg.h"
|
||||||
#include "syscalls.h"
|
#include "syscalls.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -23,7 +24,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const long fdc_motor_wait = 18; /* The number of jiffies to wait for the motor to spin up: 300ms */
|
const long fdc_motor_wait = 18; /* The number of jiffies to wait for the motor to spin up: 300ms */
|
||||||
const long fdc_motor_timeout = 120; /* The number of jiffies to let the motor spin without activity: 2 seconds */
|
const long fdc_motor_timeout = 300; /* The number of jiffies to let the motor spin without activity: 30 seconds */
|
||||||
const long fdc_seek_timeout = 180; /* 3s timeout for the head to seek */
|
const long fdc_seek_timeout = 180; /* 3s timeout for the head to seek */
|
||||||
const long fdc_timeout = 120; /* The number of jiffies to allow for basic wait loops */
|
const long fdc_timeout = 120; /* The number of jiffies to allow for basic wait loops */
|
||||||
|
|
||||||
|
@ -71,6 +72,12 @@ static short fdc_cylinders = 80; /* How many cylinders */
|
||||||
static short fdc_bytes_per_sector = 512; /* How many bytes are in a sector */
|
static short fdc_bytes_per_sector = 512; /* How many bytes are in a sector */
|
||||||
static short fdc_use_dma = 0; /* If 0: used polled I/O, if anything else, use DMA */
|
static short fdc_use_dma = 0; /* If 0: used polled I/O, if anything else, use DMA */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check the current jiffy count and turn off the motor if we've reached the time the motor should be turned off
|
||||||
|
* This time gets reset every time we ask for the motor to be turned on
|
||||||
|
*/
|
||||||
|
extern void fdc_motor_watchdog();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Convert a logical block address to cylinder-head-sector addressing
|
* Convert a logical block address to cylinder-head-sector addressing
|
||||||
*
|
*
|
||||||
|
@ -226,31 +233,14 @@ void fdc_delay(int jiffies) {
|
||||||
* 0 on success, negative number is an error
|
* 0 on success, negative number is an error
|
||||||
*/
|
*/
|
||||||
short fdc_in(unsigned char *ptr) {
|
short fdc_in(unsigned char *ptr) {
|
||||||
unsigned char msr, data;
|
long target_ticks = timers_jiffies() + fdc_timeout;
|
||||||
short step, i;
|
while ((*FDC_MSR & FDC_MSR_RQM) != FDC_MSR_RQM) {
|
||||||
|
if (timers_jiffies() >= target_ticks) {
|
||||||
step = 1;
|
log(LOG_ERROR, "fdc_in: timeout waiting for RQM");
|
||||||
for (i = 0; i < fdc_timeout; i += step) {
|
return DEV_TIMEOUT;
|
||||||
msr = *FDC_MSR & (FDC_MSR_DIO | FDC_MSR_RQM);
|
|
||||||
|
|
||||||
if (msr == (FDC_MSR_DIO | FDC_MSR_RQM)) {
|
|
||||||
data = *FDC_DATA;
|
|
||||||
if (ptr)
|
|
||||||
*ptr = data;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (msr == FDC_MSR_RQM) {
|
|
||||||
log(LOG_ERROR, "fdc_in: ready for output during input");
|
|
||||||
return ERR_GENERAL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
step += step;
|
|
||||||
fdc_delay(step);
|
|
||||||
}
|
}
|
||||||
|
*ptr = *FDC_DATA;
|
||||||
log(LOG_ERROR, "fdc_in: timeout");
|
|
||||||
return DEV_TIMEOUT;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -263,30 +253,19 @@ short fdc_in(unsigned char *ptr) {
|
||||||
* 0 on success, negative number is an error
|
* 0 on success, negative number is an error
|
||||||
*/
|
*/
|
||||||
short fdc_out(unsigned char x) {
|
short fdc_out(unsigned char x) {
|
||||||
unsigned char msr, data;
|
long target_ticks = timers_jiffies() + fdc_timeout;
|
||||||
short step, i;
|
while ((*FDC_MSR & FDC_MSR_RQM) != FDC_MSR_RQM) {
|
||||||
|
if (timers_jiffies() >= target_ticks) {
|
||||||
step = 1;
|
log(LOG_ERROR, "fdc_out: timeout waiting for RQM");
|
||||||
for (i = 0; i < fdc_timeout; i += step) {
|
return DEV_TIMEOUT;
|
||||||
msr = *FDC_MSR & (FDC_MSR_DIO | FDC_MSR_RQM);
|
|
||||||
if (msr == FDC_MSR_RQM) {
|
|
||||||
*FDC_DATA = x;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (msr == (FDC_MSR_DIO | FDC_MSR_RQM)) {
|
|
||||||
log(LOG_ERROR, "fdc_out: ready for input in output");
|
|
||||||
return ERR_GENERAL;
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
step += step;
|
*FDC_DATA = x;
|
||||||
fdc_delay(step);
|
return 0;
|
||||||
}
|
|
||||||
|
|
||||||
log(LOG_ERROR, "fdc_out: timeout");
|
|
||||||
return DEV_TIMEOUT;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Spin up the drive's spindle motor
|
* Spin up the drive's spindle motor
|
||||||
*/
|
*/
|
||||||
|
@ -312,9 +291,19 @@ short fdc_motor_on() {
|
||||||
while (wait_time > timers_jiffies()) ;
|
while (wait_time > timers_jiffies()) ;
|
||||||
// }
|
// }
|
||||||
|
|
||||||
|
short needs_handler = 0;
|
||||||
|
if (fdc_motor_off_time == 0) {
|
||||||
|
needs_handler = 1;
|
||||||
|
}
|
||||||
|
|
||||||
/* Set a new target time to shut off the motor */
|
/* Set a new target time to shut off the motor */
|
||||||
fdc_motor_off_time = timers_jiffies() + fdc_motor_timeout;
|
fdc_motor_off_time = timers_jiffies() + fdc_motor_timeout;
|
||||||
|
|
||||||
|
if (needs_handler) {
|
||||||
|
// Register the FDC motor watchdog to monitor for motor timeout
|
||||||
|
rtc_register_periodic(RTC_RATE_500ms, fdc_motor_watchdog);
|
||||||
|
}
|
||||||
|
|
||||||
/* Flag that the motor is on */
|
/* Flag that the motor is on */
|
||||||
fdc_stat |= FDC_STAT_MOTOR_ON;
|
fdc_stat |= FDC_STAT_MOTOR_ON;
|
||||||
|
|
||||||
|
@ -330,7 +319,7 @@ void fdc_motor_off() {
|
||||||
TRACE("fdc_motor_off");
|
TRACE("fdc_motor_off");
|
||||||
|
|
||||||
if ((*FDC_DOR & FDC_DOR_MOT0) == FDC_DOR_MOT0) {
|
if ((*FDC_DOR & FDC_DOR_MOT0) == FDC_DOR_MOT0) {
|
||||||
/* Motor is not on... turn it on without DMA or RESET */
|
/* Motor is not on... turn it off without DMA or RESET */
|
||||||
*FDC_DOR = FDC_DOR_NRESET;
|
*FDC_DOR = FDC_DOR_NRESET;
|
||||||
|
|
||||||
if (fdc_wait_rqm()) {
|
if (fdc_wait_rqm()) {
|
||||||
|
@ -342,9 +331,26 @@ void fdc_motor_off() {
|
||||||
/* Flag that the motor is off */
|
/* Flag that the motor is off */
|
||||||
fdc_stat &= ~FDC_STAT_MOTOR_ON;
|
fdc_stat &= ~FDC_STAT_MOTOR_ON;
|
||||||
|
|
||||||
|
// Reset the motor off time to 0, so we know we need to reinstall the watchdog later
|
||||||
|
fdc_motor_off_time = 0;
|
||||||
|
|
||||||
|
// Remove the FDC motor watchdog
|
||||||
|
rtc_register_periodic(0, 0);
|
||||||
|
|
||||||
ind_set(IND_FDC, IND_OFF);
|
ind_set(IND_FDC, IND_OFF);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check the current jiffy count and turn off the motor if we've reached the time the motor should be turned off
|
||||||
|
* This time gets reset every time we ask for the motor to be turned on
|
||||||
|
*/
|
||||||
|
void fdc_motor_watchdog() {
|
||||||
|
unsigned char flags = *RTC_FLAGS;
|
||||||
|
if (timers_jiffies() >= fdc_motor_off_time) {
|
||||||
|
fdc_motor_off();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Issue the SENSE INTERRUPT command
|
* Issue the SENSE INTERRUPT command
|
||||||
*
|
*
|
||||||
|
@ -453,11 +459,14 @@ short fdc_specify() {
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set head load time to maximum, and no DMA */
|
/* Set head load time to maximum, and no DMA */
|
||||||
|
unsigned char hlt_ndma = 0;
|
||||||
if (fdc_use_dma) {
|
if (fdc_use_dma) {
|
||||||
*FDC_DATA = 0x0B;
|
hlt_ndma = 0x0A;
|
||||||
} else {
|
} else {
|
||||||
*FDC_DATA = 0x0A;
|
hlt_ndma = 0x0B;
|
||||||
}
|
}
|
||||||
|
log_num(LOG_INFO, "FDC specify: ", hlt_ndma);
|
||||||
|
*FDC_DATA = hlt_ndma;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -503,8 +512,8 @@ short fdc_configure() {
|
||||||
return DEV_TIMEOUT;
|
return DEV_TIMEOUT;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Implied seek, enable FIFO, enable POLL, FIFO threshold = 8 bytes */
|
/* Implied seek, enable FIFO, enable POLL, FIFO threshold = 16 bytes */
|
||||||
*FDC_DATA = 0x47;
|
*FDC_DATA = 0x4F;
|
||||||
|
|
||||||
if (fdc_wait_write()) {
|
if (fdc_wait_write()) {
|
||||||
/* Timed out waiting for the FDC to be free */
|
/* Timed out waiting for the FDC to be free */
|
||||||
|
@ -571,8 +580,17 @@ short fdc_reset() {
|
||||||
/* Reset the controller */
|
/* Reset the controller */
|
||||||
*FDC_DOR = 0;
|
*FDC_DOR = 0;
|
||||||
target_time = timers_jiffies() + 2;
|
target_time = timers_jiffies() + 2;
|
||||||
while (target_time > timers_jiffies()) ;
|
while (target_time > timers_jiffies());
|
||||||
*FDC_DOR = FDC_DOR_NRESET;
|
|
||||||
|
unsigned char dor = 0;
|
||||||
|
if (fdc_use_dma) {
|
||||||
|
dor = FDC_DOR_NRESET | FDC_DOR_DMAEN;
|
||||||
|
} else {
|
||||||
|
dor = FDC_DOR_NRESET;
|
||||||
|
}
|
||||||
|
log_num(LOG_INFO, "FDC DOR: ", dor);
|
||||||
|
*FDC_DOR = dor;
|
||||||
|
|
||||||
|
|
||||||
/* Default precompensation, data rate for 1.44MB */
|
/* Default precompensation, data rate for 1.44MB */
|
||||||
*FDC_DSR = 0x80;
|
*FDC_DSR = 0x80;
|
||||||
|
@ -711,6 +729,8 @@ short fdc_command_dma(p_fdc_trans transaction) {
|
||||||
|
|
||||||
/* Result phase: read the result bytes */
|
/* Result phase: read the result bytes */
|
||||||
|
|
||||||
|
fdc_delay(30);
|
||||||
|
|
||||||
for (i = 0; i < transaction->result_count; i++) {
|
for (i = 0; i < transaction->result_count; i++) {
|
||||||
if ((result = fdc_in(&transaction->results[i])) < 0) {
|
if ((result = fdc_in(&transaction->results[i])) < 0) {
|
||||||
log(LOG_ERROR, "fdc_command: timeout getting results");
|
log(LOG_ERROR, "fdc_command: timeout getting results");
|
||||||
|
@ -775,16 +795,21 @@ short fdc_command(p_fdc_trans transaction) {
|
||||||
switch (transaction->direction) {
|
switch (transaction->direction) {
|
||||||
case FDC_TRANS_WRITE:
|
case FDC_TRANS_WRITE:
|
||||||
/* We're writing to the FDC */
|
/* We're writing to the FDC */
|
||||||
|
for (i = 0; (i < transaction->data_count); i++) {
|
||||||
|
if ((result = fdc_out(transaction->data[i])) < 0) {
|
||||||
|
log(LOG_ERROR, "fdc_command: timeout writing data");
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case FDC_TRANS_READ:
|
case FDC_TRANS_READ:
|
||||||
/* We're reading from the FDC */
|
/* We're reading from the FDC */
|
||||||
for (i = 0; (i < transaction->data_count) && ((*FDC_MSR & FDC_MSR_NONDMA) == FDC_MSR_NONDMA); i++) {
|
for (i = 0; (i < transaction->data_count); i++) {
|
||||||
if ((result = fdc_in(&transaction->data[i])) < 0) {
|
if ((result = fdc_in(&transaction->data[i])) < 0) {
|
||||||
log(LOG_ERROR, "fdc_command: timeout getting data");
|
log(LOG_ERROR, "fdc_command: timeout getting data");
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
sys_chan_write_b(0, '.');
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -794,6 +819,8 @@ short fdc_command(p_fdc_trans transaction) {
|
||||||
|
|
||||||
/* Result phase: read the result bytes */
|
/* Result phase: read the result bytes */
|
||||||
|
|
||||||
|
fdc_delay(2);
|
||||||
|
|
||||||
for (i = 0; i < transaction->result_count; i++) {
|
for (i = 0; i < transaction->result_count; i++) {
|
||||||
if ((result = fdc_in(&transaction->results[i])) < 0) {
|
if ((result = fdc_in(&transaction->results[i])) < 0) {
|
||||||
log(LOG_ERROR, "fdc_command: timeout getting results");
|
log(LOG_ERROR, "fdc_command: timeout getting results");
|
||||||
|
@ -892,7 +919,7 @@ short fdc_recalibrate() {
|
||||||
if ((result == 0)) {
|
if ((result == 0)) {
|
||||||
break;
|
break;
|
||||||
} else {
|
} else {
|
||||||
log_num(LOG_ERROR, "fdc_recalibrate: retry ", result);
|
log_num(LOG_INFO, "fdc_recalibrate: retry ", result);
|
||||||
}
|
}
|
||||||
fdc_init();
|
fdc_init();
|
||||||
trans.retries--;
|
trans.retries--;
|
||||||
|
@ -947,7 +974,7 @@ short fdc_sense_status() {
|
||||||
if ((result == 0)) {
|
if ((result == 0)) {
|
||||||
break;
|
break;
|
||||||
} else {
|
} else {
|
||||||
log_num(LOG_ERROR, "fdc_sense_status: retry ", result);
|
log_num(LOG_INFO, "fdc_sense_status: retry ", result);
|
||||||
}
|
}
|
||||||
fdc_init();
|
fdc_init();
|
||||||
trans.retries--;
|
trans.retries--;
|
||||||
|
@ -989,16 +1016,6 @@ short fdc_read(long lba, unsigned char * buffer, short size) {
|
||||||
|
|
||||||
fdc_motor_on();
|
fdc_motor_on();
|
||||||
|
|
||||||
/* Check if the disk has changed and recalibrate if it has */
|
|
||||||
// if (*FDC_DIR & 0x80) {
|
|
||||||
// fdc_stat = FDC_STAT_NOINIT;
|
|
||||||
// if (fdc_recalibrate()) {
|
|
||||||
// return DEV_NOMEDIA;
|
|
||||||
// } else {
|
|
||||||
// return ERR_MEDIA_CHANGE;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
trans.retries = 1; //FDC_DEFAULT_RETRIES;
|
trans.retries = 1; //FDC_DEFAULT_RETRIES;
|
||||||
trans.command = 0x40 | FDC_CMD_READ_DATA; /* MFM read command */
|
trans.command = 0x40 | FDC_CMD_READ_DATA; /* MFM read command */
|
||||||
trans.direction = FDC_TRANS_READ; /* We're going to read from the drive */
|
trans.direction = FDC_TRANS_READ; /* We're going to read from the drive */
|
||||||
|
@ -1020,13 +1037,16 @@ short fdc_read(long lba, unsigned char * buffer, short size) {
|
||||||
while (trans.retries > 0) {
|
while (trans.retries > 0) {
|
||||||
if (fdc_use_dma) {
|
if (fdc_use_dma) {
|
||||||
result = fdc_command_dma(&trans); /* Issue the transaction */
|
result = fdc_command_dma(&trans); /* Issue the transaction */
|
||||||
log_num(LOG_ERROR, "fdc_command_dma: ", result);
|
log_num(LOG_INFO, "fdc_command_dma: ", result);
|
||||||
} else {
|
} else {
|
||||||
result = fdc_cmd_asm(trans.command, trans.parameter_count, &trans.parameters, buffer, trans.result_count, &trans.results);
|
result = fdc_command(&trans);
|
||||||
log_num(LOG_ERROR, "fdc_cmd_asm: ", result);
|
log_num(LOG_INFO, "fdc_cmd: ", result);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((result == 0)) { //} && ((trans.results[0] & 0xC0) == 0)) {
|
if ((result == 0)) { //} && ((trans.results[0] & 0xC0) == 0)) {
|
||||||
|
sprintf(message, "fdc_read: success? ST0=%02X ST1=%02X ST2=%02X C=%02X H=%02X R=%02X N=%02X",
|
||||||
|
trans.results[0], trans.results[1], trans.results[2], trans.results[3], trans.results[4], trans.results[5], trans.results[6]);
|
||||||
|
log(LOG_ERROR, message);
|
||||||
return size;
|
return size;
|
||||||
} else {
|
} else {
|
||||||
sprintf(message, "fdc_read: retry ST0=%02X ST1=%02X ST2=%02X C=%02X H=%02X R=%02X N=%02X",
|
sprintf(message, "fdc_read: retry ST0=%02X ST1=%02X ST2=%02X C=%02X H=%02X R=%02X N=%02X",
|
||||||
|
@ -1056,7 +1076,63 @@ short fdc_read(long lba, unsigned char * buffer, short size) {
|
||||||
* number of bytes written, any negative number is an error code
|
* number of bytes written, any negative number is an error code
|
||||||
*/
|
*/
|
||||||
short fdc_write(long lba, const unsigned char * buffer, short size) {
|
short fdc_write(long lba, const unsigned char * buffer, short size) {
|
||||||
return 0;
|
t_fdc_trans trans;
|
||||||
|
unsigned char head, cylinder, sector;
|
||||||
|
short result, i;
|
||||||
|
char message[80];
|
||||||
|
|
||||||
|
TRACE("fdc_read");
|
||||||
|
|
||||||
|
lba_2_chs((unsigned long)lba, &cylinder, &head, §or);
|
||||||
|
|
||||||
|
fdc_motor_on();
|
||||||
|
|
||||||
|
trans.retries = 1; //FDC_DEFAULT_RETRIES;
|
||||||
|
trans.command = 0x40 | FDC_CMD_WRITE_DATA; /* MFM read command */
|
||||||
|
trans.direction = FDC_TRANS_WRITE; /* We're going to read from the drive */
|
||||||
|
trans.parameters[0] = (head == 1) ? 0x04 : 0x00; /* Set head and drive # */
|
||||||
|
trans.parameters[1] = cylinder & 0x00ff;
|
||||||
|
trans.parameters[2] = head & 0x0001;
|
||||||
|
trans.parameters[3] = sector & 0x00ff;
|
||||||
|
trans.parameters[4] = 2;
|
||||||
|
trans.parameters[5] = fdc_sectors_per_track;
|
||||||
|
trans.parameters[6] = 0x1B; /* GPL = 0x1B */
|
||||||
|
trans.parameters[7] = 0xFF; /* DTL = 0xFF */
|
||||||
|
trans.parameter_count = 8; /* Sending 8 parameter bytes */
|
||||||
|
|
||||||
|
trans.data = buffer; /* Transfer sector data to buffer */
|
||||||
|
trans.data_count = size;
|
||||||
|
|
||||||
|
trans.result_count = 7; /* Expect 7 result bytes */
|
||||||
|
|
||||||
|
while (trans.retries > 0) {
|
||||||
|
if (fdc_use_dma) {
|
||||||
|
result = fdc_command_dma(&trans); /* Issue the transaction */
|
||||||
|
log_num(LOG_INFO, "fdc_command_dma: ", result);
|
||||||
|
} else {
|
||||||
|
result = fdc_command(&trans);
|
||||||
|
log_num(LOG_INFO, "fdc_cmd: ", result);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((result == 0)) { //} && ((trans.results[0] & 0xC0) == 0)) {
|
||||||
|
sprintf(message, "fdc_write: success? ST0=%02X ST1=%02X ST2=%02X C=%02X H=%02X R=%02X N=%02X",
|
||||||
|
trans.results[0], trans.results[1], trans.results[2], trans.results[3], trans.results[4], trans.results[5], trans.results[6]);
|
||||||
|
log(LOG_ERROR, message);
|
||||||
|
return size;
|
||||||
|
} else {
|
||||||
|
sprintf(message, "fdc_write: retry ST0=%02X ST1=%02X ST2=%02X C=%02X H=%02X R=%02X N=%02X",
|
||||||
|
trans.results[0], trans.results[1], trans.results[2], trans.results[3], trans.results[4], trans.results[5], trans.results[6]);
|
||||||
|
log(LOG_ERROR, message);
|
||||||
|
sprintf(message, "fdc_write: retry EXTRA0=%02X EXTRA1=%02X",
|
||||||
|
trans.results[7], trans.results[8]);
|
||||||
|
log(LOG_ERROR, message);
|
||||||
|
}
|
||||||
|
fdc_init();
|
||||||
|
trans.retries--;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If we got here, we exhausted our retry attempts */
|
||||||
|
return DEV_CANNOT_WRITE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -71,6 +71,29 @@ void rtc_enable_ticks() {
|
||||||
int_enable(INT_RTC);
|
int_enable(INT_RTC);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register a function to be called periodically
|
||||||
|
*
|
||||||
|
* @param rate the rate at which the function should be called using the bq4802LY periodic rate values (0 to disable)
|
||||||
|
* @param handler a pointer to a function from void to void to be called
|
||||||
|
* @return 0 on success, any other number is an error
|
||||||
|
*/
|
||||||
|
short rtc_register_periodic(short rate, FUNC_V_2_V handler) {
|
||||||
|
if (rate == 0) {
|
||||||
|
int_disable(INT_RTC);
|
||||||
|
*RTC_RATES = 0;
|
||||||
|
*RTC_ENABLES &= ~RTC_PIE;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
int_register(INT_RTC, handler);
|
||||||
|
*RTC_RATES = rate;
|
||||||
|
unsigned char flags = *RTC_FLAGS;
|
||||||
|
*RTC_ENABLES = RTC_PIE;
|
||||||
|
int_enable(INT_RTC);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Set the time on the RTC
|
* Set the time on the RTC
|
||||||
*
|
*
|
||||||
|
|
|
@ -5,6 +5,8 @@
|
||||||
#ifndef __RTC_H
|
#ifndef __RTC_H
|
||||||
#define __RTC_H
|
#define __RTC_H
|
||||||
|
|
||||||
|
#include "types.h"
|
||||||
|
|
||||||
typedef struct s_time {
|
typedef struct s_time {
|
||||||
short year;
|
short year;
|
||||||
short month;
|
short month;
|
||||||
|
@ -54,4 +56,13 @@ extern void rtc_get_time(p_time time);
|
||||||
*/
|
*/
|
||||||
extern long rtc_get_jiffies();
|
extern long rtc_get_jiffies();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register a function to be called periodically
|
||||||
|
*
|
||||||
|
* @param rate the rate at which the function should be called using the bq4802LY periodic rate values (0 to disable)
|
||||||
|
* @param handler a pointer to a function from void to void to be called
|
||||||
|
* @return 0 on success, any other number is an error
|
||||||
|
*/
|
||||||
|
extern short rtc_register_periodic(short rate, FUNC_V_2_V handler);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
7300
src/foenixmcp.s68
7300
src/foenixmcp.s68
File diff suppressed because it is too large
Load diff
|
@ -55,7 +55,7 @@
|
||||||
#define RTC_RATE_976us 0x06
|
#define RTC_RATE_976us 0x06
|
||||||
#define RTC_RATE_4ms 0x08
|
#define RTC_RATE_4ms 0x08
|
||||||
#define RTC_RATE_15ms 0x0A
|
#define RTC_RATE_15ms 0x0A
|
||||||
|
#define RTC_RATE_500ms 0x0F
|
||||||
|
|
||||||
/* Enable bits */
|
/* Enable bits */
|
||||||
#define RTC_AIE 0x08
|
#define RTC_AIE 0x08
|
||||||
|
|
15641
src/mapfile
15641
src/mapfile
File diff suppressed because it is too large
Load diff
|
@ -6,7 +6,7 @@
|
||||||
#define __VERSION_H
|
#define __VERSION_H
|
||||||
|
|
||||||
#define VER_MAJOR 0
|
#define VER_MAJOR 0
|
||||||
#define VER_MINOR 53
|
#define VER_MINOR 60
|
||||||
#define VER_BUILD 8
|
#define VER_BUILD 2
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in a new issue