Created
May 25, 2012 18:09
-
-
Save i2pi/2789587 to your computer and use it in GitHub Desktop.
jformat
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
** Disk Funtions ** | |
⁄ƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒ∑ | |
≥ JAOS 0.0.1 - Josh and Andrew's Operating System ∫ | |
√ƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒ∂ | |
≥ THIS IS DESIGNED FOR VERSION 0.0.1 OF THE JAOS CODE ∫ | |
√ƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒ∂ | |
≥ ∫ | |
≥ JAOS was written by Joshua Reich and Andrew Shirzad ∫ | |
≥ They are the ONLY copyright holders. ∫ | |
≥ They hold no responsibility for any misuse of this ∫ | |
≥ code, and warn you that it is far from being safe to ∫ | |
≥ use this code in its current state. ∫ | |
≥ ∫ | |
‘ÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕº | |
-- At the moment it only runs the FAT stuff | |
-- It has been tested fully now ... So you can be even more worried | |
*/ | |
#define O_RDONLY 1 | |
#define O_WRONLY 2 | |
#define O_RDWR 4 | |
#define O_TEXT 0x4000 /* CR-LF translation */ | |
#define O_BINARY 0x8000 /* no translation */ | |
#include <stdio.h> // Printf routine, will be rewritten in anycase | |
#include <io.h> // File opening, reading, etc. To format JAOS from DOS | |
#include <conio.h> | |
const int CMD_Reset = 0; | |
const int CMD_Read = 2; | |
const int CMD_Write = 3; | |
const int CMD_Verify = 4; | |
const int CMD_Format = 5; | |
const char Q_Format = 1; | |
const char Read_Fat = 2; | |
const char Cap_144M = 4; | |
const char Cap_120M = 8; | |
const char Cap_360K = 16; | |
const char Cap_720K = 32; | |
const char Drive_A = 0; | |
const char Drive_B = 1; | |
const char MAX_ATTEMPTS = 3; // Number of times to repeat a disk op. | |
const Head_MASK = 0x20; // Bit Mask to get Head | |
typedef char FileNameType[29]; | |
typedef char FAT_EntryType[31]; | |
typedef char SectorBufferType[512]; // MUST BE 512... This needs to be | |
// fixed so that other disks can be | |
// used !!!!!!!!! | |
typedef char AreaType[1]; | |
typedef unsigned int word; | |
typedef unsigned char byte; | |
FAT_EntryType FAT[290]; | |
byte SECTORS_PER_TRACK = 18; | |
byte MAX_TRACKS = 80; | |
word FAT_Track, FAT_Sector,FAT_Head; // Global Variables of the start FAT disk | |
// location | |
byte biosdisk(byte cmd, byte drive, byte head, byte track, byte sector, | |
byte nsects, char far *buffer) | |
{ | |
byte result; | |
asm { mov ah , cmd | |
mov dl , drive | |
les bx , buffer | |
mov dh , head | |
mov al , nsects | |
mov cl , sector | |
mov ch , track | |
int 0x13 | |
mov result,ah | |
} | |
return result; | |
} | |
word MAX_ENTRIES(void) | |
{ | |
return SECTORS_PER_TRACK * (512 / 32); | |
// Sectors per track * 32-Byte entries per 512-Byte sector | |
} | |
char *Disk_Error(word Code) | |
{ | |
char *ErrorName; | |
switch (Code) | |
{ | |
case 0x00:ErrorName="OK. "; break; | |
case 0x01:ErrorName="Invalid function "; break; | |
case 0x02:ErrorName="Address mark not found"; break; | |
case 0x03:ErrorName="Write protected "; break; | |
case 0x04:ErrorName="Sector not found "; break; | |
case 0x05:ErrorName="Reset failed "; break; | |
case 0x06:ErrorName="Disk changed "; break; | |
case 0x07:ErrorName="Activity failed "; break; | |
case 0x08:ErrorName="DMA overrun "; break; | |
case 0x09:ErrorName="64K DMA breach "; break; | |
case 0x0A:ErrorName="Bad sector "; break; | |
case 0x0B:ErrorName="Bad track "; break; | |
case 0x0C:ErrorName="Unsupported track "; break; | |
case 0x10:ErrorName="CRC error "; break; | |
case 0x11:ErrorName="CRC corrected data "; break; | |
case 0x20:ErrorName="Controller failure "; break; | |
case 0x40:ErrorName="Seek failure "; break; | |
case 0x80:ErrorName="Failure to respond "; break; | |
case 0xAA:ErrorName="HD not ready "; break; | |
case 0xBB:ErrorName="Undefined HD error "; break; | |
case 0xCC:ErrorName="Write fault occurred "; break; | |
case 0xE0:ErrorName="Statues error "; break; | |
case 0xFF:ErrorName="Sense failure "; break; | |
default: ErrorName="Unknown error"; | |
} | |
return(ErrorName); | |
} | |
word Test_Drive(word Drive_Num) | |
{ | |
char buffer[512]; | |
byte result; | |
result =biosdisk(CMD_Verify,Drive_Num,1,1,1,1,buffer); | |
result &=0x80; | |
result =~result; | |
result &=0x80; | |
return result; | |
} | |
void Reset_Drive(word Drive_Num) | |
{ | |
char buffer[512]; | |
biosdisk(CMD_Reset,Drive_Num,1,1,1,1,buffer); | |
} | |
char Area_Code (word Head, // Head Number | |
word Sector, // Sector Number | |
word Track, // Track Number | |
word ByteNum // Area code has 2 bytes | |
) | |
{ | |
// This function returns the appropriate byte of the Area Code of | |
// a disk location. Calculated by : | |
// Bit(s) Use | |
// ------------------ | |
// 0-4 | Sector | |
// 5 | Head | |
// 6-7 | Unused (probably for trees or sharing) | |
// 8-15 | Track | |
char temp; | |
switch (ByteNum) | |
{ | |
case 0: { temp=Sector; | |
if (Head) (temp=temp*2); | |
} | |
case 1: temp=Track; | |
} | |
return(temp); | |
} | |
word FormatDrive(char Drive_Num, // self explanatory | |
AreaType FAT_Area, // area code of FAT start | |
char* boot_file // name of bootfile; if <4 chars | |
) // then no bootfile is loaded. | |
{ | |
word track; | |
word count; | |
word result; | |
word temp; | |
int handle; | |
word attempt; | |
char new_buf[512]; // boot sector | |
char sect_buf[4*18]; // format data | |
for (count=0; count<512; count++) new_buf[count]='~'; | |
if (boot_file!=NULL) handle = open(boot_file, O_RDONLY | O_BINARY); | |
else handle=10; | |
if (handle < 0) return handle; | |
if (boot_file!=NULL) read(handle, new_buf, (word)filelength(handle)); | |
new_buf[504]=(char)1; // Version Number | |
new_buf[505]=(char)"J"; // OS ID tag | |
new_buf[506]=(char)"A"; | |
new_buf[507]=(char)"O"; | |
new_buf[508]=(char)"S"; | |
new_buf[509]=FAT_Area[1]; // Pointer to FAT location | |
new_buf[510]=FAT_Area[2]; | |
if (boot_file!=NULL) | |
{ | |
new_buf[511]=0x55; // Specifies BIOS bootability | |
new_buf[512]=0xAA; | |
} else | |
{ | |
new_buf[511]=0xFF; // Specifies BIOS non-bootability | |
new_buf[512]=0xFF; | |
} | |
if (boot_file!=NULL) close(handle); | |
Reset_Drive(Drive_Num); | |
asm { mov ah, 0x18 | |
mov dl, Drive_Num | |
mov ch,MAX_TRACKS-1 | |
mov cl,SECTORS_PER_TRACK | |
int 0x13 | |
} | |
printf("Formatting %3d Tracks with %2d sectors per track.\n",MAX_TRACKS,SECTORS_PER_TRACK); | |
for (track=0; track<MAX_TRACKS; track++) | |
{ | |
// format head 0 | |
for (count=0; count<SECTORS_PER_TRACK; count++) | |
{ | |
temp=4*count; | |
sect_buf[temp]= track; //track | |
sect_buf[temp+1]=0; //head | |
sect_buf[temp+2]=count+1; //sector | |
sect_buf[temp+3]= 2; //512 bytes per sector | |
} | |
attempt=0; result=1; | |
while ((result!=0)&&(attempt<MAX_ATTEMPTS)) | |
{ | |
attempt++; | |
result=biosdisk(CMD_Format,Drive_Num,0,track,1,SECTORS_PER_TRACK | |
,sect_buf); | |
} | |
printf("Formatting @ (%d, 0x%x, 0x%x) %d%% [0x%x]",sect_buf[1] | |
,sect_buf[0],sect_buf[2],(100 * (word) sect_buf[0]/MAX_TRACKS),result); | |
if(result) printf("%s\n",Disk_Error(result)); else printf("\r"); | |
while ((result!=0)&&(attempt<MAX_ATTEMPTS)) | |
{ | |
attempt++; | |
result=biosdisk(CMD_Verify,Drive_Num,0,track,1,SECTORS_PER_TRACK | |
,NULL); | |
} | |
printf("Verifying @ (%d, 0x%x, 0x%x) %d%% [0x%x]",sect_buf[1],sect_buf[0],sect_buf[2],(100*(word)sect_buf[0]/MAX_TRACKS),result); | |
if(result) printf("%s\n",Disk_Error(result)); else printf("\r"); | |
// format head 1 | |
for (count=0; count<SECTORS_PER_TRACK; count++) | |
{ | |
temp=4*count; | |
sect_buf[temp+0]=track; //track | |
sect_buf[temp+1]=1; //head | |
sect_buf[temp+2]=count+1; //sector | |
sect_buf[temp+3]=2; //512 bytes per sector | |
} | |
attempt=0; result=1; | |
while ((result!=0)&&(attempt<MAX_ATTEMPTS)) | |
{ | |
attempt++; | |
result=biosdisk(CMD_Format,Drive_Num,1,track,1,SECTORS_PER_TRACK | |
,sect_buf); | |
} | |
printf("Formatting @ (%d, 0x%x, 0x%x) %d%% [0x%x]",sect_buf[1],sect_buf[0],sect_buf[2],(100*(word)sect_buf[0]/MAX_TRACKS),result); | |
if(result) printf("%s\n",Disk_Error(result)); else printf("\r"); | |
while ((result!=0)&&(attempt<MAX_ATTEMPTS)) | |
{ | |
attempt++; | |
result=biosdisk(CMD_Verify,Drive_Num,1,track,1,SECTORS_PER_TRACK | |
,NULL); | |
} | |
printf("Verifying @ (%d, 0x%x, 0x%x) %d%% [0x%x] ",sect_buf[1],sect_buf[0],sect_buf[2],(100*(word)sect_buf[0]/MAX_TRACKS),result); | |
if(result) printf("%s\n",Disk_Error(result)); else printf("\r"); | |
} | |
Reset_Drive(Drive_Num); | |
result=biosdisk(CMD_Verify,Drive_Num,0,1,1,1 | |
,NULL); | |
printf("Verifying @ (0, 0x 1, 0x 1) [0x%x] ",result); | |
if(result) printf("%s\n",Disk_Error(result)); else printf("\r"); | |
// Copy sector 1 to disk | |
biosdisk(CMD_Write,Drive_Num,0,0,1,1,new_buf); | |
printf("\n"); | |
printf("Format Complete \n"); | |
return 1; | |
} | |
word Read_Disk(word Disk_Num, //Disk number | |
AreaType Area_Code, //Area code of sector to read from | |
SectorBufferType Buffer //Buffer to store read data | |
) | |
{ | |
word Head, Track, Sector; // Guess what these are ! | |
Head=Area_Code[0] & Head_MASK; | |
if (Head) (Sector=Area_Code[0]-Head_MASK); | |
else (Sector=Area_Code[0]); | |
Track=Area_Code[1]; | |
if (Test_Drive(Disk_Num)) { | |
biosdisk(CMD_Read,Disk_Num,Head,Track,Sector,1, Buffer); | |
return (0); //Success | |
} else return(1); //Failure | |
} | |
word Write_Disk(word Disk_Num, //Disk number | |
AreaType Area_Code, //Area code of sector to write to | |
SectorBufferType Buffer //Buffer to read data from | |
) | |
{ | |
word Head, Track, Sector; // Guess what these are ! | |
Head=Area_Code[0] & Head_MASK; | |
if (Head) (Sector=Area_Code[0]-Head_MASK); | |
else (Sector=Area_Code[0]); | |
Track=Area_Code[1]; | |
if (Test_Drive(Disk_Num)) { | |
biosdisk(CMD_Write,Disk_Num,Head,Track,Sector,1, Buffer); | |
return (0); //Success | |
} else return(1); //Failure | |
} | |
word Put_FAT(word Disk_Num, AreaType Area_Code) | |
{ | |
// Puts the contents of the FAT onto Disk_Num @ Area_Code | |
// Returns 1 for success... Returns 0 for either bad disk or no FAT | |
SectorBufferType Buffer; // Data buffer | |
word Sector_Num; | |
word result; | |
word attempts; | |
word Count; // Byte in Sector | |
word Entry_Num; // Entry in FAT | |
word In_Entry; // Byte in Entry | |
FAT_Head=Area_Code[0] & Head_MASK; // Convert FAT_Area_Code to | |
if (FAT_Head) (FAT_Sector=Area_Code[0]-Head_MASK); // actual disk | |
else (FAT_Sector=Area_Code[0]); // location. | |
FAT_Track=Area_Code[1]; | |
Sector_Num=FAT_Sector; | |
Count=0; | |
for (Entry_Num=0; Entry_Num<MAX_ENTRIES(); Entry_Num++) | |
for (In_Entry=0; In_Entry<32; In_Entry++) | |
{ | |
Buffer[Count]=FAT[Entry_Num][In_Entry]; | |
Count++; | |
if (Count>511) | |
{ | |
Count=0; | |
attempts=0; | |
result=1; | |
while (result !=0 && attempts<MAX_ATTEMPTS) | |
{ | |
result=biosdisk(CMD_Write,Disk_Num,FAT_Head,FAT_Track | |
,Sector_Num,1,Buffer); | |
if(result) Reset_Drive(Disk_Num); | |
attempts++; | |
} | |
printf("Placing FAT @ (%d, 0x%2x, 0x%2x) [0x%2x] ",FAT_Head,FAT_Track,Sector_Num,result); | |
if (result!=0) printf("%s\n",Disk_Error(result)); else printf("\r"); | |
Sector_Num++; | |
} | |
} | |
return (1); // **NOTE: This is not checking it YET... | |
} | |
word Get_FAT(word Disk_Num, AreaType Area_Code) | |
{ | |
// Should always be called when a disk is put in drive | |
// Returns 1 for success... Returns 0 for either bad disk or no FAT | |
SectorBufferType Buffer; // Data buffer | |
word Entry; // The number of the entry in the FAT (1..MAX_ENTRIES) | |
word Count; // Position in sector | |
word Sector_Num; // The FAT is made up of 10 sectors | |
// Each sector holds 16 -32 bit entrys | |
FAT_Head=Area_Code[0] & Head_MASK; // Convert FAT_Area_Code to | |
if (FAT_Head) (FAT_Sector=Area_Code[0]-Head_MASK); // actual disk | |
else (FAT_Sector=Area_Code[0]); // location. | |
FAT_Track=Area_Code[1]; | |
Entry=0; | |
for (Sector_Num=0; Sector_Num<11; Sector_Num++) | |
{ | |
biosdisk(CMD_Read,Disk_Num,FAT_Head,FAT_Track,Sector_Num+FAT_Sector,1,Buffer); | |
for (Count=0; Count<32; Count++) | |
FAT[Entry][Count]=Buffer[Count]; | |
Entry++; | |
} | |
return (1); // **NOTE: This is not checking it YET... | |
} | |
void Get_FAT_FileName(word EntryNum,FileNameType FileName) | |
{ | |
// Reads the EntryNum th FAT entry, and returns the name of that file | |
word count; | |
for (count=0; count<30; count++) | |
FileName[count]=FAT[EntryNum][count]; | |
} | |
word Put_FAT_FileName(word EntryNum, FileNameType FileName) | |
{ | |
word count; | |
for (count=0; count<30; count++) | |
FAT[EntryNum][count]=FileName[count]; //ANDREW:There must be a | |
// better way to do this!! | |
return(1); // Should really check if FAT has been initialised... | |
} | |
void Put_FAT_Area_Code(word EntryNum,AreaType AreaCode) | |
{ | |
FAT[EntryNum][30]=AreaCode[0]; | |
FAT[EntryNum][31]=AreaCode[1]; | |
} | |
char Get_FAT_Area_Code(word EntryNum,word Byte) | |
{ | |
// Reads the EntryNum th FAT entry, and returns the start Area of that file | |
if (Byte) {return(FAT[EntryNum][30]);} | |
else return(FAT[EntryNum][31]); | |
} | |
byte format(byte Drive_Num) | |
{ | |
byte result; | |
AreaType FAT_AreaCode; | |
printf("Formatting drive...\n"); | |
FAT_AreaCode[0]=Area_Code(0,1,2,0); //refer to : | |
FAT_AreaCode[1]=Area_Code(0,1,2,1); // H:0; S:1; T:2; | |
result=FormatDrive(Drive_Num,FAT_AreaCode,NULL); | |
if(result!=1) | |
{ | |
printf("Format failed..\nExiting program."); | |
return 2; | |
} | |
else return 1; | |
} | |
void Format_Routine(byte Drive_Num) | |
{ | |
// This sets up a FAT on a new disk... | |
word Entry; | |
AreaType FAT_AreaCode; | |
FileNameType fname1; | |
printf("Generating FAT entries...\n"); | |
for (Entry=0; Entry<MAX_ENTRIES(); Entry++) | |
{ | |
Put_FAT_FileName(Entry,"|---------------------------->"); | |
//Make an empty slot | |
FAT[Entry][30]=Area_Code(0,1,2,0); //refer to : | |
FAT[Entry][31]=Area_Code(0,1,2,1); // H:0; S:1; T:2; | |
} | |
FAT_AreaCode[0]=Area_Code(0,1,1,0); // Make FAT at H:0; S:1; T:1; | |
FAT_AreaCode[1]=Area_Code(0,1,1,1); // Make FAT at H:0; S:1; T:1; | |
printf("Storing FAT on disk...\n"); | |
Put_FAT(Drive_Num,FAT_AreaCode); | |
printf("Retrieving first 10 entries on disk to show off (Josh couldn't do it)...\n"); | |
printf("Andrew - I wrote most this.. so be nice... I am yet to see your video code! :)\n"); | |
Get_FAT(Drive_Num,FAT_AreaCode); | |
for(Entry=0;Entry<10;Entry++) | |
{ | |
Get_FAT_FileName(Entry,fname1); | |
fname1[30]=0; | |
printf("Entry %3d - %s\n",Entry,fname1); | |
} | |
} | |
void main (void) | |
{ SectorBufferType Buffer; | |
AreaType AreaCode; | |
int Hand,count; | |
Hand=open("Boot_001.com",O_RDONLY); | |
read(Hand,Buffer,131); | |
close(Hand); | |
clrscr(); | |
Buffer[503]=(char)1; // Version Number | |
Buffer[504]='J'; // OS ID tag | |
Buffer[505]='A'; | |
Buffer[506]='O'; | |
Buffer[507]='S'; | |
Buffer[510]=0x55; // Specifies BIOS bootability | |
Buffer[511]=0xAA; | |
AreaCode[0]=Area_Code(0,1,0,0); | |
AreaCode[1]=Area_Code(0,1,0,1); | |
Reset_Drive(0); | |
printf("\nDrive status : 0x%x\n", Test_Drive(0)); | |
printf("Before write:\n"); | |
for (count=0; count<513 ; count++) | |
printf("%c",Buffer[count]); | |
Write_Disk(0,AreaCode,Buffer); | |
for (count=0; count<513 ; count++) Buffer[count]=0; | |
Read_Disk(0,AreaCode,Buffer); | |
printf("\nAfter write:\n"); | |
for (count=0; count<513 ; count++) | |
printf("%c",Buffer[count]); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment