DMA Is Basically Done, Just need to work out some kinks

This commit is contained in:
Tyler McGurrin 2025-06-04 16:26:11 -04:00
parent 8197dcc01d
commit 4bb606a7cf
6 changed files with 143 additions and 50 deletions

View File

@ -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)

View File

@ -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;
}

View File

@ -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 {

View File

@ -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()

View File

@ -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);
}

View File

@ -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"