Skip to content

Instantly share code, notes, and snippets.

@i2pi
Created May 25, 2012 18:09
Show Gist options
  • Save i2pi/2789587 to your computer and use it in GitHub Desktop.
Save i2pi/2789587 to your computer and use it in GitHub Desktop.
jformat
/*
** 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