Low level PATA and SDC drivers

Added low level code for PATA and SDC devices.
This commit is contained in:
Peter Weingartner 2021-09-13 20:39:41 -04:00
parent a1cd5ddc24
commit ca23f971e7
15 changed files with 2207 additions and 349 deletions

434
src/dev/pata.c Normal file
View file

@ -0,0 +1,434 @@
/**
* Implementation of the PATA hard drive low level driver
*/
#include <string.h>
#include "log.h"
#include "errors.h"
#include "constants.h"
// #include "fatfs/ff.h"
// #include "dev/block.h"
#include "dev/pata.h"
#include "dev/text_screen_iii.h"
#include "pata_reg.h"
//
// Variables
//
short g_pata_error = 0; // Most recent error code received from the PATA drive
short g_pata_status = PATA_STAT_NOINIT; // Status of the PATA interface
//
// Code
//
//
// Wait until the PATA drive is no longer busy, or we've run out of time
//
// Returns:
// 0 on success (PATA drive is no longer busy), DEV_TIMEOUT on timeout
//
short pata_wait_not_busy() {
short count = MAX_TRIES_BUSY;
char status;
TRACE("pata_wait_not_busy");
do {
status = *PATA_CMD_STAT;
} while ((status & PATA_STAT_BSY) && (count-- > 0));
if (count == 0) {
return DEV_TIMEOUT;
} else {
return 0;
}
}
//
// Wait until the PATA drive is ready, or we've run out of time
//
// Returns:
// 0 on success (PATA drive is ready), DEV_TIMEOUT on timeout
//
short pata_wait_ready() {
short count = MAX_TRIES_BUSY;
char status;
TRACE("pata_wait_ready");
do {
status = *PATA_CMD_STAT;
} while (((status & PATA_STAT_DRDY) == 0) && (count-- > 0));
if (count == 0) {
return DEV_TIMEOUT;
} else {
return 0;
}
}
//
// Wait until the PATA drive is ready and not busy, or we've run out of time
//
// Returns:
// 0 on success (PATA drive is ready and not busy), DEV_TIMEOUT on timeout
//
short pata_wait_ready_not_busy() {
short count = MAX_TRIES_BUSY;
char status;
TRACE("pata_wait_ready_not_busy");
do {
status = *PATA_CMD_STAT;
} while (((status & (PATA_STAT_DRDY | PATA_STAT_BSY)) != PATA_STAT_DRDY) && (count-- > 0));
if (count == 0) {
return DEV_TIMEOUT;
} else {
return 0;
}
}
//
// Wait until the PATA drive is ready to transfer data, or we've run out of time
//
// Returns:
// 0 on success (PATA drive is ready to transfer data), DEV_TIMEOUT on timeout
//
short pata_wait_data_request() {
short count = MAX_TRIES_BUSY;
char status;
TRACE("pata_wait_data_request");
do {
status = *PATA_CMD_STAT;
} while (((status & PATA_STAT_DRQ) == 0) && (count-- > 0));
if (count == 0) {
return DEV_TIMEOUT;
} else {
return 0;
}
}
char g_buffer[512];
//
// Identify the PATA drive
//
// Inputs:
// drive_info = pointer to a s_drive_info
//
// Returns:
// 0 on success, any negative number is an error code
//
short pata_identity(p_drive_info drive_info) {
char * buffer;
unsigned short *wptr;
char * cptr;
short i;
short count;
TRACE("pata_identity");
*PATA_HEAD = 0xe0; // Drive 0, lBA enabled, Head 0
*PATA_SECT_CNT = 1;
*PATA_SECT_SRT = 0;
*PATA_CLDR_LO = 0;
*PATA_CLDR_HI = 0;
// Issue identity command
*PATA_CMD_STAT = PATA_CMD_IDENTITY;
if (pata_wait_not_busy()) {
return DEV_TIMEOUT;
}
// TODO: Wait ~500ns
if (pata_wait_ready_not_busy()) {
return DEV_TIMEOUT;
}
TRACE("copying data");
// Copy the data... let the compiler and the FPGA worry about endianess
wptr = (unsigned short *)g_buffer;
for (i = 0; i < 512; ) {
unsigned short data = *PATA_DATA_16;
g_buffer[i++] = data & 0xff;
g_buffer[i++] = (data >> 8) & 0xff;
}
TRACE("data copied");
wptr = (unsigned short *)buffer;
drive_info->flags = g_buffer[1] << 16 | g_buffer[0];
drive_info->lba_enabled = g_buffer[99] << 16 | g_buffer[98];
drive_info->l.lbaw.lba_default_lo = g_buffer[121] << 8 | g_buffer[120];
drive_info->l.lbaw.lba_default_hi = g_buffer[123] << 8 | g_buffer[122];
// Copy the serial number (need to swap chars)
memcpy(&(drive_info->serial_number), g_buffer + 22, sizeof(drive_info->serial_number));
// Copy the firmware version (need to swap chars)
memcpy(&(drive_info->firmware_version), g_buffer + 46, sizeof(drive_info->firmware_version));
// Copy the model name (need to swap chars)
memcpy(&(drive_info->model_name), g_buffer + 54, sizeof(drive_info->model_name));
return 0;
}
//
// Initialize the PATA hard drive
//
// Returns:
// 0 on success, any negative number is an error code
//
short pata_init() {
short result;
TRACE("pata_init");
// Issue intialize command
*PATA_CMD_STAT = PATA_CMD_INIT;
if (pata_wait_not_busy()) {
return DEV_TIMEOUT;
}
*PATA_HEAD = 0xA0; // Drive 0, lBA enabled, Head 0
*PATA_SECT_CNT = 1;
*PATA_SECT_SRT = 0;
*PATA_CLDR_LO = 0;
*PATA_CLDR_HI = 0;
if (pata_wait_ready_not_busy()) {
return DEV_TIMEOUT;
}
// Mark that the drive is initialized and present
g_pata_status = PATA_STAT_PRESENT;
return 0;
}
//
// Read a block from the PATA hard drive
//
// Inputs:
// lba = the logical block address of the block to read
// buffer = the buffer into which to copy the block data
// size = the size of the buffer.
//
// Returns:
// number of chars read, any negative number is an error code
//
short pata_read(long lba, char * buffer, short size) {
short i;
unsigned short *wptr;
TRACE("pata_read");
if (pata_wait_ready_not_busy()) {
return DEV_TIMEOUT;
}
*PATA_HEAD = ((lba >> 24) & 0x07) | 0xe0; // Upper 3 bits of LBA, Drive 0, LBA mode.
if (pata_wait_ready_not_busy()) {
return DEV_TIMEOUT;
}
*PATA_SECT_CNT = 1; // Read one sector (make this an option?)
*PATA_SECT_SRT = lba & 0xff; // Set the rest of the LBA
*PATA_CLDR_LO = (lba >> 8) & 0xff;
*PATA_CLDR_LO = (lba >> 16) & 0xff;
*PATA_CMD_STAT = PATA_CMD_READ_SECTOR; // Issue the READ command
// TODO: Wait ~500ns
if (pata_wait_ready_not_busy()) {
return DEV_TIMEOUT;
}
// Copy the data... let the compiler and the FPGA worry about endianess
for (i = 0, wptr = (unsigned short *)buffer; i < size; i += 2) {
*wptr++ = *PATA_DATA_16;
}
return i;
}
//
// Write a block to the PATA hard drive
//
// Inputs:
// lba = the logical block address of the block to write
// buffer = the buffer containing the data to write
// size = the size of the buffer.
//
// Returns:
// number of chars written, any negative number is an error code
//
short pata_write(long lba, const char * buffer, short size) {
short i;
unsigned short *wptr;
TRACE("pata_write");
if (pata_wait_ready_not_busy()) {
return DEV_TIMEOUT;
}
*PATA_HEAD = ((lba >> 24) & 0x07) | 0xe0; // Upper 3 bits of LBA, Drive 0, LBA mode.
if (pata_wait_ready_not_busy()) {
return DEV_TIMEOUT;
}
*PATA_SECT_CNT = 1; // Read one sector (make this an option?)
*PATA_SECT_SRT = lba & 0xff; // Set the rest of the LBA
*PATA_CLDR_LO = (lba >> 8) & 0xff;
*PATA_CLDR_LO = (lba >> 16) & 0xff;
*PATA_CMD_STAT = PATA_CMD_WRITE_SECTOR; // Issue the WRITE command
// TODO: Wait ~500ns
if (pata_wait_ready_not_busy()) {
return DEV_TIMEOUT;
}
// Copy the data... let the compiler and the FPGA worry about endianess
for (i = 0, wptr = (unsigned short *)buffer; i < size; i += 2) {
*PATA_DATA_16 = *wptr++;
}
return 0;
}
//
// Return the status of the PATA hard drive
//
// Returns:
// the status of the device
//
short pata_status() {
TRACE("pata_status");
return g_pata_status;
}
//
// Return any error code of the PATA hard drive
//
// Returns:
// the error code of the device
//
short pata_error() {
TRACE("pata_error");
return g_pata_error;
}
//
// Ensure that any pending writes to teh device have been completed
//
// Returns:
// 0 on success, any negative number is an error code
//
short pata_flush() {
TRACE("pata_flush");
return 0;
}
//
// Issue a control command to the PATA hard drive
//
// Inputs:
// command = the number of the command to send
// buffer = pointer to chars of additional data for the command
// size = the size of the buffer
//
// Returns:
// 0 on success, any negative number is an error code
//
short pata_ioctrl(short command, char * buffer, short size) {
short result;
long *p_long;
unsigned short *p_word;
long *p_lba_word;
t_drive_info drive_info;
p_drive_info p_info;
TRACE("pata_ioctrl");
switch (command) {
case PATA_GET_SECTOR_COUNT:
p_lba_word = (long *)buffer;
result = pata_identity(&drive_info);
if (result != 0) {
return result;
}
*p_lba_word = drive_info.l.lba_default;
break;
case PATA_GET_SECTOR_SIZE:
// Return the size of a sector... always 512
p_word = (unsigned short *)buffer;
*p_word = PATA_SECTOR_SIZE;
break;
case PATA_GET_BLOCK_SIZE:
// This isn't a flash device... return 1
p_long = (long *)buffer;
*p_long = 1;
break;
case PATA_GET_DRIVE_INFO:
p_info = (p_drive_info *)buffer;
result = pata_identity(p_info);
if (result != 0) {
return result;
}
break;
default:
return 0;
}
return 0;
}
//
// Install the PATA driver
//
// Returns:
// 0 on success, any negative number is an error code
//
short pata_install() {
// t_dev_block bdev;
//
// TRACE("pata_install");
//
// g_pata_error = 0;
// g_pata_status = PATA_STAT_NOINIT;
//
// // Check if drive is installed
// if ((*DIP_BOOTMODE & HD_INSTALLED) == 0) {
// bdev.number = BDEV_HDC;
// bdev.name = "HDD";
// bdev.init = pata_init;
// bdev.read = pata_read;
// bdev.write = pata_write;
// bdev.status = pata_status;
// bdev.flush = pata_flush;
// bdev.ioctrl = pata_ioctrl;
//
// g_pata_status = PATA_STAT_PRESENT & PATA_STAT_NOINIT;
//
// return bdev_register(&bdev);
// } else {
// return 0;
// }
return 0;
}

