/*
|
/*
|
* main.c -- show partitions on a disk
|
* main.c -- show partitions on a disk
|
*/
|
*/
|
|
|
|
|
#include "types.h"
|
#include "types.h"
|
#include "stdarg.h"
|
#include "stdarg.h"
|
#include "iolib.h"
|
#include "iolib.h"
|
#include "start.h"
|
#include "start.h"
|
#include "idedsk.h"
|
#include "idedsk.h"
|
|
|
|
|
#define NPE (SECTOR_SIZE / sizeof(PartEntry))
|
#define NPE (SECTOR_SIZE / sizeof(PartEntry))
|
#define DESCR_SIZE 20
|
#define DESCR_SIZE 20
|
|
|
|
|
typedef struct {
|
typedef struct {
|
unsigned long type;
|
unsigned long type;
|
unsigned long start;
|
unsigned long start;
|
unsigned long size;
|
unsigned long size;
|
char descr[DESCR_SIZE];
|
char descr[DESCR_SIZE];
|
} PartEntry;
|
} PartEntry;
|
|
|
PartEntry ptr[NPE];
|
PartEntry ptr[NPE];
|
|
|
|
|
/**************************************************************/
|
/**************************************************************/
|
|
|
|
|
void error(char *fmt, ...) {
|
void error(char *fmt, ...) {
|
va_list ap;
|
va_list ap;
|
|
|
va_start(ap, fmt);
|
va_start(ap, fmt);
|
printf("Error: ");
|
printf("Error: ");
|
vprintf(fmt, ap);
|
vprintf(fmt, ap);
|
printf(", halting...\n");
|
printf(", halting...\n");
|
va_end(ap);
|
va_end(ap);
|
while (1) ;
|
while (1) ;
|
}
|
}
|
|
|
|
|
/**************************************************************/
|
/**************************************************************/
|
|
|
|
|
unsigned long getNumber(unsigned char *p) {
|
unsigned long getNumber(unsigned char *p) {
|
return (unsigned long) *(p + 0) << 24 |
|
return (unsigned long) *(p + 0) << 24 |
|
(unsigned long) *(p + 1) << 16 |
|
(unsigned long) *(p + 1) << 16 |
|
(unsigned long) *(p + 2) << 8 |
|
(unsigned long) *(p + 2) << 8 |
|
(unsigned long) *(p + 3) << 0;
|
(unsigned long) *(p + 3) << 0;
|
}
|
}
|
|
|
|
|
void convertPartitionTable(PartEntry *e, int n) {
|
void convertPartitionTable(PartEntry *e, int n) {
|
int i;
|
int i;
|
unsigned char *p;
|
unsigned char *p;
|
|
|
for (i = 0; i < n; i++) {
|
for (i = 0; i < n; i++) {
|
p = (unsigned char *) &e[i];
|
p = (unsigned char *) &e[i];
|
e[i].type = getNumber(p + 0);
|
e[i].type = getNumber(p + 0);
|
e[i].start = getNumber(p + 4);
|
e[i].start = getNumber(p + 4);
|
e[i].size = getNumber(p + 8);
|
e[i].size = getNumber(p + 8);
|
}
|
}
|
}
|
}
|
|
|
|
|
/**************************************************************/
|
/**************************************************************/
|
|
|
|
|
static char *exceptionCause[32] = {
|
static char *exceptionCause[32] = {
|
/* 00 */ "terminal 0 transmitter interrupt",
|
/* 00 */ "terminal 0 transmitter interrupt",
|
/* 01 */ "terminal 0 receiver interrupt",
|
/* 01 */ "terminal 0 receiver interrupt",
|
/* 02 */ "terminal 1 transmitter interrupt",
|
/* 02 */ "terminal 1 transmitter interrupt",
|
/* 03 */ "terminal 1 receiver interrupt",
|
/* 03 */ "terminal 1 receiver interrupt",
|
/* 04 */ "keyboard interrupt",
|
/* 04 */ "keyboard interrupt",
|
/* 05 */ "unknown interrupt",
|
/* 05 */ "unknown interrupt",
|
/* 06 */ "unknown interrupt",
|
/* 06 */ "unknown interrupt",
|
/* 07 */ "unknown interrupt",
|
/* 07 */ "unknown interrupt",
|
/* 08 */ "disk interrupt",
|
/* 08 */ "disk interrupt",
|
/* 09 */ "unknown interrupt",
|
/* 09 */ "unknown interrupt",
|
/* 10 */ "unknown interrupt",
|
/* 10 */ "unknown interrupt",
|
/* 11 */ "unknown interrupt",
|
/* 11 */ "unknown interrupt",
|
/* 12 */ "unknown interrupt",
|
/* 12 */ "unknown interrupt",
|
/* 13 */ "unknown interrupt",
|
/* 13 */ "unknown interrupt",
|
/* 14 */ "timer interrupt",
|
/* 14 */ "timer 0 interrupt",
|
/* 15 */ "unknown interrupt",
|
/* 15 */ "timer 1 interrupt",
|
/* 16 */ "bus timeout exception",
|
/* 16 */ "bus timeout exception",
|
/* 17 */ "illegal instruction exception",
|
/* 17 */ "illegal instruction exception",
|
/* 18 */ "privileged instruction exception",
|
/* 18 */ "privileged instruction exception",
|
/* 19 */ "divide instruction exception",
|
/* 19 */ "divide instruction exception",
|
/* 20 */ "trap instruction exception",
|
/* 20 */ "trap instruction exception",
|
/* 21 */ "TLB miss exception",
|
/* 21 */ "TLB miss exception",
|
/* 22 */ "TLB write exception",
|
/* 22 */ "TLB write exception",
|
/* 23 */ "TLB invalid exception",
|
/* 23 */ "TLB invalid exception",
|
/* 24 */ "illegal address exception",
|
/* 24 */ "illegal address exception",
|
/* 25 */ "privileged address exception",
|
/* 25 */ "privileged address exception",
|
/* 26 */ "unknown exception",
|
/* 26 */ "unknown exception",
|
/* 27 */ "unknown exception",
|
/* 27 */ "unknown exception",
|
/* 28 */ "unknown exception",
|
/* 28 */ "unknown exception",
|
/* 29 */ "unknown exception",
|
/* 29 */ "unknown exception",
|
/* 30 */ "unknown exception",
|
/* 30 */ "unknown exception",
|
/* 31 */ "unknown exception"
|
/* 31 */ "unknown exception"
|
};
|
};
|
|
|
|
|
int defaultISR(int irq) {
|
int defaultISR(int irq) {
|
printf("\n%s\n", exceptionCause[irq]);
|
printf("\n%s\n", exceptionCause[irq]);
|
return 0; /* do not skip any instruction */
|
return 0; /* do not skip any instruction */
|
}
|
}
|
|
|
|
|
void initInterrupts(void) {
|
void initInterrupts(void) {
|
int i;
|
int i;
|
|
|
for (i = 0; i < 32; i++) {
|
for (i = 0; i < 32; i++) {
|
setISR(i, defaultISR);
|
setISR(i, defaultISR);
|
}
|
}
|
}
|
}
|
|
|
|
|
/**************************************************************/
|
/**************************************************************/
|
|
|
|
|
Bool checkDiskReady(void) {
|
Bool checkDiskReady(void) {
|
int tries;
|
int tries;
|
int i;
|
int i;
|
|
|
for (tries = 0; tries < 10; tries++) {
|
for (tries = 0; tries < 10; tries++) {
|
for (i = 0; i < 500000; i++) {
|
for (i = 0; i < 500000; i++) {
|
if ((*DISK_CTRL & DISK_CTRL_READY) != 0) {
|
if ((*DISK_CTRL & DISK_CTRL_READY) != 0) {
|
return TRUE;
|
return TRUE;
|
}
|
}
|
}
|
}
|
printf(".");
|
printf(".");
|
}
|
}
|
return FALSE;
|
return FALSE;
|
}
|
}
|
|
|
|
|
unsigned long getDiskSize(void) {
|
unsigned long getDiskSize(void) {
|
return *DISK_CAP;
|
return *DISK_CAP;
|
}
|
}
|
|
|
|
|
Bool readDisk(unsigned long sector,
|
Bool readDisk(unsigned long sector,
|
unsigned int count,
|
unsigned int count,
|
unsigned int *addr) {
|
unsigned int *addr) {
|
unsigned int n;
|
unsigned int n;
|
unsigned int *p;
|
unsigned int *p;
|
unsigned int i;
|
unsigned int i;
|
|
|
while (count != 0) {
|
while (count != 0) {
|
n = count > 8 ? 8 : count;
|
n = count > 8 ? 8 : count;
|
*DISK_SCT = sector;
|
*DISK_SCT = sector;
|
*DISK_CNT = n;
|
*DISK_CNT = n;
|
*DISK_CTRL = DISK_CTRL_STRT;
|
*DISK_CTRL = DISK_CTRL_STRT;
|
while ((*DISK_CTRL & DISK_CTRL_DONE) == 0) ;
|
while ((*DISK_CTRL & DISK_CTRL_DONE) == 0) ;
|
if (*DISK_CTRL & DISK_CTRL_ERR) {
|
if (*DISK_CTRL & DISK_CTRL_ERR) {
|
return FALSE;
|
return FALSE;
|
}
|
}
|
p = DISK_BUFFER;
|
p = DISK_BUFFER;
|
for (i = 0; i < n * SECTOR_SIZE / sizeof(unsigned int); i++) {
|
for (i = 0; i < n * SECTOR_SIZE / sizeof(unsigned int); i++) {
|
*addr++ = *p++;
|
*addr++ = *p++;
|
}
|
}
|
sector += n;
|
sector += n;
|
count -= n;
|
count -= n;
|
}
|
}
|
return TRUE;
|
return TRUE;
|
}
|
}
|
|
|
|
|
/**************************************************************/
|
/**************************************************************/
|
|
|
|
|
void main(void) {
|
void main(void) {
|
unsigned long numSectors;
|
unsigned long numSectors;
|
unsigned long partLast;
|
unsigned long partLast;
|
int i, j;
|
int i, j;
|
char c;
|
char c;
|
|
|
/* init interrupts */
|
/* init interrupts */
|
initInterrupts();
|
initInterrupts();
|
/* check disk ready */
|
/* check disk ready */
|
if (!checkDiskReady()) {
|
if (!checkDiskReady()) {
|
error("disk not ready");
|
error("disk not ready");
|
}
|
}
|
/* determine disk size */
|
/* determine disk size */
|
numSectors = getDiskSize();
|
numSectors = getDiskSize();
|
printf("Disk has %lu (0x%lX) sectors.\n",
|
printf("Disk has %lu (0x%lX) sectors.\n",
|
numSectors, numSectors);
|
numSectors, numSectors);
|
if (numSectors < 32) {
|
if (numSectors < 32) {
|
error("disk is too small");
|
error("disk is too small");
|
}
|
}
|
/* read partition table record */
|
/* read partition table record */
|
if (!readDisk(1, 1, (unsigned int *) ptr)) {
|
if (!readDisk(1, 1, (unsigned int *) ptr)) {
|
error("cannot read partition table from disk");
|
error("cannot read partition table from disk");
|
}
|
}
|
convertPartitionTable(ptr, NPE);
|
convertPartitionTable(ptr, NPE);
|
/* show partition table */
|
/* show partition table */
|
printf("Partitions:\n");
|
printf("Partitions:\n");
|
printf(" # b type start last size description\n");
|
printf(" # b type start last size description\n");
|
for (i = 0; i < NPE; i++) {
|
for (i = 0; i < NPE; i++) {
|
if (ptr[i].type != 0) {
|
if (ptr[i].type != 0) {
|
partLast = ptr[i].start + ptr[i].size - 1;
|
partLast = ptr[i].start + ptr[i].size - 1;
|
} else {
|
} else {
|
partLast = 0;
|
partLast = 0;
|
}
|
}
|
printf("%2d %s 0x%08lX 0x%08lX 0x%08lX 0x%08lX ",
|
printf("%2d %s 0x%08lX 0x%08lX 0x%08lX 0x%08lX ",
|
i,
|
i,
|
ptr[i].type & 0x80000000 ? "*" : " ",
|
ptr[i].type & 0x80000000 ? "*" : " ",
|
ptr[i].type & 0x7FFFFFFF,
|
ptr[i].type & 0x7FFFFFFF,
|
ptr[i].start,
|
ptr[i].start,
|
partLast,
|
partLast,
|
ptr[i].size);
|
ptr[i].size);
|
for (j = 0; j < DESCR_SIZE; j++) {
|
for (j = 0; j < DESCR_SIZE; j++) {
|
c = ptr[i].descr[j];
|
c = ptr[i].descr[j];
|
if (c == '\0') {
|
if (c == '\0') {
|
break;
|
break;
|
}
|
}
|
if (c >= 0x20 && c < 0x7F) {
|
if (c >= 0x20 && c < 0x7F) {
|
printf("%c", c);
|
printf("%c", c);
|
} else {
|
} else {
|
printf(".");
|
printf(".");
|
}
|
}
|
}
|
}
|
printf("\n");
|
printf("\n");
|
}
|
}
|
/* done */
|
/* done */
|
printf("Halting...\n");
|
printf("Halting...\n");
|
}
|
}
|
|
|