[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:
		
							
								
								
									
										63
									
								
								Kernel/drivers/cmos/cmos.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										63
									
								
								Kernel/drivers/cmos/cmos.c
									
									
									
									
									
										Normal 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));
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										12
									
								
								Kernel/drivers/cmos/cmos.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								Kernel/drivers/cmos/cmos.h
									
									
									
									
									
										Normal 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
									
								
							
							
						
						
									
										111
									
								
								Kernel/drivers/dma/dma.c
									
									
									
									
									
										Normal 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
									
								
							
							
						
						
									
										80
									
								
								Kernel/drivers/dma/dma.h
									
									
									
									
									
										Normal 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
									
								
							
							
						
						
									
										34
									
								
								Kernel/drivers/drivers.c
									
									
									
									
									
										Normal 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
									
								
							
							
						
						
									
										6
									
								
								Kernel/drivers/drivers.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,6 @@
 | 
			
		||||
#ifndef __DRIVERS__H
 | 
			
		||||
#define __DRIVERS__H
 | 
			
		||||
 | 
			
		||||
extern void DriversInstall();
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
							
								
								
									
										384
									
								
								Kernel/drivers/floppy/floppy.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										384
									
								
								Kernel/drivers/floppy/floppy.c
									
									
									
									
									
										Normal 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, §);
 | 
			
		||||
	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);
 | 
			
		||||
							
								
								
									
										86
									
								
								Kernel/drivers/floppy/floppy.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										86
									
								
								Kernel/drivers/floppy/floppy.h
									
									
									
									
									
										Normal 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
									
								
							
							
						
						
									
										13
									
								
								Kernel/drivers/pit/pit.c
									
									
									
									
									
										Normal 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
									
								
							
							
						
						
									
										7
									
								
								Kernel/drivers/pit/pit.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,7 @@
 | 
			
		||||
#ifndef __PIT__H
 | 
			
		||||
#define __PIT__H
 | 
			
		||||
 | 
			
		||||
extern void PitSetFrequency(uint32 frequency);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
		Reference in New Issue
	
	Block a user