118
src/dev/pata.h Normal file
View file

@ -0,0 +1,118 @@
/**
* Low level driver for the PATA hard drive.
*/
#ifndef __PATA_H
#define __PATA_H
#include "types.h"
#define PATA_GET_SECTOR_COUNT 1
#define PATA_GET_SECTOR_SIZE 2
#define PATA_GET_BLOCK_SIZE 3
#define PATA_GET_DRIVE_INFO 4
#define PATA_SECTOR_SIZE 512 // Size of a block on the PATA
#define PATA_STAT_NOINIT 0x01 // PATA hard drive has not been initialized
#define PATA_STAT_PRESENT 0x02 // PATA hard drive is present
//
// Structures
//
typedef struct s_drive_info {
unsigned short flags;
char serial_number[18];
char firmware_version[6];
char model_name[38];
unsigned short lba_enabled;
union u1 {
struct s1 {
unsigned short lba_default_lo;
unsigned short lba_default_hi;
} lbaw;
unsigned long lba_default;
} l;
} t_drive_info, *p_drive_info;
//
// Install the PATA driver
//
// Returns:
// 0 on success, any negative number is an error code
//
extern short pata_install();
//
// Initialize the PATA hard drive
//
// Returns:
// 0 on success, any negative number is an error code
//
extern short pata_init();
//
// Read a block from the PATA hard drive
//
// Inputs:
// lba = the logical block address of the block to read
// buffer = the buffer into which to copy the block data
// size = the size of the buffer.
//
// Returns:
// number of chars read, any negative number is an error code
//
extern short pata_read(long lba, char * buffer, short size);
//
// Write a block to the PATA hard drive
//
// Inputs:
// lba = the logical block address of the block to write
// buffer = the buffer containing the data to write
// size = the size of the buffer.
//
// Returns:
// number of chars written, any negative number is an error code
//
extern short pata_write(long lba, const char * buffer, short size);
//
// Return the status of the PATA hard drive
//
// Returns:
// the status of the device
//
extern short pata_status();
//
// Return any error code of the PATA hard drive
//
// Returns:
// the error code of the device
//
extern short pata_error();
//
// Ensure that any pending writes to teh device have been completed
//
// Returns:
// 0 on success, any negative number is an error code
//
extern short pata_flush();
//
// Issue a control command to the PATA hard drive
//
// Inputs:
// command = the number of the command to send
// buffer = pointer to chars of additional data for the command
// size = the size of the buffer
//
// Returns:
// 0 on success, any negative number is an error code
//
extern short pata_ioctrl(short command, char * buffer, short size);
#endif

388
src/dev/sdc.c Normal file
View file

@ -0,0 +1,388 @@
/**
* Implementation of the SDC device driver
*/
#include "log.h"
// #include "fatfs/ff.h"
#include "constants.h"
#include "errors.h"
// #include "dev/block/block.h"
#include "sdc_reg.h"
#include "dev/sdc.h"
#include "dev/text_screen_iii.h"
unsigned char g_sdc_status = SDC_STAT_NOINIT;
unsigned char g_sdc_error = 0;
//
// Attempt to reset the SD controller
//
void sdc_reset() {
short delay;
TRACE("sdc_reset");
// NOTE: I haven't quite figured out reset on this block... setting the reset bit
// seems to leave the controller in an odd state.
// *SDC_CONTROL_REG = 1;
}
//
// Return true if there is an SD card in the slot
//
short sdc_detected() {
return 1;
// return (*SDCARD_STAT & SDC_DETECTED) != SDC_DETECTED;
}
//
// Return true if there is an SD card is protected
//
short sdc_protected() {
return 0;
// return (*SDCARD_STAT & SDC_WRITEPROT) != SDC_WRITEPROT;
}
//
// Turn the SDC LED on or off
//
// Inputs:
// is_on = if 0, turn the LED off, otherwise turn the LED on
//
void sdc_set_led(short is_on) {
// volatile unsigned char *gabe_control = (unsigned char *)GABE_MSTR_CTRL;
//
// if (is_on) {
// *gabe_control = *gabe_control | GABE_CTRL_SDC_LED;
// } else {
// *gabe_control = *gabe_control & ~GABE_CTRL_SDC_LED;
// }
}
//
// Wait for the SDC to complete its transaction
//
// Returns:
// 0 on success, DEV_TIMEOUT on timeout
//
short sdc_wait_busy() {
short retry_count = MAX_TRIES_BUSY;
unsigned char status;
do {
if (retry_count-- == 0) {
// If we have run out of tries, return a TIMEOUT error
return DEV_TIMEOUT;
}
status = *SDC_TRANS_STATUS_REG;
} while ((status & SDC_TRANS_BUSY) == SDC_TRANS_BUSY);
return 0;
}
//
// Initialize the SDC
//
// Returns:
// 0 on success, any negative number is an error code
//
short sdc_init() {
TRACE("sdc_init");
// Check for presence of the card
if (!sdc_detected()) {
// SDC_DETECTED is active 0... 1 means there is no card
g_sdc_status = SDC_STAT_NOINIT;
return DEV_NOMEDIA;
}
*SDC_TRANS_TYPE_REG = SDC_TRANS_INIT_SD; // Start the INIT_SD transaction
*SDC_TRANS_CONTROL_REG = SDC_TRANS_START;
if (sdc_wait_busy() == 0) { // Wait for it to complete
g_sdc_error = *SDC_TRANS_ERROR_REG; // Check for any error condition
if (g_sdc_error == 0) {
TRACE("sdc_init: SUCCESS");
g_sdc_status = 0; // Flag that the SD has been initialized
return 0;
} else {
TRACE("sdc_init: DEV_CANNOT_INIT");
g_sdc_status = SDC_STAT_NOINIT;
return DEV_CANNOT_INIT;
}
} else {
TRACE("sdc_init: DEV_TIMEOUT");
g_sdc_status = SDC_STAT_NOINIT;
return DEV_TIMEOUT;
}
}
//
// Read a block from the SDC
//
// Inputs:
// lba = the logical block address of the block to read
// buffer = the buffer into which to copy the block data
// size = the size of the buffer.
//
// Returns:
// number of bytes read, any negative number is an error code
//
short sdc_read(long lba, unsigned char * buffer, short size) {
long adjusted_lba;
TRACE("sdc_read");
// Check for presence of the card
if (!sdc_detected()) {
// SDC_DETECTED is active 0... 1 means there is no card
g_sdc_status = SDC_STAT_NOINIT;
return DEV_NOMEDIA;
}
sdc_set_led(1); // Turn on the SDC LED
// Send the LBA to the SDC
adjusted_lba = lba << 9;
*SDC_SD_ADDR_7_0_REG = adjusted_lba & 0xff;
*SDC_SD_ADDR_15_8_REG = (adjusted_lba >> 8) & 0xff;
*SDC_SD_ADDR_23_16_REG = (adjusted_lba >> 16) & 0xff;
*SDC_SD_ADDR_31_24_REG = (adjusted_lba >> 24) & 0xff;
// Start the READ transaction
*SDC_TRANS_TYPE_REG = SDC_TRANS_READ_BLK; // Set the transaction type to READ
*SDC_TRANS_CONTROL_REG = SDC_TRANS_START; // Start the transaction
if (sdc_wait_busy() == 0) { // Wait for the transaction to complete
g_sdc_error = *SDC_TRANS_ERROR_REG; // Check for errors
if (g_sdc_error != 0) {
sdc_set_led(0); // Turn off the SDC LED
return DEV_CANNOT_READ;
} else {
short count;
short i;
// Get the number of bytes to be read and make sure there is room
count = *SDC_RX_FIFO_DATA_CNT_HI << 8 | *SDC_RX_FIFO_DATA_CNT_LO;
if (count > size) {
return DEV_BOUNDS_ERR;
}
for (i = 0; i < count; i++) { // Fetch the bytes from the SDC
buffer[i] = *SDC_RX_FIFO_DATA_REG;
}
sdc_set_led(0); // Turn off the SDC LED
g_sdc_error = *SDC_TRANS_ERROR_REG; // Check for errors
if (g_sdc_error != 0) {
return DEV_CANNOT_READ;
} else {
// Success: return the byte count
return count;
}
}
} else {
sdc_set_led(0); // Turn off the SDC LED
return DEV_TIMEOUT;
}
}
//
// Write a block to the SDC
//
// Inputs:
// lba = the TRACEical block address of the block to write
// buffer = the buffer containing the data to write
// size = the size of the buffer.
//
// Returns:
// number of bytes written, any negative number is an error code
//
short sdc_write(long lba, const unsigned char * buffer, short size) {
long adjusted_lba;
short i;
TRACE("sdc_write");
// Check for presence of the card
if (!sdc_detected()) {
// SDC_DETECTED is active 0... 1 means there is no card
g_sdc_status = SDC_STAT_NOINIT;
return DEV_NOMEDIA;
}
sdc_set_led(1); // Turn on the SDC LED
if (size <= SDC_SECTOR_SIZE) {
// Copy the data to the SDC, if there isn't too much...
for (i = 0; i < size; i++) {
*SDC_TX_FIFO_DATA_REG = buffer[i];
}
if (size < SDC_SECTOR_SIZE) {
// If we copied less than a block's worth, pad the rest with 0s...
for (i = 0; i < SDC_SECTOR_SIZE - size; i++) {
*SDC_TX_FIFO_DATA_REG = 0;
}
}
} else {
// If size is too big, return a BOUNDS error
return DEV_BOUNDS_ERR;
}
// Send the LBA to the SDC
adjusted_lba = lba << 9;
*SDC_SD_ADDR_7_0_REG = adjusted_lba & 0xff;
*SDC_SD_ADDR_15_8_REG = (adjusted_lba >> 8) & 0xff;
*SDC_SD_ADDR_23_16_REG = (adjusted_lba >> 16) & 0xff;
*SDC_SD_ADDR_31_24_REG = (adjusted_lba >> 24) & 0xff;
// Start the WRITE transaction
*SDC_TRANS_TYPE_REG = SDC_TRANS_WRITE_BLK; // Set the transaction type to WRITE
*SDC_TRANS_CONTROL_REG = SDC_TRANS_START; // Start the transaction
if (sdc_wait_busy() == 0) { // Wait for the transaction to complete
g_sdc_error = *SDC_TRANS_ERROR_REG; // Check for errors
if (g_sdc_error != 0) {
sdc_set_led(0); // Turn off the SDC LED
return DEV_CANNOT_WRITE;
} else {
// Success: return the byte count
return size;
}
} else {
sdc_set_led(0); // Turn off the SDC LED
return DEV_TIMEOUT;
}
}
//
// Return the status of the SDC
//
// Returns:
// the status of the device
//
short sdc_status() {
short status = g_sdc_status;
if (sdc_detected()) {
// Add the PRESENT flag, if the card is inserted
status |= SDC_STAT_PRESENT;
}
if (sdc_protected()) {
// Add the PROTECTED flag, if the card is write-protected
status |= SDC_STAT_PROTECTED;
}
return status;
}
//
// Return any error code of the SDC
//
// Returns:
// the error code of the device
//
short sdc_error() {
return g_sdc_error;
}
//
// Ensure that any pending writes to teh device have been completed
//
// Returns:
// 0 on success, any negative number is an error code
//
short sdc_flush() {
return 0; // We don't buffer writes... always return success
}
//
// Return the count of sectors in this SD card
//
short sdc_sector_count() {
// TODO: implement this!
return 1000;
}
#define SDC_GET_SECTOR_COUNT 1
#define SDC_GET_SECTOR_SIZE 2
#define SDC_GET_BLOCK_SIZE 3
//
// Issue a control command to the device
//
// Inputs:
// command = the number of the command to send
// buffer = pointer to bytes of additional data for the command
// size = the size of the buffer
//
// Returns:
// 0 on success, any negative number is an error code
//
short sdc_ioctrl(short command, unsigned char * buffer, short size) {
unsigned long *p_dword;
unsigned short *p_word;
unsigned long *p_lba_word;
switch (command) {
case SDC_GET_SECTOR_COUNT:
p_lba_word = (unsigned long *)buffer;
*p_lba_word = sdc_sector_count();
break;
case SDC_GET_SECTOR_SIZE:
// Return the size of a sector... always 512
p_word = (unsigned short *)buffer;
*p_word = SDC_SECTOR_SIZE;
break;
case SDC_GET_BLOCK_SIZE:
// We don't know what the block size is... return 1
p_dword = (unsigned long *)buffer;
*p_dword = 1;
break;
default:
return 0;
}
}
//
// Install the SDC driver
//
short sdc_install() {
// t_dev_block dev; // bdev_register copies the data, so we'll allocate this on the stack
//
// TRACE("sdc_install");
//
// sdc_reset();
//
// dev.number = BDEV_SDC;
// dev.name = "SDC";
// dev.init = sdc_init;
// dev.read = sdc_read;
// dev.write = sdc_write;
// dev.flush = sdc_flush;
// dev.status = sdc_status;
// dev.ioctrl = sdc_ioctrl;
//
// return bdev_register(&dev);
return 0;
}

96
src/dev/sdc.h Normal file
View file

@ -0,0 +1,96 @@
/**
* Definitions support low level SDC device driver
*/
#ifndef __SDC_H
#define __SDC_H
#include "types.h"
//
// Definitions for GABE's internal SD card controller
//
#define SDC_SECTOR_SIZE 512 // Size of a block on the SDC
#define SDC_STAT_NOINIT 0x01 // SD has not been initialized
#define SDC_STAT_PRESENT 0x02 // SD is present
#define SDC_STAT_PROTECTED 0x04 // SD is write-protected
//
// Install the SDC driver
//
extern short sdc_install();
//
// Initialize the SDC
//
// Returns:
// 0 on success, any negative number is an error code
//
extern short sdc_init();
//
// Read a block from the SDC
//
// Inputs:
// lba = the logical block address of the block to read
// buffer = the buffer into which to copy the block data
// size = the size of the buffer.
//
// Returns:
// number of bytes read, any negative number is an error code
//
extern short sdc_read(long lba, unsigned char * buffer, short size);
//
// Write a block to the SDC
//
// Inputs:
// lba = the logical block address of the block to write
// buffer = the buffer containing the data to write
// size = the size of the buffer.
//
// Returns:
// number of bytes written, any negative number is an error code
//
extern short sdc_write(long lba, const unsigned char * buffer, short size);
//
// Return the status of the SDC
//
// Returns:
// the status of the device
//
extern short sdc_status();
//
// Return any error code of the SDC
//
// Returns:
// the error code of the device
//
extern short sdc_error();
//
// Ensure that any pending writes to teh device have been completed
//
// Returns:
// 0 on success, any negative number is an error code
//
extern short sdc_flush();
//
// Issue a control command to the device
//
// Inputs:
// command = the number of the command to send
// buffer = pointer to bytes of additional data for the command
// size = the size of the buffer
//
// Returns:
// 0 on success, any negative number is an error code
//
extern short sdc_ioctrl(short command, unsigned char * buffer, short size);
#endif

