[GOOD] BUILD 0.1.0.450 DATE 8/29/2011 AT 10:30 AM

====================================================
+ Changed 'align 0x4' line above multiboot header in loader.asm to
'align 4'
+ Removed -e option for echo in build.sh
+ Modified build.sh for linux
+ Fixed triple fault when enabling paging
+ Fixed page faults at memory manager initialization
+ Fixed 'mem' console function
+ Added more info about page fault at crash screen
+ Added Panic() macro
+ Added verbose mode for memory manager

[ BAD] BUILD 0.1.0.390 DATE 8/27/2011 AT 10:54 PM
====================================================
+ Added stdlib routines, separated in different files
+ Rewritten physical memory manager
+ Added virtual mem manager
+ Added memory allocation/freeing
+ Added memory library
+ Added temporary allocation (at end of kernel), until paging is started
- Removed functionality from debug console function 'mem'
- Removed system.h, the one remaining function now in stdio.h
This commit is contained in:
2021-09-14 18:48:57 +03:00
parent b6ddeca1c3
commit 913e65b856
326 changed files with 6990 additions and 12229 deletions

View File

@ -0,0 +1,63 @@
#include <time.h>
#include <stdio.h>
#include "cmos.h"
uint8 CmosRead (uint8 address)
{
outportb(0x70, address); iowait();
return inportb(0x71);
}
void CmosWrite (uint8 address, uint8 val)
{
outportb(0x70, address); iowait();
outportb(0x71, val);
}
void CmosSetRTC (const Time* time)
{
unsigned char BCD = ((CmosRead(0x0b)&4)==0) ? 1 : 0;
unsigned char ampm = ((CmosRead(0x0b)&2)==0) ? 1 : 0;
uint8 year = time->Year % 100;
uint8 century = time->Year / 100;
CmosWrite (0, (BCD) ? (time->Second%10) | (time->Second/10*16) : time->Second); // Seconds
CmosWrite (2, (BCD) ? (time->Minute%10) | (time->Minute/10*16) : time->Minute); // Minutes
if (ampm && time->Hour > 12) // Hours
CmosWrite (4, (BCD) ? (((time->Hour - 12) % 10) | ((time->Hour - 12)/10*16) | 0x80) : (time->Hour | 0x80) );
else if (ampm && time->Hour == 0) // Midnight convention: 12 PM = 00:00
CmosWrite (4, (BCD) ? 0x92 : 0x8C);
else CmosWrite (4, (BCD) ? (time->Hour%10) | (time->Hour/10*16) : time->Hour); // 24h / AM
CmosWrite (7, (BCD) ? (time->Day%10) | (time->Day/10*16) : time->Day); // Day
CmosWrite (8, (BCD) ? (time->Month%10) | (time->Month/10*16) : time->Month); // Month
CmosWrite (9, (BCD) ? (year%10) | (year/10*16) : year); // Year
CmosWrite (0x32, (BCD) ? (century%10) | (century/10*16) : century); // Century
}
void CmosGetRTC(Time* tim)
{
unsigned char BCD = ((CmosRead(0x0b)&4)==0) ? 1 : 0;
unsigned char am_pm = ((CmosRead(0x0b)&2)==0) ? 1 : 0;
tim->Second = (BCD) ? (CmosRead(0x00)%16) + 10*(CmosRead(0x00)/16): CmosRead(0x00);
tim->Minute = (BCD) ? (CmosRead(0x02)%16) + 10*(CmosRead(0x02)/16): CmosRead(0x02);
// Time is PM
if (am_pm && (CmosRead(0x04)&80)) {
tim->Hour = (BCD) ? ((CmosRead(0x04)-0x80)%16) + 10*((CmosRead(0x04)-0x80)/16): CmosRead(0x04)-0x80;
tim->Hour += 12;
}
// 24Hour format, or AM
else tim->Hour = (BCD) ? (CmosRead(0x04)%16) + 10*(CmosRead(0x04)/16): CmosRead(0x04);
tim->WeekDay = (BCD) ? (CmosRead(0x06)%16) + 10*(CmosRead(0x06)/16): CmosRead(0x06);
tim->Day = (BCD) ? (CmosRead(0x07)%16) + 10*(CmosRead(0x07)/16): CmosRead(0x07);
tim->Month = (BCD) ? (CmosRead(0x08)%16) + 10*(CmosRead(0x08)/16): CmosRead(0x08);
tim->Year = (BCD) ? (CmosRead(0x09)%16) + 10*(CmosRead(0x09)/16): CmosRead(0x09);
tim->Year += 100 * ((BCD) ? (CmosRead(0x32)%16) + 10*(CmosRead(0x32)/16): CmosRead(0x32));
}

