DMA Is Basically Done, Just need to work out some kinks
This commit is contained in:
parent
8197dcc01d
commit
4bb606a7cf
@ -11,6 +11,9 @@
|
||||
#include <arch/i686/io.h>
|
||||
#include <arch/i686/irq.h>
|
||||
#include <dri/serial.h>
|
||||
#include <dri/dma/dma.h>
|
||||
|
||||
uint8_t* DMA_BUFFER;
|
||||
|
||||
extern uint16_t DEBUG_COM_PORT;
|
||||
|
||||
@ -115,6 +118,9 @@ uint8_t Floppy_Read_Data()
|
||||
void Floppy_Read_Sector_CHS(uint8_t head, uint8_t track, uint8_t sector)
|
||||
{
|
||||
uint32_t st0, cyl;
|
||||
|
||||
DMA_Init_Floppy((uint8_t*)DMA_BUFFER, 512);
|
||||
DMA_Set_Read(FLOPPY_DMA_CHANNEL);
|
||||
|
||||
// set the DMA for read transfer
|
||||
Floppy_DMA_Read();
|
||||
@ -289,7 +295,7 @@ uint8_t* Floppy_Read_Sector(int sectorLBA)
|
||||
Floppy_Motor_Control(false);
|
||||
|
||||
// this is a bit hackish, but ofc i dont care. (also still need to implement DMA lolololololol)
|
||||
// return (uint8_t*) DMA_BUFFER;
|
||||
return (uint8_t*) DMA_BUFFER;
|
||||
}
|
||||
|
||||
void Floppy_Motor_Control(bool enable)
|
||||
|
||||
@ -5,21 +5,25 @@
|
||||
\*----------------*/
|
||||
#include "dma.h"
|
||||
|
||||
#include <arch/i686/io.h>
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
void DMA_Set_Address(uint8_t channel, uint8_t low, uint8_t high)
|
||||
{
|
||||
if ( channel > 8 )
|
||||
if (channel > 8)
|
||||
return;
|
||||
|
||||
unsigned short port = 0;
|
||||
switch ( channel ) {
|
||||
case 0: {port = DMA0_CHANNNEL0_ADDR_REG; break;}
|
||||
case 1: {port = DMA0_CHANNNEL1_ADDR_REG; break;}
|
||||
case 2: {port = DMA0_CHANNNEL2_ADDR_REG; break;}
|
||||
case 3: {port = DMA0_CHANNNEL3_ADDR_REG; break;}
|
||||
case 4: {port = DMA1_CHANNNEL4_ADDR_REG; break;}
|
||||
case 5: {port = DMA1_CHANNNEL5_ADDR_REG; break;}
|
||||
case 6: {port = DMA1_CHANNNEL6_ADDR_REG; break;}
|
||||
case 7: {port = DMA1_CHANNNEL7_ADDR_REG; break;}
|
||||
uint16_t port = 0;
|
||||
switch (channel) {
|
||||
case 0: {port = DMA0_CHANNEL0_ADDR_REG; break;}
|
||||
case 1: {port = DMA0_CHANNEL1_ADDR_REG; break;}
|
||||
case 2: {port = DMA0_CHANNEL2_ADDR_REG; break;}
|
||||
case 3: {port = DMA0_CHANNEL3_ADDR_REG; break;}
|
||||
case 4: {port = DMA1_CHANNEL4_ADDR_REG; break;}
|
||||
case 5: {port = DMA1_CHANNEL5_ADDR_REG; break;}
|
||||
case 6: {port = DMA1_CHANNEL6_ADDR_REG; break;}
|
||||
case 7: {port = DMA1_CHANNEL7_ADDR_REG; break;}
|
||||
}
|
||||
|
||||
outb(port, low);
|
||||
@ -33,33 +37,32 @@ void DMA_Set_Count(uint8_t channel, uint8_t low, uint8_t high)
|
||||
|
||||
unsigned short port = 0;
|
||||
switch (channel) {
|
||||
case 0: {port = DMA0_CHANNNEL0_COUNT_REG; break;}
|
||||
case 1: {port = DMA0_CHANNNEL1_COUNT_REG; break;}
|
||||
case 2: {port = DMA0_CHANNNEL2_COUNT_REG; break;}
|
||||
case 3: {port = DMA0_CHANNNEL3_COUNT_REG; break;}
|
||||
case 4: {port = DMA1_CHANNNEL4_COUNT_REG; break;}
|
||||
case 5: {port = DMA1_CHANNNEL5_COUNT_REG; break;}
|
||||
case 6: {port = DMA1_CHANNNEL6_COUNT_REG; break;}
|
||||
case 7: {port = DMA1_CHANNNEL7_COUNT_REG; break;}
|
||||
case 0: {port = DMA0_CHANNEL0_COUNT_REG; break;}
|
||||
case 1: {port = DMA0_CHANNEL1_COUNT_REG; break;}
|
||||
case 2: {port = DMA0_CHANNEL2_COUNT_REG; break;}
|
||||
case 3: {port = DMA0_CHANNEL3_COUNT_REG; break;}
|
||||
case 4: {port = DMA1_CHANNEL4_COUNT_REG; break;}
|
||||
case 5: {port = DMA1_CHANNEL5_COUNT_REG; break;}
|
||||
case 6: {port = DMA1_CHANNEL6_COUNT_REG; break;}
|
||||
case 7: {port = DMA1_CHANNEL7_COUNT_REG; break;}
|
||||
}
|
||||
outb(port, low);
|
||||
outb(port, high);
|
||||
}
|
||||
|
||||
void DMA_Set_External_Page_Register(uint8_t register, uint8_t value)
|
||||
void DMA_Set_External_Page_Register(uint8_t reg, uint8_t value)
|
||||
{
|
||||
if (register > 14)
|
||||
return;
|
||||
if (reg > 14) return;
|
||||
|
||||
unsigned short port = 0;
|
||||
switch (register) {
|
||||
case 1: {port = DMA_PAGE_CHAN1_ADDRBYTE2; break;}
|
||||
case 2: {port = DMA_PAGE_CHAN2_ADDRBYTE2; break;}
|
||||
case 3: {port = DMA_PAGE_CHAN3_ADDRBYTE2; break;}
|
||||
switch (reg) {
|
||||
case 1: {port = DMA_PAGE_CHANNEL1_ADDRBYTE2; break;}
|
||||
case 2: {port = DMA_PAGE_CHANNEL2_ADDRBYTE2; break;}
|
||||
case 3: {port = DMA_PAGE_CHANNEL3_ADDRBYTE2; break;}
|
||||
case 4: {return;}// nothing should ever write to register 4
|
||||
case 5: {port = DMA_PAGE_CHAN5_ADDRBYTE2; break;}
|
||||
case 6: {port = DMA_PAGE_CHAN6_ADDRBYTE2; break;}
|
||||
case 7: {port = DMA_PAGE_CHAN7_ADDRBYTE2; break;}
|
||||
case 5: {port = DMA_PAGE_CHANNEL5_ADDRBYTE2; break;}
|
||||
case 6: {port = DMA_PAGE_CHANNEL6_ADDRBYTE2; break;}
|
||||
case 7: {port = DMA_PAGE_CHANNEL7_ADDRBYTE2; break;}
|
||||
}
|
||||
outb(port, value);
|
||||
}
|
||||
@ -69,9 +72,9 @@ void DMA_Set_Mode(uint8_t channel, uint8_t mode)
|
||||
int dma = (channel < 4) ? 0 : 1;
|
||||
int chan = (dma==0) ? channel : channel-4;
|
||||
|
||||
dma_mask_channel (channel);
|
||||
outportb ( (channel < 4) ? (DMA0_MODE_REG) : DMA1_MODE_REG, chan | (mode) );
|
||||
dma_unmask_all ( dma );
|
||||
DMA_Mask_Channel(channel);
|
||||
outb((channel < 4) ? (DMA0_MODE_REG) : DMA1_MODE_REG, chan | (mode));
|
||||
DMA_Unmask_All(dma);
|
||||
}
|
||||
|
||||
// prepares channel for read
|
||||
@ -80,8 +83,73 @@ void DMA_Set_Read(uint8_t channel)
|
||||
DMA_Set_Mode(channel, DMA_MODE_READ_TRANSFER | DMA_MODE_TRANSFER_SINGLE | DMA_MODE_MASK_AUTO);
|
||||
}
|
||||
|
||||
//! prepares channel for write
|
||||
// prepares channel for write
|
||||
void DMA_Set_Write(uint8_t channel)
|
||||
{
|
||||
DMA_Set_Mode(channel, DMA_MODE_WRITE_TRANSFER | DMA_MODE_TRANSFER_SINGLE | DMA_MODE_MASK_AUTO);
|
||||
}
|
||||
|
||||
void DMA_Mask_Channel(uint8_t channel)
|
||||
{
|
||||
if (channel <= 4)
|
||||
outb(DMA0_CHANNELMASK_REG, (1 << (channel-1)));
|
||||
else
|
||||
outb(DMA1_CHANNELMASK_REG, (1 << (channel-5)));
|
||||
}
|
||||
|
||||
void DMA_Unmask_Channel(uint8_t channel)
|
||||
{
|
||||
if (channel <= 4)
|
||||
outb(DMA0_CHANNELMASK_REG, channel);
|
||||
else
|
||||
outb(DMA1_CHANNELMASK_REG, channel);
|
||||
}
|
||||
|
||||
void DMA_Unmask_All(int dma)
|
||||
{
|
||||
outb(DMA1_UNMASK_ALL_REG, 0xff);
|
||||
}
|
||||
|
||||
// Groan...
|
||||
|
||||
void DMA_Reset_Flipflop(int dma)
|
||||
{
|
||||
if (dma < 2)
|
||||
return;
|
||||
outb( (dma==0) ? DMA0_CLEARBYTE_FLIPFLOP_REG : DMA1_CLEARBYTE_FLIPFLOP_REG, 0xff);
|
||||
}
|
||||
|
||||
void DMA_Reset(int dma)
|
||||
{
|
||||
outb(DMA0_TEMP_REG, 0xff);
|
||||
}
|
||||
|
||||
bool DMA_Init_Floppy(uint8_t* buffer, unsigned length)
|
||||
{
|
||||
union{
|
||||
uint8_t byte[4];//Lo[0], Mid[1], Hi[2]
|
||||
unsigned long l;
|
||||
}a, c;
|
||||
|
||||
a.l=(unsigned)buffer;
|
||||
c.l=(unsigned)length-1;
|
||||
|
||||
//Check for buffer issues
|
||||
if ((a.l >> 24) || (c.l >> 16) || (((a.l & 0xffff)+c.l) >> 16)){
|
||||
return false;
|
||||
}
|
||||
|
||||
DMA_Reset(1);
|
||||
DMA_Mask_Channel(FLOPPY_DMA_CHANNEL );//Mask channel 2
|
||||
DMA_Reset_Flipflop( 1 );//Flipflop reset on DMA 1
|
||||
|
||||
DMA_Set_Address(FLOPPY_DMA_CHANNEL, a.byte[0],a.byte[1]);//Buffer address
|
||||
DMA_Reset_Flipflop(1);//Flipflop reset on DMA 1
|
||||
|
||||
DMA_Set_Count(FLOPPY_DMA_CHANNEL, c.byte[0],c.byte[1]);//Set count
|
||||
DMA_Set_Read(FLOPPY_DMA_CHANNEL );
|
||||
|
||||
DMA_Unmask_All(1);//Unmask channel 2
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -5,12 +5,30 @@
|
||||
\*----------------*/
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#define FLOPPY_DMA_CHANNEL 2
|
||||
|
||||
void DMA_Reset_Flipflop(int dma);
|
||||
void DMA_Set_Address(uint8_t channel, uint8_t low, uint8_t high);
|
||||
void DMA_Set_Count(uint8_t channel, uint8_t low, uint8_t high);
|
||||
void DMA_Set_External_Page_Register(uint8_t register, uint8_t value);
|
||||
void DMA_Set_Mode(uint8_t channel, uint8_t mode);
|
||||
void DMA_Set_Read(uint8_t channel);
|
||||
void DMA_Set_Write(uint8_t channel);
|
||||
void DMA_Mask_Channel(uint8_t channel);
|
||||
void DMA_Unmask_Channel(uint8_t channel);
|
||||
void DMA_Unmask_All(int dma);
|
||||
void DMA_Reset(int dma);
|
||||
bool DMA_Init_Floppy(uint8_t* buffer, unsigned length);
|
||||
|
||||
enum DMA0_IO {
|
||||
|
||||
DMA0_STATUS_REG = 0x08,
|
||||
DMA0_COMMAND_REG = 0x08,
|
||||
DMA0_REQUEST_REG = 0x09,
|
||||
DMA0_CHANMASK_REG = 0x0a,
|
||||
DMA0_CHANNELMASK_REG = 0x0a,
|
||||
DMA0_MODE_REG = 0x0b,
|
||||
DMA0_CLEARBYTE_FLIPFLOP_REG = 0x0c,
|
||||
DMA0_TEMP_REG = 0x0d,
|
||||
@ -24,7 +42,7 @@ enum DMA1_IO {
|
||||
DMA1_STATUS_REG = 0xd0,
|
||||
DMA1_COMMAND_REG = 0xd0,
|
||||
DMA1_REQUEST_REG = 0xd2,
|
||||
DMA1_CHANMASK_REG = 0xd4,
|
||||
DMA1_CHANNELMASK_REG = 0xd4,
|
||||
DMA1_MODE_REG = 0xd6,
|
||||
DMA1_CLEARBYTE_FLIPFLOP_REG = 0xd8,
|
||||
DMA1_INTER_REG = 0xda,
|
||||
@ -46,14 +64,14 @@ enum DMA0_CHANNEL_IO {
|
||||
|
||||
enum DMA1_CHANNEL_IO {
|
||||
|
||||
DMA1_CHANNNEL4_ADDR_REG = 0xc0,
|
||||
DMA1_CHANNNEL4_COUNT_REG = 0xc2,
|
||||
DMA1_CHANNNEL5_ADDR_REG = 0xc4,
|
||||
DMA1_CHANNNEL5_COUNT_REG = 0xc6,
|
||||
DMA1_CHANNNEL6_ADDR_REG = 0xc8,
|
||||
DMA1_CHANNNEL6_COUNT_REG = 0xca,
|
||||
DMA1_CHANNNEL7_ADDR_REG = 0xcc,
|
||||
DMA1_CHANNNEL7_COUNT_REG = 0xce,
|
||||
DMA1_CHANNEL4_ADDR_REG = 0xc0,
|
||||
DMA1_CHANNEL4_COUNT_REG = 0xc2,
|
||||
DMA1_CHANNEL5_ADDR_REG = 0xc4,
|
||||
DMA1_CHANNEL5_COUNT_REG = 0xc6,
|
||||
DMA1_CHANNEL6_ADDR_REG = 0xc8,
|
||||
DMA1_CHANNEL6_COUNT_REG = 0xca,
|
||||
DMA1_CHANNEL7_ADDR_REG = 0xcc,
|
||||
DMA1_CHANNEL7_COUNT_REG = 0xce,
|
||||
};
|
||||
|
||||
enum DMA0_PAGE_REG {
|
||||
|
||||
@ -36,6 +36,8 @@ void Keyboard_Handler()
|
||||
|
||||
// If CTRL+ALT+DEL Reboot
|
||||
if(_keyboard_scancode == 224 && _ctrl == true && _alt == true) Reboot();
|
||||
// If CTRL+ALT+ESC Shut Down
|
||||
if(_keyboard_scancode == 1 && _ctrl == true && _alt == true); // Shutdown();
|
||||
}
|
||||
|
||||
uint8_t Keyboard_Controller_Status()
|
||||
|
||||
@ -64,18 +64,17 @@ void __attribute__((section(".entry"))) start(BootParams* bootParams) {
|
||||
printf("Initializing Basic Drivers...");
|
||||
Serial_Init(DEBUG_COM_PORT, 9600);
|
||||
Keyboard_Init();
|
||||
Floppy_Init(); // This should always be last; its slow as fuck
|
||||
// Floppy_Init(); // This should always be last; its slow as fuck
|
||||
printf("Done!\n");
|
||||
|
||||
|
||||
|
||||
|
||||
// Debug Info for Memory
|
||||
Serial_Printf(DEBUG_COM_PORT, "Memory Debug Info:\n");
|
||||
Serial_Printf(DEBUG_COM_PORT, "Boot Device: %x\n", bootParams->BootDevice);
|
||||
Serial_Printf(DEBUG_COM_PORT, "Memory Region Count: %x\n", bootParams->Memory.RegionCount);
|
||||
Serial_Printf(DEBUG_COM_PORT, "MEMORY:> Boot Device: %x\n", bootParams->BootDevice);
|
||||
Serial_Printf(DEBUG_COM_PORT, "MEMORY:> Region Count: %x\n", bootParams->Memory.RegionCount);
|
||||
for (int i = 0; i < bootParams->Memory.RegionCount; i++) {
|
||||
Serial_Printf(DEBUG_COM_PORT, "Memory: start=0x%llx length=0x%llx type=0x%x\n",
|
||||
Serial_Printf(DEBUG_COM_PORT, "MEMORY:> start=0x%llx length=0x%llx type=0x%x\n",
|
||||
bootParams->Memory.Regions[i].Begin, bootParams->Memory.Regions[i].Length, bootParams->Memory.Regions[i].Type);
|
||||
}
|
||||
|
||||
|
||||
@ -6,5 +6,5 @@
|
||||
#pragma once
|
||||
|
||||
#define LOGO " _ _____ _ __________________\n / | / / | / | / / _/_ __/ ____/\n / |/ / /| | / |/ // / / / / __/ \n / /| / ___ |/ /| // / / / / /___ \n/_/ |_/_/ |_/_/ |_/___/ /_/ /_____/ \n"
|
||||
#define VERSION "RD-00032"
|
||||
#define VERSION "RD-00033"
|
||||
#define BOOTLOGO " _ ______ ____ ____ ______\n / | / / __ )/ __ \\/ __ /_ __/\n / |/ / __ / / / / / / // / \n / /| / /_/ / /_/ / /_/ // / \n/_/ |_/_____/\\____/\\____//_/ \n"
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user