View file

@ -3,12 +3,13 @@
*/ */
#include <string.h> #include <string.h>
#include "sys_general.h" #include "sys_general.h"
#include "syscalls.h" #include "syscalls.h"
#include "dev/channel.h" #include "dev/channel.h"
#include "dev/console.h" #include "dev/console.h"
#include "dev/text_screen_iii.h" #include "dev/text_screen_iii.h"
#include "dev/pata.h"
#include "dev/sdc.h"
#include "log.h" #include "log.h"
/* /*
@ -16,31 +17,78 @@
*/ */
void initialize() { void initialize() {
text_init(); // Initialize the text channels text_init(); // Initialize the text channels
DEBUG("Foenix/MCP starting up...\n"); DEBUG("Foenix/MCP starting up...");
cdev_init_system(); // Initialize the channel device system cdev_init_system(); // Initialize the channel device system
DEBUG("Channel device system ready.\n"); DEBUG("Channel device system ready.");
if (con_install()) { if (con_install()) {
DEBUG("FAILED: Console installation.\n"); DEBUG("FAILED: Console installation.");
} else { } else {
DEBUG("Console installed.\n"); DEBUG("Console installed.");
} }
// At this point, we should be able to call into to console to print to the screens // At this point, we should be able to call into to console to print to the screens
// if (pata_init()) {
// DEBUG("Error initializing the PATA drive.");
// }
if (sdc_init()) {
DEBUG("Error initializing the PATA drive.");
}
} }
void print(short channel, char * message) { void print(short channel, char * message) {
syscall(SYS_CHAN_WRITE, channel, message, strlen(message)); syscall(SYS_CHAN_WRITE, channel, message, strlen(message));
} }
int main(int argc, char * argv[]) { void print_hex(short channel, unsigned short x) {
initialize(); char number[3];
short digit;
char hex_digits[] = "0123456789ABCDEF";
print(CDEV_CONSOLE, "Hello from Screen A!\n"); digit = (x & 0xf0) >> 4;
print(CDEV_EVID, "Hello from Screen B!\n"); number[0] = hex_digits[digit];
DEBUG("Stopping.\n"); digit = (x & 0x0f);
number[1] = hex_digits[digit];
/* Infinite loop... */
while (1) {}; number[2] = 0;
print(channel, number);
}
int main(int argc, char * argv[]) {
short x;
short result;
char buffer[512];
initialize();
for (x = 0; x < 512; x++) {
buffer[x] = 0;
}
print(CDEV_CONSOLE, "Hello from Screen A!\n");
print(CDEV_EVID, "Hello from Screen B!\n");
print(1, "Hard drive sector 0:\n")
result = sdc_read(0L, buffer, 512);
if (result > 0) {
for (x = 0; x < result; x++) {
if (x % 16 == 0) {
print(1, "\n");
}
print_hex(1, buffer[x]);
print(1, " ");
}
print(1, "\n");
} else if (result < 0) {
DEBUG("IDE returned an error.");
} else {
DEBUG("IDE returned nothing.");
}
DEBUG("Stopping.");
/* Infinite loop... */
while (1) {};
} }

263
src/foenixmcp.s68 Normal file
View file

@ -0,0 +1,263 @@
S0100000666F656E69786D63702E73363817
S22400000000020000000100000001002C0001002C0001002C0001002C0001002C0001002CCA
S2240000200001002C0001002C0001002C0001002C0001002C0001002C0001002C0001002C53
S2240000400001002C0001002C0001002C0001002C0001002C0001002C0001002C0001002C33
S2240000600001002C0001002C0001002C0001002C0001002C0001002C0001002C0001002C13
S2240000800001002C0001002C0001002C0001002C0001002C0001002C0001002C0001002CF3
S2240000A00001002C0001002C0001002C0001002C0001002C000100560001002C0001002CA9
S2240100004FF90002000041F900011F94203C0000061067104298598066FA41FA003A327C83
S22401002000B422884EB9000100F460FE4E7348E77F002E2F00382C2F00342A2F0030282F8F
S224010040002C262F0028242F0024222F00204E4D4CDF00FE4E752F072F062F052F042F037E
S2240100602F022F014EB9000105A84FEF001C4E7348E7203047F900011F6E203C00011F6E12
S224010080672674014AAB0004670C52822002E5884AB3080066F45382670E2002E5882473BA
S2240100A008004E92538266F22F2F00104EB90001002A584F4CDF0C044E754E7148E70030C2
S2240100C04AB900011F806626267900011F94700123C000011F80200B670C246B00044E9293
S2240100E02653200B66F42F2F000C6184584F4CDF0C004E7548E7003047F900011F7A203C77
S22401010000011F76670C4A936708245B4E924A9366F82F2F00102F2F00104EB9000102E420
S2240101202F0061984FEF000C4CDF0C004E7500004EB900011954487A00B04EB900010560F9
S2240101404EB900010634487A00BC4EB9000105604EB900010DBC504F4A40670E487A003209
S2240101604EB900010560584F600C487A00444EB900010560584F4EB9000115B84A40670C0D
S224010180487A00424EB900010560584F4E754E714641494C45443A20436F6E736F6C6520CD
S2240101A0696E7374616C6C6174696F6E2E004E71436F6E736F6C6520696E7374616C6C65EB
S2240101C0642E00004572726F7220696E697469616C697A696E67207468652050415441208B
S2240101E064726976652E0000466F656E69782F4D4350207374617274696E672075702E2E4C
S2240102002E004E714368616E6E656C206465766963652073797374656D2072656164792E7A
S22401022000004E7148E72020342F000E246F0010204A20084A1866FC908846802F002F0ADA
S224010240300248C02F00487800024EB90001002E4FEF00104CDF04044E754E714FEFFFE80F
S22401026048E73800382F002A362F002E41FA006243EF001222D822D822D822D812D8100327
S224010280C03C00F0C07C00FFC0BC0000FFFFE880340041EF00121F702000000C1003C03C0F
S2240102A0000F7400140041EF00121F702000000D422F000E41EF000C2F08300448C02F0046
S2240102C06100FF62504F4CDF001C4FEF00184E7530313233343536373839414243444546B5
S2240102E000004E714FEFFDFC48E730006100FE427400600A41EF000C423020005242B47C92
S22401030002006DF0487A011242A76100FF18487A0120487800016100FF0C487A012C487883
S22401032000016100FF004878020041EF00282F0842A74EB90001169436004FEF00246F64FF
S2240103407400604C300248C0487800102F004EB90001046A504F4A80660E487A00804878E9
S22401036000016100FEC0504F41EF000CD0C21010488048C02F00487800016100FEE0487A09
S2240103800060487800016100FE9C4FEF00105242B6426EB0487A004E487800016100FE868D
S2240103A0504F601E4A436C0E487A003E4EB900010560584F600C487A00484EB9000105601C
S2240103C0584F487A009C4EB900010560584F60FE70004CDF000C4FEF02044E750A004E7129
S2240103E020004E710A004E714944452072657475726E656420616E206572726F722E00008D
S2240104004944452072657475726E6564206E6F7468696E672E004E7148656C6C6F2066728B
S2240104206F6D2053637265656E2041210A004E7148656C6C6F2066726F6D20536372656535
S2240104406E2042210A004E714861726420647269766520736563746F7220303A0A004E7120
S22401046053746F7070696E672E004CEF000300044A816B0A4A806B12616220014E754481BF
S2240104804A806B10615620014E754480614E448120014E7544806144448120014E754CEF0D
S2240104A000030004613620014E754CEF000300044A806A1644804A816A084481611E44811E
S2240104C04E756118448044814E754A816A0E4481610A44804E754CEF000300042F02484198
S2240104E03401661E4840484148423400670484C130024840340084C1300248423202241F58
S2240105004E752F037610B27C00806404E1995143B27C08006404E9995943B27C20006404C4
S224010520E59955434A416B04E39953433400E6A848424242E6AA484380C1360030023403C8
S2240105404841C4C1908264065343D08164FE720032034843E7B84840C141261F241F4E751C
S22401056048E72020246F000C7400601841F228001010488048C02F0042A74EB900011EC42E
S224010580504F5282204A20084A1866FC90884680B08262D84878000A42A74EB900011EC4A5
S2240105A0504F4CDF04044E7548E73C002A2F0020282F0014262F001C242F0018200453807E
S2240105C067065380671E603A1003C0BC000000FF2F00300248C02F004EB900010ABC48C0BA
S2240105E0504F602C300548C02F0020432F08300248C02F004EB900010A3C48C04FEF000CBB
S224010600600E487A00144EB90001056070FF584F4CDF003C4E754E7173797363616C6C2009
S224010620756E6B6E6F776E2066756E6374696F6E0A00000048E7300072006046702E2400DB
S224010640260148424843C4C1C6C0C0C1D44348424242D08241F900011F9842700800702E0B
S2240106602400260148424843C4C1C6C0C0C1D44348424242D08241F900011F9842B0080223
S22401068052817008B0816EB47200604A70242400260148424843C4C1C6C0C0C1D443484279
S2240106A04242D08241F90001210831BCFFFF080070242400260148424843C4C1C6C0C0C187
S2240106C0D44348424242D08241F90001210831BCFFFF080252817010B0816EB042790001E6
S2240106E0210842790001210A33FC00010001212C33FC00010001212E4CDF000C4E754E712D
S22401070048E73830266F00183213B27C00086C6E300148C0742E2600280248434844C6C270
S224010720C8C0C0C2D64448434243D08341F900011F98D1C024483493256B00020002256B52
S22401074000060006256B000A000A256B000E000E256B00120012256B00160016256B001A1D
S224010760001A256B001E001E256B00260026256B00220022256B002A002A7000600270FEB9
S2240107804CDF0C1C4E754E7148E730007200606C70242400260148424843C4C1C6C0C0C161
S2240107A0D44348424242D08241F9000121084A7008006C4670242400260148424843C4C16B
S2240107C0C6C0C0C1D44348424242D08241F900012108318108007024240026014842484383
S2240107E0C4C1C6C0C0C1D44348424242D08241F900012108D1C02008600A52817010B081E5
S2240108006E8E70004CDF000C4E754E7148E73800322F0012300148C0742426002802484327
S2240108204844C6C2C8C0C0C2D64448434243D08341F900012108D1C020084CDF001C4E75F0
S224010840226F000432BCFFFF426900024E754E71514F48E73820342F001EB47C00086C385E
S224010860300248C0722E2600280148434844C6C1C8C0C0C1D64448434243D08341F90001EA
S2240108801F98D1C02448B452660C226A00062F4900144E91600270FE4CDF041C504F4E75AC
S2240108A048E73820246F001C322F0016226F0018B27C00106C70300148C0742426002802A1
S2240108C048434844C6C2C8C0C0C2D64448434243D08341F900012108D1C022882051B250DA
S2240108E0663E20510C68000800026C2E20513028000248C0742E2600280248434844C6C261
S224010900C8C0C0C2D64448434243D08341F900011F98D1C024887000600E70FE600A600401
S22401092070FE6004600270F64CDF041C4E754E714FEFFFF048E73820382F002E362F002676
S224010940246F002841EF00142F0841EF00142F08300348C02F006100FF4834004FEF000C50
S2240109606620300448C02F002F0A2F2F0018206F00202268000A2F4900264E914FEF000CC7
S224010980600230024CDF041C4FEF00104E754E714FEFFFF048E73820382F002E362F0026CE
S2240109A0246F002841EF00142F0841EF00142F08300348C02F006100FEE834004FEF000C51
S2240109C06620300448C02F002F0A2F2F0018206F00202268000E2F4900264E914FEF000C63
S2240109E0600230024CDF041C4FEF00104E754E714FEFFFF048E73000362F001E41EF000CF7
S224010A002F0841EF000C2F08300348C02F006100FE9034004FEF000C66162F2F0008206FDE
S224010A200010226800122F4900164E91584F600230024CDF000C4FEF00104E754FEFFFF0E7
S224010A4048E73820382F002E362F0026246F002841EF00142F0841EF00142F08300348C0FD
S224010A602F006100FE3C34004FEF000C6620300448C02F002F0A2F2F0018206F002022684F
S224010A8000162F4900264E914FEF000C600E487A00184EB9000105603002584F4CDF041C9A
S224010AA04FEF00104E754E716368616E5F7772697465206572726F720A004E714FEFFFF0FC
S224010AC048E73800182F0027362F002241EF00102F0841EF00102F08300348C02F006100FB
S224010AE0FDC034004FEF000C661C700010042F002F2F0010206F00182268001A2F49001E31
S224010B004E91504F600230024CDF001C4FEF00104E754E714FEFFFF048E73000362F001E97
S224010B2041EF000C2F0841EF000C2F08300348C02F006100FD6C34004FEF000C66162F2F3D
S224010B400008206F00102268001E2F4900164E91584F600230024CDF000C4FEF00104E7550
S224010B604FEFFFF048E73000362F001E41EF000C2F0841EF000C2F08300348C02F006100AF
S224010B80FD2034004FEF000C66162F2F0008206F0010226800222F4900164E91584F600211
S224010BA030024CDF000C4FEF00104E754FEFFFF048E73C003A2F002E282F0028362F00267C
S224010BC041EF00142F0841EF00142F08300348C02F006100FCCC34004FEF000C662030054D
S224010BE048C02F002F042F2F0018206F0020226800262F4900264E914FEF000C6002300255
S224010C004CDF003C4FEF00104E754E714FEFFFF048E73C203A2F0036382F002E362F002A1C
S224010C20246F003041EF00182F0841EF00182F08300348C02F006100FC6834004FEF000C40
S224010C406626300548C02F002F0A300448C02F002F2F0020206F00282268002A2F49002E63
S224010C604E914FEF0010600230024CDF043C4FEF00104E7570004E7548E72020142F001339
S224010C80246F000C1002488048C02F00302A000248C02F004EB900011EC47000504F4CDFE7
S224010CA004044E7570004E7548E73830382F0022266F001C246F0018760060222F0A61E43E
S224010CC03400584F6C043002601E4A426F0E300248C0C0BC000000FF17803800528330047D
S224010CE048C0B0836ED630034CDF0C1C4E754E7148E73830382F0022266F0018246F001CEB
S224010D007400604C2F0B619C3600584F6C043003604A4A436F3A10034A00760016004232B9
S224010D20280030035140670E55406702601442322800300260264A826F06538242322800D4
S224010D40600E1003220252821580180042322800300448C05380B0826EAA30024CDF0C1CED
S224010D604E754E7148E73830382F0022266F001C246F00187400602216332800660260221E
S224010D801003488048C02F00302A000248C02F004EB900011EC4504F5282300448C0B082DD
S224010DA06ED630024CDF0C1C4E754E71700C4E7570004E7570004E7570004E754FEFFFD0FD
S224010DC02F7C00010E98000242572F7C00010C7400062F7C00010CA8000A2F7C00010CF0DC
S224010DE0000E2F7C00010CA400122F7C00010D6400162F7C00010C78001A2F7C00010DB08B
S224010E0000222F7C00010DB400262F7C00010DAC001E2F7C00010DB8002A41D72F084EB9A3
S224010E20000107002F7C00010EA000063F7C000100042F7C00010C74000A2F7C00010CA8EE
S224010E40000E2F7C00010CF000122F7C00010CA400162F7C00010D64001A2F7C00010C78EB
S224010E60001E2F7C00010DB000262F7C00010DB4002A2F7C00010DAC00222F7C00010DB830
S224010E80002E41EF00042F084EB900010700504F4FEF00304E754E71434F4E534F4C450002
S224010EA0455649440000000048E73000343C2710487A003E4EB900010560584F163900C0DB
S224010EC0040E10034880C03C0080C07C00FFC0BC0000FFFF4A806708300253424A406EDC1A
S224010EE04A42660470FD600270004CDF000C4E75706174615F776169745F6E6F745F62751D
S224010F007379000048E73000343C2710487A003E4EB900010560584F163900C0040E100391
S224010F204880C03C0040C07C00FFC0BC0000FFFF4A806608300253424A406EDC4A42660429
S224010F4070FD600270004CDF000C4E75706174615F776169745F72656164790048E73000C5
S224010F60343C2710487A00424EB900010560584F163900C0040E10034880C03C00C0C07CB8
S224010F8000FFC0BC0000FFFF7240B2806708300253424A406EDA4A42660470FD60027000B1
S224010FA04CDF000C4E754E71706174615F776169745F72656164795F6E6F745F6275737972
S224010FC000004E7148E73000343C2710487A003E4EB900010560584F163900C0040E1003FE
S224010FE04880C03C0008C07C00FFC0BC0000FFFF4A806608300253424A406EDC4A426604A1
S22401100070FD600270004CDF000C4E75706174615F776169745F646174615F72657175655D
S2240110207374000048E73838246F001C487A02224EB90001056013FC00E000C0040C13FC54
S224011040000100C00404423900C00406423900C00408423900C0040A13FC00EC00C0040E1F
S2240110606100FE46584F4A40670670FD600001DA6100FEEA4A40670670FD600001CC487AE3
S22401108001E04EB90001056047F9000123487600584F6038383900C0040070003004C0BC46
S2240110A0000000FF3203524341F9000123481180100070003004E080C0BC000000FF320366
S2240110C0524341F90001234811801000B67C02006DC2487A019C4EB900010560264C103944
S2240110E000012349488048C07210E3A8123900012348488148C1808134801039000123AB4A
S224011100488048C07210E3A81239000123AA488148C18081354000401039000123C1488055
S22401112048C0E1881239000123C0488148C18081354000421039000123C3488048C0E18816
S2240111401239000123C2488148C1808141EA004231400002741243F90001235E41EA000234
S2240111602008B4BC0000001065307201C200670410D953822209C23C00016710B4BC0001BC
S2240111800000651610D9538266FA60187203C282948120D9598266FA34015342650610D918
S2240111A051CAFFFC740643F90001237641EA00142008B4BC0000001065307201C2006704A7
S2240111C010D953822209C23C00016710B4BC00010000651610D9538266FA60187203C2826F
S2240111E0948120D9598266FA34015342650610D951CAFFFC742643F90001237E41EA001AAF
S2240112002008B4BC0000001065307201C200670410D953822209C23C00016710B4BC00011B
S2240112200000651610D9538266FA60187203C282948120D9598266FA34015342650610D977
S22401124051CAFFFC7000584F4CDF1C1C4E754E71706174615F6964656E74697479004E7148
S224011260636F7079696E67206461746100004E716461746120636F7069656400487A0056B0
S2240112804EB900010560423900C0040E6100FC1A584F4A40670470FD603813FC00A000C007
S2240112A0040C13FC000100C00404423900C00406423900C00408423900C0040A6100FC9E70
S2240112C04A40670470FD600A33FC000200011F8870004E75706174615F696E6974004E71B8
S2240112E048E73830282F0018362F0022266F001C487A00A64EB9000105606100FC60584F71
S2240113004A40670670FD6000008A72182004E2A0C0BC0000000780BC000000E013C000C017
S224011320040C6100FC384A40670470FD606413FC000100C00404203C000000FFC08413C092
S22401134000C004062004E080C0BC000000FF13C000C0040872102004E2A0C0BC000000FF7C
S22401136013C000C0040813FC002100C0040E6100FBEC4A40670470FD60187400244B600C55
S224011380204A548A30B900C004005442B6426EF030024CDF0C1C4E75706174615F726561E1
S2240113A064004E7148E73830282F0018362F0022266F001C487A00A64EB900010560610090
S2240113C0FB9C584F4A40670670FD6000008A72182004E2A0C0BC0000000780BC000000E0AC
S2240113E013C000C0040C6100FB744A40670470FD606413FC000100C00404203C000000FF1B
S224011400C08413C000C004062004E080C0BC000000FF13C000C0040872102004E2A0C0BCA3
S224011420000000FF13C000C0040813FC003000C0040E6100FB284A40670470FD6018740025
S224011440244B600C204A548A33D000C004005442B6426EF070004CDF0C1C4E757061746184
S2240114605F77726974650000487A00124EB900010560303900011F88584F4E75706174617A
S2240114805F73746174757300487A00124EB900010560303900011F84584F4E7570617461E5
S2240114A05F6572726F720000487A000E4EB9000105607000584F4E75706174615F666C753A
S2240114C0736800004FEFFFA848E7303E362F007A246F007C487A006E4EB9000105603003EB
S2240114E05340584F670E534067265340672A5340672E60402A4A41EF002A2F086100FB26A4
S2240115003400584F6704300260302AAF006C6028284A38BC02006020264A70012680601809
S2240115202C4A2F0E6100FAFE3400584F67043002600860047000600270004CDF7C0C4FEF22
S22401154000584E75706174615F696F6374726C0070004E75487A000E4EB900010560584FC1
S2240115604E754E717364635F7265736574004E7170014E7570004E754E754E7148E7300020
S224011580323C2710300153414A40660470FD6020143900C0030470001002C03C0001C07C2B
S2240115A000FFC0BC0000FFFF7601B68067D670004CDF000C4E754E71487A00CE4EB9000101
S2240115C0056061AC584F4A40660C13FC000100011F8C70F8606813FC000100C0030213FC20
S2240115E0000100C0030361944A40663C13F900C0030500011F906616487A00464EB90001ED
S2240116000560423900011F8C7000584F6030487A00444EB90001056013FC000100011F8C62
S22401162070FC584F60186016487A00464EB90001056013FC000100011F8C70FD584F4E759B
S2240116407364635F696E69743A2053554343455353004E717364635F696E69743A204445D5
S224011660565F43414E4E4F545F494E4954004E717364635F696E69743A204445565F544918
S2240116804D454F5554004E717364635F696E697400004E7148E73E203C2F00262A2F001C5C
S2240116A0246F0020487A01024EB9000105606100FEC0584F4A40660E13FC000100011F8CBF
S2240116C070F8600000DC487800016100FEAC70092805E1AC203C000000FFC08413C000C02F
S2240116E003072004E080C0BC000000FF13C000C0030872102004E2A0C0BC000000FF13C0C7
S22401170000C0030972182004E2A0C0BC000000FF13C000C0030A13FC000200C0030213FCC7
S224011720000100C003036100FE54584F4A40666613F900C0030500011F90670C42A76100EB
S224011740FE3870FB584F60587000103900C00312E1887200123900C0031380813600BC43C3
S2240117606C0470F9603A7400600A15B900C0031020005242B6426EF242A76100FDFC13F916
S22401178000C0030500011F90584F670470FB60103003600C600A42A76100FDDE70FD584F9C
S2240117A04CDF047C4E754E717364635F7265616400004E7148E73C202A2F0018362F00227F
S2240117C0246F001C487A00FE4EB9000105606100FDA0584F4A40660E13FC000100011F8CC8
S2240117E070F8600000DA487800016100FD8C584FB67C02006E3A7400600A13F2200000C050
S22401180003205242B6426EF2B67C02006C2074006008423900C003205242300248C03203B6
S22401182048C14481D2BC00000200B2806EE4600670F96000008A70092805E1AC203C000078
S22401184000FFC08413C000C003072004E080C0BC000000FF13C000C0030872102004E2A0DD
S224011860C0BC000000FF13C000C0030972182004E2A0C0BC000000FF13C000C0030A13FCEE
S224011880000300C0030213FC000100C003036100FCEC4A40661E13F900C0030500011F90C9
S2240118A0670C42A76100FCD270FA584F60103003600C600A42A76100FCC070FD584F4CDFC8
S2240118C0043C4E757364635F7772697465004E712F027400143900011F8C6100FC944A4063
S2240118E06704847C00026100FC8C4A406704847C00043002241F4E757000103900011F90F2
S2240119004E754E7170004E75303C03E84E754E7148E7203C342F001A246F001C30025340B7
S224011920670A5340671253406716601C2A4A61D8320048C12A816012284A38BC0200600AC1
S224011940264A70012680600270004CDF3C044E7570004E7548E7003045F90001254847F97C
S2240119600001257624BC00C40000257C00C600000004257C00C680000008257C00C4001052
S224011980000C257C00C400140010257C00C400040014205270012080206A0014429042A753
S2240119A0610001DA42A74878000F42A76100034242A7610003A042A742A742A76100010A8A
S2240119C026BC00C80000277C00CA00000004277C00CA80000008277C00C80010000C277CC7
S2240119E000C800140010277C00C800040014205370012080206B001442904878000161005B
S224011A00017C42A74878000F48780001610002E2487800016100033E42A742A7487800018F
S224011A20610000A670004FEF00404CDF0C004E7548E73F003C2F002E3A2F002A182F0027A9
S224011A40362F0022342F001EB47C00026C74300248C0722E2F022E00240148474842CEC160
S224011A60C4C0C0C1DE4248474247D087241F41F900012548D1C0224810034A00C07C00FF4E
S224011A80C0BC0000FFFF7218E3A81204488148C17E10EFA980811205C23C0002C27C00FF4E
S224011AA0C2BC0000FFFFD28180811206C23C0001C27C00FFC2BC0000FFFF80812069000CEA
S224011AC020804CDF00FC4E7548E73F203A2F0022362F0026342F002ABA7C00026C0000960B
S224011AE0300548C0722E2C002E0148464847CCC1CEC0C0C1DC4748464246D08641F9000125
S224011B002548D1C0244870003003322A001C48C1B2806E047600524270003002322A001E67
S224011B2048C1B2806E14302A001E53403400300548C02F006100029A584F35430020354284
S224011B400022700030027210E3A8720032038081206A001020803002C1EA00183800D84384
S224011B60206A0004D0C425480024206A0008D0C4254800284CDF04FC4E754E714FEFFFEC1B
S224011B8048E73F200C6F000200366C00015874007A007C00302F003648C0722E2F022F032F
S224011BA02400260148424843C4C1C6C0C0C1D44348424242D082261F241F41F9000125488C
S224011BC0D1C02448206A001424102052203C00000400C0903A00205230280002C07C0300C9
S224011BE0C0BC0000FFFFE0883C003006907C0000670E53406718534067225340672C603620
S224011C00357C00500018357C003C001A6028357C00640018357C004B001A601A357C008028
S224011C200018357C0060001A600C357C00500018357C0032001A4A45672441EA001830103C
S224011C4048C022006C025281E281308141EA001A301048C022006C025281E2813081356A5C
S224011C60001A001E356A0018001C3002C03C0001C07C00FFC0BC0000FFFF67683002C07C32
S224011C803F00C0BC0000FFFFE0883E00703F4840C0827210E2A83F40002A300748C04A80A8
S224011CA06C025680E4803600302F002A48C04A806C025680E48038004A45671C300348C0B8
S224011CC022006C025281E2813601300448C022006C025281E281380141EA001C975041EA6D
S224011CE0001E99504CDF04FC4FEF00144E754E7148E73E00382F0022362F001E342F001AE2
S224011D00B47C00026C48300248C0722E2A002C0148454846CAC1CCC0C0C1DA4648454245BF
S224011D20D08541F900012548D1C022481003C03C000FC07C00FFC0BC0000FFFFE98832042B
S224011D4048C1C2BC0000000F80811340002C4CDF007C4E7548E73C20362F001AB67C0002BF
S224011D606C66300348C0722E28002A0148444845C8C1CAC0C0C1D84548444244D08441F9F3
S224011D8000012548D1C0244874006016206A000411BC00202800226A000813AA002C2800A0
S224011DA05282302A001848C0322A001A48C128002A0148444845C8C1CAC0C0C1D8454844A7
S224011DC04244D084B0826EC44CDF043C4E754E714FEFFFE448E73F3E0C6F0002004E6C00CE
S224011DE000D8302F004E48C0722E2F022F032400260148424843C4C1C6C0C0C1D4434842C0
S224011E004242D082261F241F41F900012548D1C02C487600604C3003C1EE001838007001EC
S224011E20D043C1EE00183A00246E0004D4C4266E0008D6C4286E0004D8C52A6E0008DAC5AE
S224011E4074006016204C528C224A528A1290204D528D224B528B12905242B46E00186DE407
S224011E605243300348C0322E001E48C15381B2806EA4302E001E5340C1EE00183E00226E49
S224011E800004D2C72F490036226E0008D2C72F49003A1C2E002C74006018206F003652AFE6
S224011EA0003610BC0020206F003A52AF003A10865242B46E00186DE24CDF7CFC4FEF001C46
S224011EC04E754E7148E73C30162F0023342F001EB47C00026C00008A300248C0722E2800CC
S224011EE02A0148444845C8C1CAC0C0C1D84548444244D08441F900012548D1C026481003C7
S224011F00903C000A67065700671E601E302B002248C052802F0042A7300248C02F006100E5
S224011F20FBA84FEF000C6038603641EB002422505290128343EB00282451529114AB002CAE
S224011F40302B002248C02F00302B002048C052802F00300248C02F006100FB6E4FEF000CC6
S212011F604CDF0C3C4E754E71302F00064E7550
S20C011F6E000000000000000065
S20C011F7600000000000000005D
S215011F80000000000000000000010000010000000048
S804000000FB