View File

@ -0,0 +1,12 @@
#ifndef __CMOS__H
#define __CMOS__H
#include <types.h>
#include <time.h>
extern uint8 CmosRead (uint8 address);
extern void CmosWrite (uint8 address, uint8 val);
extern void CmosSetRTC (const Time* time);
extern void CmosGetRTC(Time* tim);
#endif

111
Kernel/drivers/dma/dma.c Normal file
View File

@ -0,0 +1,111 @@
/*
* dma.c
*
* Created on: Aug 20, 2011
* Author: Tiberiu
*/
#include <stdio.h>
#include "dma.h"
void DmaSetAddress (uint8 channel, uint8 low, uint8 high)
{
uint16 port = 0;
switch (channel)
{
case 0: port = DmaRegisterChannel0Address; break;
case 1: port = DmaRegisterChannel1Address; break;
case 2: port = DmaRegisterChannel2Address; break;
case 3: port = DmaRegisterChannel3Address; break;
case 4: port = DmaRegisterChannel4Address; break;
case 5: port = DmaRegisterChannel5Address; break;
case 6: port = DmaRegisterChannel6Address; break;
case 7: port = DmaRegisterChannel7Address; break;
default: return;
}
outportb(port, low); iowait();
outportb(port, high);
}
void DmaSetCount (uint8 channel, uint8 low, uint8 high)
{
uint16 port = 0;
switch (channel)
{
case 0: port = DmaRegisterChannel0Count; break;
case 1: port = DmaRegisterChannel1Count; break;
case 2: port = DmaRegisterChannel2Count; break;
case 3: port = DmaRegisterChannel3Count; break;
case 4: port = DmaRegisterChannel4Count; break;
case 5: port = DmaRegisterChannel5Count; break;
case 6: port = DmaRegisterChannel6Count; break;
case 7: port = DmaRegisterChannel7Count; break;
default: return;
}
outportb(port, low); iowait();
outportb(port, high);
}
void DmaSetExternalPageRegisters (uint8 channel, uint8 val)
{
uint16 port = 0;
switch (channel)
{
case 1: port = DmaRegisterChannel1PageAddress; break;
case 2: port = DmaRegisterChannel2PageAddress; break;
case 3: port = DmaRegisterChannel3PageAddress; break;
case 5: port = DmaRegisterChannel5PageAddress; break;
case 6: port = DmaRegisterChannel6PageAddress; break;
case 7: port = DmaRegisterChannel7PageAddress; break;
default: return;
}
outportb(port, val);
}
void DmaResetFlipFlop (uint8 channel)
{
uint16 port = (channel < 4) ? DmaRegisterFlipFlopReset : 2*DmaRegisterFlipFlopReset+0xC0;
outportb(port, 0);
}
void DmaReset ()
{
outportb(DmaRegisterMasterReset, 0);
}
void DmaUnmaskAll()
{
outportb(DmaRegisterMaskReset, 0);
}
void DmaMaskChannel(uint8 channel)
{
if (channel >= 8) return;
uint16 port = (channel < 4) ? (DmaRegisterSingleChannelMask) : (2*DmaRegisterSingleChannelMask + 0xC0);
outportb(port, channel%4 | 4);
}
void DmaUnmaskChannel (uint8 channel)
{
if (channel >= 8) return;
uint16 port = (channel < 4) ? (DmaRegisterSingleChannelMask) : (2*DmaRegisterSingleChannelMask + 0xC0);
outportb(port, channel%4);
}
void DmaSetMode (uint8 channel, uint8 mode)
{
if (channel >= 8) return;
uint16 port = (channel < 4) ? (DmaRegisterMode) : (2*DmaRegisterMode + 0xC0);
DmaMaskChannel(channel);
outportb(port, (channel%4) | mode );
DmaUnmaskAll();
}