View file

@ -0,0 +1,127 @@
/*
* Definitions to access the PATA port on the A2560K
*/
#ifndef __PATA_A2560K_H
#define __PATA_A2560K_H
#define PATA_DATA_16 ((volatile unsigned short *)0x00C00400)
#define PATA_DATA_8 ((volatile unsigned char *)0x00C00400)
#define PATA_ERROR ((volatile unsigned char *)0x00C00402)
#define PATA_ERR_AMNF 0x01 // Error: Address mark not found
#define PATA_ERR_TKZNF 0x02 // Error: Track 0 not found
#define PATA_ERR_ABRT 0x04 // Error: Aborted command
#define PATA_ERR_MCR 0x08 // Error: Media change request
#define PATA_ERR_IDNF 0x10 // Error: ID not found
#define PATA_ERR_MC 0x20 // Error: Media change
#define PATA_ERR_UNC 0x40 // Error: Uncorrectable data error
#define PATA_ERR_BBK 0x80 // Error: Bad block detected
#define PATA_SECT_CNT ((volatile unsigned char *)0x00C00404)
#define PATA_SECT_SRT ((volatile unsigned char *)0x00C00406)
#define PATA_CLDR_LO ((volatile unsigned char *)0x00C00408)
#define PATA_CLDR_HI ((volatile unsigned char *)0x00C0040A)
#define PATA_HEAD ((volatile unsigned char *)0x00C0040C)
#define PATA_CMD_STAT ((volatile unsigned char *)0x00C0040E)
#define PATA_STAT_BSY 0x80 // BSY (Busy) is set whenever the device has control of the command Block Registers.
#define PATA_STAT_DRDY 0x40 // DRDY (Device Ready) is set to indicate that the device is capable of accepting all command codes.
#define PATA_STAT_DF 0x20 // DF (Device Fault) indicates a device fault error has been detected.
#define PATA_STAT_DSC 0x10 // DSC (Device Seek Complete) indicates that the device heads are settled over a track.
#define PATA_STAT_DRQ 0x08 // DRQ (Data Request) indicates that the device is ready to transfer a unsigned short or char of data between
// the host and the device.
#define PATA_STAT_CORR 0x04 // CORR (Corrected Data) is used to indicate a correctable data error.
#define PATA_STAT_IDX 0x02 // Vendor specific bit
#define PATA_STAT_ERR 0x01 // ERR (Error) indicates that an error occurred during execution of the previous command.
#define PATA_CMD_INIT 0x00
#define PATA_CMD_READ_SECTOR 0x21
#define PATA_CMD_WRITE_SECTOR 0x30
#define PATA_CMD_IDENTITY 0xEC
/*
* - BSY (Busy) is set whenever the device has control of the command
* Block Registers. When the BSY bit is equal to one, a write to a
* command block register by the host shall be ignored by the
* device.
*
* The device shall not change the state of the DRQ bit unless the
* BSY bit is equal to one. When the last block of a PIO data in
* command has been transferred by the host, then the DRQ bit is
* cleared without the BSY bit being set.
*
* When the BSY bit equals zero, the device may only change the IDX,
* DRDY, DF, DSC, and CORR bits in the Status register and the Data
* register. None of the other command block registers nor other
* bits within the Status register shall be changed by the device.
*
* NOTE - BIOSs and software device drivers that sample status as
* soon as the BSY bit is cleared to zero may not detect the
* assertion of the CORR bit by the device. After the host has
* written the Command register either the BSY bit shall be set, or
* if the BSY bit is cleared, the DRQ bit shall be set, until
* command completion.
*
* NOTE - The BSY bit is set and then cleared so quickly, that host
* detection of the BSY bit being set is not certain.
*
* The BSY bit shall be set by the device under the following
* circumstances:
* a) within 400 ns after either the negation of RESET- or the
* setting of the SRST bit in the Device Control register;
* b) within 400 ns after writing the Command register if the DRQ
* bit is not set;
* c) between blocks of a data transfer during PIO data in
* commands if the DRQ bit is not set;
* d) after the transfer of a data block during PIO data out
* commands if the DRQ bit is not set;
* e) during the data transfer of DMA commands if the DRQ bit is
* not set.
*
* The device shall not set the BSY bit at any other time.
*
* - DRDY (Device Ready) is set to indicate that the device is capable
* of accepting all command codes. This bit shall be cleared at
* power on. Devices that implement the power management features
* shall maintain the DRDY bit equal to one when they are in the
* Idle or Standby power modes. When the state of the DRDY bit
* changes, it shall not change again until after the host reads the
* status register.
*
* When the DRDY bit is equal to zero, a device responds as follows:
* a) the device shall accept and attempt to execute the EXECUTE
* DEVICE DIAGNOSTIC and INITIALIZE DEVICE PARAMETERS commands;
* b) If a device accepts commands other than EXECUTE DEVICE
* DIAGNOSTIC and INITIALIZE DEVICE PARAMETERS during the time the
* DRDY bit is equal to zero, the results are vendor specific.
*
* - DF (Device Fault) indicates a device fault error has been
* detected. The internal status or internal conditions that causes
* this error to be indicated is vendor specific.
*
* - DSC (Device Seek Complete) indicates that the device heads are
* settled over a track. When an error occurs, this bit shall not be
* changed until the Status register is read by the host, at which
* time the bit again indicates the current Seek Complete status.
*
* - DRQ (Data Request) indicates that the device is ready to transfer
* a unsigned short or char of data between the host and the device.
*
* - CORR (Corrected Data) is used to indicate a correctable data
* error. The definition of what constitutes a correctable error is
* vendor specific. This condition does not terminate a data
* transfer.
*
* - IDX (Index) is vendor specific.
*
* - ERR (Error) indicates that an error occurred during execution of
* the previous command. The bits in the Error register have
* additional information regarding the cause of the error. Once the
* device has set the error bit, the device shall not change the
* contents of the following items until a new command has been
* accepted, the SRST bit is set to one, or RESET- is asserted: the
* ERR bit in the Status register.
*/
#endif

View file

@ -0,0 +1,55 @@
/*
* Definitions for access to the SDC controller
*/
#ifndef __SDC_A2560K_H
#define __SDC_A2560K_H
// SDC_TRANS_TYPE_REG
#define SDC_TRANS_DIRECT 0x00 // 00 = Direct Access
#define SDC_TRANS_INIT_SD 0x01 // 01 = Init SD
#define SDC_TRANS_READ_BLK 0x02 // 10 = RW_READ_BLOCK (512 Bytes)
#define SDC_TRANS_WRITE_BLK 0x03 // 11 = RW_WRITE_SD_BLOCK
// SDC_TRANS_CONTROL_REG
#define SDC_TRANS_START 0x01
// SDC_TRANS_STATUS_REG
#define SDC_TRANS_BUSY 0x01 // 1= Transaction Busy
// SDC_TRANS_ERROR_REG
#define SDC_TRANS_INIT_NO_ERR 0x00 // Init Error Report [1:0]
#define SDC_TRANS_INIT_CMD0_ERR 0x01
#define SDC_TRANS_INIT_CMD1_ERR 0x02
#define SDC_TRANS_RD_NO_ERR 0x00 // Read Error Report [3:2]
#define SDC_TRANS_RD_CMD_ERR 0x04
#define SDC_TRANS_RD_TOKEN_ERR 0x08
#define SDC_TRANS_WR_NO_ERR 0x00 // Write Report Error [5:4]
#define SDC_TRANS_WR_CMD_ERR 0x10
#define SDC_TRANS_WR_DATA_ERR 0x20
#define SDC_TRANS_WR_BUSY_ERR 0x30
#define SDC_VERSION_REG ((unsigned char *)0x00C00300)
#define SDC_CONTROL_REG ((unsigned char *)0x00C00301)
#define SDC_TRANS_TYPE_REG ((unsigned char *)0x00C00302)
#define SDC_TRANS_CONTROL_REG ((unsigned char *)0x00C00303)
#define SDC_TRANS_STATUS_REG ((unsigned char *)0x00C00304)
#define SDC_TRANS_ERROR_REG ((unsigned char *)0x00C00305)
#define SDC_DIRECT_ACCESS_REG ((unsigned char *)0x00C00306)
#define SDC_SD_ADDR_7_0_REG ((unsigned char *)0x00C00307)
#define SDC_SD_ADDR_15_8_REG ((unsigned char *)0x00C00308)
#define SDC_SD_ADDR_23_16_REG ((unsigned char *)0x00C00309)
#define SDC_SD_ADDR_31_24_REG ((unsigned char *)0x00C0030A)
#define SDC_SPI_CLK_DEL_REG ((unsigned char *)0x00C0030B)
#define SDC_RX_FIFO_DATA_REG ((unsigned char *)0x00C00310)
#define SDC_RX_FIFO_DATA_CNT_HI ((unsigned char *)0x00C00312)
#define SDC_RX_FIFO_DATA_CNT_LO ((unsigned char *)0x00C00313)
#define SDC_RX_FIFO_CTRL_REG ((unsigned char *)0x00C00314)
#define SDC_TX_FIFO_DATA_REG ((unsigned char *)0x00C00320)
#define SDC_TX_FIFO_CTRL_REG ((unsigned char *)0x00C00324)
#endif