80
Kernel/drivers/dma/dma.h Normal file
View File

@ -0,0 +1,80 @@
/*
* dma.h
*
* Created on: Aug 20, 2011
* Author: Tiberiu
*/
#ifndef DMA_H_
#define DMA_H_
#include <types.h>
enum DmaRegisters
{
DmaRegisterStatus = 0x08,
DmaRegisterCommand = 0x08,
DmaRegisterRequest = 0x09,
DmaRegisterSingleChannelMask = 0x0A,
DmaRegisterMode = 0x0B,
DmaRegisterFlipFlopReset = 0x0C,
DmaRegisterIntermediate = 0x0D,
DmaRegisterMasterReset = 0x0D,
DmaRegisterMaskReset = 0x0E,
DmaRegisterMultichannelMask = 0x0F,
DmaRegisterChannel0Address = 0x00,
DmaRegisterChannel1Address = 0x02,
DmaRegisterChannel2Address = 0x04,
DmaRegisterChannel3Address = 0x06,
DmaRegisterChannel4Address = 0xC0,
DmaRegisterChannel5Address = 0xC4,
DmaRegisterChannel6Address = 0xC8,
DmaRegisterChannel7Address = 0xCC,
DmaRegisterChannel0Count = 0x01,
DmaRegisterChannel1Count = 0x03,
DmaRegisterChannel2Count = 0x05,
DmaRegisterChannel3Count = 0x07,
DmaRegisterChannel4Count = 0xC2,
DmaRegisterChannel5Count = 0xC6,
DmaRegisterChannel6Count = 0xCA,
DmaRegisterChannel7Count = 0xCE,
DmaRegisterChannel1PageAddress = 0x83,
DmaRegisterChannel2PageAddress = 0x81,
DmaRegisterChannel3PageAddress = 0x82,
DmaRegisterChannel5PageAddress = 0x8B,
DmaRegisterChannel6PageAddress = 0x89,
DmaRegisterChannel7PageAddress = 0x8A
};
enum DmaModes
{
DmaModeChannelMask = 0x3,
DmaModeSelfTest = 0,
DmaModeWrite = 0x8,
DmaModeRead = 0x4,
DmaModeAutoReinit = 0x10,
DmaModeDown = 0x20,
DmaModeTransferOnDemand = 0,
DmaModeTransferSingleDma = 0x40,
DmaModeTransferBlockDma = 0x80,
DmaModeTransferCascade = 0xC0
};
extern void DmaSetAddress (uint8 channel, uint8 low, uint8 high);
extern void DmaSetCount (uint8 channel, uint8 low, uint8 high);
extern void DmaSetExternalPageRegisters (uint8 channel, uint8 val);
extern void DmaSetMode (uint8 channel, uint8 mode);
extern void DmaResetFlipFlop (uint8 channel);
extern void DmaReset ();
extern void DmaMaskChannel(uint8 channel);
extern void DmaUnmaskChannel (uint8 channel);
extern void DmaUnmaskAll ();
#endif /* DMA_H_ */

34
Kernel/drivers/drivers.c Normal file
View File

@ -0,0 +1,34 @@
#include "drivers.h"
#include "cmos/cmos.h"
#include "pit/pit.h"
#include "floppy/floppy.h"
#include "time.h"
#include "../hal/cpu/irq.h"
#include <debugio.h>
void DriversInstall_Clock()
{
// Set up PIT
PitSetFrequency(PIT_FREQUENCY);
// Update internal clock
Time time;
CmosGetRTC(&time);
TimeSetInternalTime(TimeConvertToTimeSystem(time));
Log("%#[Drivers] %#Read RTC time: ", ColorWhite, ColorLightGray);
Log("%#%u/%u/%u %u:%u:%u.%u\n", ColorLightCyan, time.Month, time.Day,
time.Year, time.Hour, time.Minute, time.Second, time.Milisecond);
}
void DriversInstall()
{
// Install clock
DriversInstall_Clock();
// Install fdc
IrqInstallHandler(6, FloppyIrqHandler);
FloppyInitialize();
}

6
Kernel/drivers/drivers.h Normal file
View File