19
src/include/pata_reg.h Normal file
View file

@ -0,0 +1,19 @@
/*
* Include file to access the PATA port on the Foenix machine
*/
#ifndef __PATA_REG_H
#define __PATA_REG_H
#include "types.h"
// #if SYSTEM == A2560K
// /* PATA registers for the A2560K */
#include "A2560K/PATA_a2560k.h"
// #elif SYSTEM == C256_FMX || SYSTEM == C256_U || SYSTEM == C256_U_PLUS
// /* VICKY registers for the C256 FMX, U, and U+ */
// #include "FMX/vicky_general.h"
// #endif
#endif

19
src/include/sdc_reg.h Normal file
View file

@ -0,0 +1,19 @@
/*
* Include file to access the SDC port on the Foenix machine
*/
#ifndef __SDC_REG_H
#define __SDC_REG_H
#include "types.h"
// #if SYSTEM == A2560K
// /* PATA registers for the A2560K */
#include "A2560K/sdc_a2560k.h"
// #elif SYSTEM == C256_FMX || SYSTEM == C256_U || SYSTEM == C256_U_PLUS
// /* VICKY registers for the C256 FMX, U, and U+ */
// #include "FMX/vicky_general.h"
// #endif
#endif

View file

@ -2,6 +2,7 @@
* A logging utility * A logging utility
*/ */
#include <string.h>
#include "log.h" #include "log.h"
#include "dev/text_screen_iii.h" #include "dev/text_screen_iii.h"
@ -13,4 +14,5 @@ void DEBUG(char * message) {
for (i = 0; i < strlen(message); i++) { for (i = 0; i < strlen(message); i++) {
text_put_raw(0, message[i]); text_put_raw(0, message[i]);
} }
} text_put_raw(0, '\n');
}

View file

@ -10,4 +10,6 @@
*/ */
extern void DEBUG(char * message); extern void DEBUG(char * message);
#endif #define TRACE(msg) DEBUG(msg);
#endif

View file

@ -1,6 +1,6 @@
/** /**
* Implementation of 68000 specific syscall routines. * Implementation of 68000 specific syscall routines.
* *
* NOTE: these routines are not called directly but are instead called through TRAP#13 * NOTE: these routines are not called directly but are instead called through TRAP#13
*/ */
@ -15,15 +15,13 @@
int32_t syscall_dispatch(int32_t function, int32_t param0, int32_t param1, int32_t param2, int32_t param3, int32_t param4, int32_t param5) { int32_t syscall_dispatch(int32_t function, int32_t param0, int32_t param1, int32_t param2, int32_t param3, int32_t param4, int32_t param5) {
switch (function) { switch (function) {
case SYS_CHAN_WRITE_B: case SYS_CHAN_WRITE_B:
DEBUG("SYS_CHAN_WRITE_B\n");
return chan_write_b((short)param0, (uint8_t)param1); return chan_write_b((short)param0, (uint8_t)param1);
case SYS_CHAN_WRITE: case SYS_CHAN_WRITE:
DEBUG("SYS_CHAN_WRITE_B\n");
return chan_write((short)param0, (const uint8_t *)param1, (short)param2); return chan_write((short)param0, (const uint8_t *)param1, (short)param2);
default: default:
DEBUG("syscall unknown function\n"); DEBUG("syscall unknown function\n");
return -1; return -1;
} }
} }

File diff suppressed because it is too large Load diff

View file

@ -1,5 +1,5 @@
-cc=vbccm68k -quiet %s -o= %s %s -O=%ld -I..\vbcc\targets\m68k-foenix\include -cc=vbccm68k -quiet %s -o= %s %s -O=%ld -ID:\projects\FoenixMCP\vbcc\targets\m68k-foenix\include
-ccv=vbccm68k %s -o= %s %s -O=%ld -I..\vbcc\targets\m68k-foenix\include -ccv=vbccm68k %s -o= %s %s -O=%ld -ID:\projects\FoenixMCP\vbcc\targets\m68k-foenix\include
-as=vasmm68k_mot -quiet -Fvobj -nowarn=62 %s -o %s -as=vasmm68k_mot -quiet -Fvobj -nowarn=62 %s -o %s
-asv=vasmm68k_mot -Fvobj -nowarn=62 %s -o %s -asv=vasmm68k_mot -Fvobj -nowarn=62 %s -o %s
-rm=del %s -rm=del %s