@ -0,0 +1,6 @@
#ifndef __DRIVERS__H
#define __DRIVERS__H
extern void DriversInstall();
#endif

View File

@ -0,0 +1,384 @@
/*
* floppy.c
*
* Created on: Aug 20, 2011
* Author: Tiberiu
*/
#include <debugio.h>
#include <stdio.h>
#include <types.h>
#include <time.h>
#include <storage.h>
#include "floppy.h"
#include "../dma/dma.h"
#include "../cmos/cmos.h"
FloppyType fdTypes[] = {
/* Sectors
* | Sectors per track
* | | Heads
* | | | Tracks
* | | | | Gap1
* | | | | | Data rate
* | | | | | | Spec1
* | | | | | | | SRT HLT HUT Motor Spinup time
* | | | | | | | | | | | Motor Spindown time
* | | | | | | | | | | | | Interrupt timeout
* | | | | | | | | | | | | | Disk type name string*/
{ 0, 0,0, 0,0x00,0x00,0x00,0x00,0x00,0x00, 0, 0, 0, "none"},
{ 720, 9,2,40,0x2A,0x01,0xDF,0x0C,0x04,0x00,1000,1000,3000, "5.25\" 360k"},
{ 2400,15,2,80,0x1B,0x00,0xDF,0x0A,0x08,0x00, 400,1000,3000, "5.25\" 1.2M"},
{ 1440, 9,2,80,0x2A,0x02,0xDF,0x0F,0x04,0x00,1000,1000,3000, "3.5\" 720k"},
{ 2880,18,2,80,0x1B,0x00,0xCF,0x0C,0x08,0x00, 400,1000,3000, "3.5\" 1.44M"},
//{ 2880,18,2,80,0x1B,0x00,0xCF,0x0C,0x08,0x00,2000,3000,3000, "3.5\" 1.44M"},
{ 5760,36,2,80,0x1B,0x03,0xAF,0x0A,0x0F,0x00, 400,1000,3000, "3.5\" 2.88M AMI BIOS"},
{ 5760,36,2,80,0x1B,0x03,0xAF,0x0A,0x0F,0x00, 400,1000,3000, "3.5\" 2.88M"},
};
int8 fd0, fd1;
/**************************************
* IRQ handler etc *
**************************************/
volatile uint8 FloppyIrqFired;
void FloppyIrqHandler(_RegsStack32* UNUSED(r))
{
FloppyIrqFired = 1;
}
void FloppyWaitIrq()
{
TimerStart(fdTypes[4].InterruptTimeout);
while (!FloppyIrqFired && !TimerIsDone());
if (!FloppyIrqFired) {
Error("%#[Floppy] %#Irq timeout [%ums] !\n", ColorBrown, ColorLightRed, fdTypes[4].InterruptTimeout);
}
}
/**************************************
* Installation *
**************************************/
void FloppyInitialize()
{
// Detect drives
uint8 fd = CmosRead(0x10);
fd0 = fd >> 4;
fd1 = fd & 0xf;
if (fd0 > 6) fd0 = 0;
if (fd1 > 6) fd1 = 0;
if (!fd0 && !fd1) {
Error("%#[Floppy] %#No supported floppy drives found.", ColorBrown, ColorLightRed);
outportb(FloppyRegisterDigitalOutput, 0);
return;
}
Log("%#[Floppy] %#Detected floppy drives:", ColorBrown, ColorLightGray);
if (fd0) Log(" %#fd0=%#%s", ColorLightCyan, Color(ColorCyan, ColorWhite), fdTypes[fd0].Name);
if (fd1) Log(" %#fd1=%#%s", ColorLightCyan, Color(ColorCyan, ColorWhite), fdTypes[fd1].Name);
Log("\n");
// Reset floppy controller
FloppyReset();
// Configure and lock
FloppyConfigure();
FloppySendCommand(FloppyCommandLock | 0x80);
FloppyReadData();
// Enable perpendicular mode for 3.5" ED floppies
if (fd0 > 4)
{
FloppySendCommand(FloppyCommandPerpendicularMode);
FloppySendCommand(1);
}
if (fd1 > 4)
{
FloppySendCommand(FloppyCommandPerpendicularMode);
FloppySendCommand(2);
}
// Initialize DMA
FloppyInitDma();
}
void FloppyInitDma()
{
DmaMaskChannel(2);
DmaResetFlipFlop(2);
DmaSetAddress(2, 0, 0x10);
DmaResetFlipFlop(2);
DmaSetCount(2, 0xff, 0x23);
DmaSetExternalPageRegisters(2,0);
DmaUnmaskChannel(2);
}
/**************************************
* Controller reset *
**************************************/
void FloppyReset()
{
FloppyIrqFired = 0; int32 i = 0;
Log("%#[Floppy] %#Resetting...\n", ColorBrown, ColorLightGray);
// Clear reset bit from DOR
outportb(FloppyRegisterDigitalOutput, 0);
for (i = 0; i < 1000; i++);
outportb(FloppyRegisterDigitalOutput, 4|8);
// Wait for IRQ6
FloppyWaitIrq(fd0);
// Recalibrate every drive
if (fd0)
{
FloppyMotor(0,1);
FloppySelectDrive(0);
FloppyRecalibrate(0);
FloppyMotor(0,0);
}
if (fd1)
{
FloppyMotor(1,1);
FloppySelectDrive(1);
FloppyRecalibrate(1);
FloppyMotor(1,0);
}
}
/**************************************
* Configure floppy controller *
**************************************/
void FloppyConfigure()
{
FloppySendCommand(FloppyCommandConfigure);
FloppySendCommand(0);
FloppySendCommand(1<<6 | 7);
FloppySendCommand(0);
}
/**************************************
* Base commands *
**************************************/
void FloppySendCommand (uint8 command)
{
int32 t;
for (t = 0; t < 5000 && ((inportb(FloppyRegisterMainStatus) & FloppyMsrRQM) == 0); t++) ;
outportb (FloppyRegisterFIFO, command);
}
uint8 FloppyReadData ()
{
int32 t;
for (t = 0; t < 5000 && ((inportb(FloppyRegisterMainStatus) & FloppyMsrRQM) == 0); t++) ;
return inportb (FloppyRegisterFIFO);
}
/**************************************
* Sense interrupt *
**************************************/
void FloppySenseInterrupt(uint8 *st0, uint8 *cyl)
{
FloppySendCommand(FloppyCommandSenseInterrupt);
*st0 = FloppyReadData();
*cyl = FloppyReadData();
}
/**************************************
* Specify *
**************************************/
void FloppySpecify (uint8 fd)
{
FloppySendCommand(FloppyCommandSpecify);
FloppySendCommand((fdTypes[fd].SRT << 4) | fdTypes[fd].HUT);
FloppySendCommand(fdTypes[fd].HLT << 1);
}
/**************************************
* Motor on/off *
**************************************/
void FloppyMotor (uint8 fd_number, uint8 status)
{
if (fd_number >= 2) return;
uint8 fd = (fd_number == 0) ? fd0 : fd1;
uint8 temp = inportb(FloppyRegisterDigitalOutput);
// Turn motor on/off
if (status) temp |= 0x1<<(4+fd_number);
else temp &= ~(0x1<<(4+fd_number));
outportb(FloppyRegisterDigitalOutput, temp);
// Wait for spinup/spindown
if (status) TimerStart(fdTypes[fd].Spinup);
else TimerStart(fdTypes[fd].Spindown);
Log("%#[Floppy] %#Waiting for motor...\n", ColorBrown, ColorLightGray);
while (!TimerIsDone());
}
/**************************************
* Select drive *
**************************************/
void FloppySelectDrive(uint8 number)
{
if (number >= 2) return;
uint8 fd = (number == 0) ? fd0 : fd1;
// Set CCR
outportb(FloppyRegisterConfigurationControl, fdTypes[fd].DataRate);
// Specify
FloppySpecify(fd);
// Select drive
uint8 dor = inportb(FloppyRegisterDigitalOutput);
dor = (dor & ~0xFF) | number;
}
/**************************************
* RECALIBRATE *
* motor must be on, drive selected *
**************************************/
void FloppyRecalibrate(uint8 fd_number)
{
if (fd_number >= 2) return;
uint8 st0, cyl, timeout = 10;
do {
Log("%#[Floppy] %#Recalibrating: attempt %u/10\n", ColorBrown, ColorLightGray, 11-timeout);
FloppyIrqFired = 0;
FloppySendCommand(FloppyCommandRecalibrate);
FloppySendCommand(fd_number);
FloppyWaitIrq();
FloppySenseInterrupt(&st0, &cyl);
timeout--;
} while((st0 & 0x20) == 0 && timeout > 0);
}
/**************************************
* SEEK *
* motor must be on, drive selected *
**************************************/
void FloppySeek(uint8 fd_number, uint8 cylinder, uint8 head)
{
if (fd_number >= 2) return;
uint8 st0, cyl, timeout = 10;
do {
Log("%#[Floppy] %#Seeking: attempt %u/10\n", ColorBrown, ColorLightGray, 11-timeout);
FloppyIrqFired = 0;
FloppySendCommand(FloppyCommandSeek);
FloppySendCommand(head<<2 | fd_number);
FloppySendCommand(cylinder);
FloppyWaitIrq();
FloppySenseInterrupt(&st0, &cyl);
timeout--;
} while(cyl != cylinder && timeout > 0);
}
/**************************************
* READ/WRITE *
* motor must be on, drive selected *
**************************************/
void FloppyRW(uint8 isWrite, uint8 fd_number, uint8 head, uint8 cylinder, uint8 sector)
{
if (fd_number >= 2) return;
uint8 fd = (fd_number == 0) ? fd0 : fd1;
uint8 timeout = 10;
uint8 result[7], i, error;
do
{
error = 0;
Log("%#[Floppy] %#Read/write operation: attempt %u/10\n", ColorBrown, ColorLightGray, 11-timeout);
FloppyIrqFired = 0;
if (isWrite) FloppySendCommand(FloppyCommandWriteData | FloppyModeMultitrack | FloppyModeMagneticEncoding);
else FloppySendCommand(FloppyCommandReadData | FloppyModeMultitrack | FloppyModeMagneticEncoding);
FloppySendCommand(head<<2 | fd_number);
FloppySendCommand(cylinder);
FloppySendCommand(head);
FloppySendCommand(sector);
FloppySendCommand(2);
FloppySendCommand(fdTypes[fd].SectorsPerTrack);
FloppySendCommand(fdTypes[fd].Gap);
FloppySendCommand(0xff);
FloppyWaitIrq();
for (i = 0; i < 7; i++)
result[i] = FloppyReadData();
// Disk is write protected, don't try again
if (result[1] & 2)
{
Error("%#[Floppy] %#Error: disk is write protected!\n", ColorBrown, ColorLightRed);
return;
}
// Any other error - try again
if (result[0] & 0xC8) error = 1;
if (result[1] & 0xB5) error = 1;
if (result[2] & 0x77) error = 1;
if (result[6] & 0x02) error = 1;
timeout--;
} while (timeout > 0 && !error);
}
uint32 FloppyRead(uint8 drive, uint32 lba)
{
if (drive >= 2) return 0;
uint8 fd = (drive == 0) ? fd0 : fd1;
// Convert LBA to CHS
uint32 cyl=0, head=0, sect=1;
ConvertLbaToChs(fdTypes[fd].SectorsPerTrack, lba, &cyl, &head, &sect);
Log("%#[Floppy] %#Converted LBA=%u to Cyl=%u Head=%u Sect=%u\n", ColorBrown, ColorLightGray, lba, cyl, head, sect);
FloppyInitDma();
// Reset drive if necessary
if ((inportb(FloppyRegisterMainStatus) & 0xC0) != 0x80)
FloppyReset();
// Start motor, select drive
FloppyMotor(drive, 1);
FloppySelectDrive(drive);
// Seek to correct location
FloppySeek(drive, cyl, head);
// Start DMA read
DmaMaskChannel(2);
DmaSetMode(2, 0x46);
DmaUnmaskChannel(2);
FloppyRW(0, drive, head, cyl, sect);
FloppyMotor(drive, 0);
return 0x1000;
}
// Log("%#[Drivers] %#Initializing blah blah %d...", ColorWhite, ColorLightGray,PIT_FREQUENCY);

View File

@ -0,0 +1,86 @@
/*
* floppy.h
*
* Created on: Aug 20, 2011
* Author: Tiberiu
*/
#ifndef FLOPPY_H_
#define FLOPPY_H_
#include <types.h>
enum FloppyRegisters
{
FloppyRegisterStatusA = 0x3F0, // read-only
FloppyRegisterStatusB = 0x3F1, // read-only
FloppyRegisterDigitalOutput = 0x3F2,
FloppyRegisterTapeDrive = 0x3F3,
FloppyRegisterMainStatus = 0x3F4, // read-only
FloppyRegisterDatarateSelect = 0x3F4, // write-only
FloppyRegisterFIFO = 0x3F5,
FloppyRegisterDigitalInput = 0x3F7, // read-only
FloppyRegisterConfigurationControl = 0x3F7 // write-only
};
enum FloppyCommands
{
FloppyCommandReadTrack = 2, // generates IRQ6
FloppyCommandSpecify = 3, // * set drive parameters
FloppyCommandSenseDriveStatus = 4,
FloppyCommandWriteData = 5, // * write to the disk
FloppyCommandReadData = 6, // * read from the disk
FloppyCommandRecalibrate = 7, // * seek to cylinder 0
FloppyCommandSenseInterrupt = 8, // * ack IRQ6, get status of last command
FloppyCommandWriteDeletedData = 9,
FloppyCommandReadID = 10, // generates IRQ6
FloppyCommandReadDeletedData = 12,
FloppyCommandFormatTrack = 13, // *
FloppyCommandSeek = 15, // * seek both heads to cylinder X
FloppyCommandVersion = 16, // * used during initialization, once
FloppyCommandScanEqual = 17,
FloppyCommandPerpendicularMode = 18, // * used during initialization, once, maybe
FloppyCommandConfigure = 19, // * set controller parameters
FloppyCommandLock = 20, // * protect controller params from a reset
FloppyCommandVerify = 22,
FloppyCommandScanLowOrEqual = 25,
FloppyCommandScanHighOrEqual = 29,
FloppyModeMultitrack = 0x80,
FloppyModeMagneticEncoding = 0x40, // always set for read/write/verify/format
FloppyModeSkip = 0x20
};
enum FloppyMSRMasks
{
FloppyMsrRQM = 0x80,
FloppyMsrDIO = 0x40,
FloppyMsrNDMA = 0x20,
FloppyMsrBusy = 0x10
};
typedef struct {
uint32 Size, SectorsPerTrack, Heads, Tracks;
uint8 Gap, DataRate, Spec1, SRT, HLT, HUT;
uint32 Spinup, Spindown, InterruptTimeout;
string Name;
} FloppyType;
extern void FloppyInitialize();
extern void FloppyIrqHandler(_RegsStack32 *r);
extern void FloppyWaitIrq();
extern void FloppyInitDma();
extern void FloppyReset();
extern void FloppyConfigure();
extern void FloppySendCommand (uint8 command);
extern uint8 FloppyReadData ();
extern void FloppySenseInterrupt(uint8 *st0, uint8 *cyl);
extern void FloppySpecify (uint8 fd);
extern void FloppyMotor (uint8 fd_number, uint8 status);
extern void FloppySelectDrive(uint8 number);
extern void FloppyRecalibrate(uint8 fd_number);
extern void FloppyRW(uint8 isWrite, uint8 fd_number, uint8 head, uint8 cylinder, uint8 sector);
extern uint32 FloppyRead(uint8 drive, uint32 lba);
#endif /* FLOPPY_H_ */

13
Kernel/drivers/pit/pit.c Normal file
View File

@ -0,0 +1,13 @@
#include <stdio.h>
#include <time.h>
#include "pit.h"
void PitSetFrequency(uint32 frequency)
{
uint32 divisor = 1193180 / frequency; // Calculate the divisor
outportb(0x43, 0x36); // Set our command byte 0x36
outportb(0x40, divisor & 0xff); // Set low byte
outportb(0x40, divisor>>8); // Set high byte
TimeSetInternalFrequency(frequency);
}

7
Kernel/drivers/pit/pit.h Normal file
View File

@ -0,0 +1,7 @@
#ifndef __PIT__H
#define __PIT__H
extern void PitSetFrequency(uint32 frequency);
#endif