Page 1 of 1

Floppy Reading Problem

Posted: Wed Aug 02, 2006 2:20 am
by Tolga
Hi. I wrote my floppy driver. For all functions, i looked to intel document. Now my read_sector function doing something with floppy. I setup DMA to 512 byte and address 0. But after reading function, im writing 512 byte character to screen from address 0. I understand that it is not readed. Can the problem be about DMA?

After Reading operation, Results;

Status Register 0 = 0;
Status Register 1 = 0;
Status Register 2 = 0;
Cylinder = 0;
Head = 0;
Sector = 2; (Im reading sector 1)

Re:Floppy Reading Problem

Posted: Wed Aug 02, 2006 4:37 am
by Pype.Clicker
do you mean "address 0" like in "bootsector" or like in "real-mode interrupt vector table" ?

Re:Floppy Reading Problem

Posted: Wed Aug 02, 2006 5:21 am
by Tolga
This process in pmode and im reading floppy sector 1. (First sector). And address 0 is memory address. (Real mode interrupt vector table area)

Re:Floppy Reading Problem

Posted: Wed Aug 02, 2006 7:49 am
by Tolga
DMA setup code:

Code: Select all

// Setup DMA (For 1 Sector)
void tfdc::setup_dma()
{
   // Stop Interrupts
   cli();
   
   // Select DMA
   dma.select_channel( 2 );
   dma.set_ports();
   
   // Disable Channel
   dma.disable_channel();
   
   // Clear Regs
   dma.clear_flip_flop();
   
   // Set Mode
   dma.set_control_byte( dma_single_mode, dma_address_increment, dma_auto_initialization, dma_read_transfer );
   
   // Set Offset
   dma.set_address( 0 );
   
   // Set Size
   dma.set_transfer_length( 512 );
   
   // Set Mask (Enable Channel)
   dma.enable_channel();
   
   // Enable Interrupts
   sti();
}

Re:Floppy Reading Problem

Posted: Wed Aug 02, 2006 2:45 pm
by Tolga
Everybody designing file system. :'( After i solve this problem, i too. Please help me. Im looking to results. I think there is no error at reading. can the problem be about DMA?

Re:Floppy Reading Problem

Posted: Wed Aug 02, 2006 4:04 pm
by Slasher
We need the code in full to know if its DMA that is the problem.
eg
dma.set_ports();

can't help without knowing what you are doing in the functions.

Re:Floppy Reading Problem

Posted: Wed Aug 02, 2006 10:07 pm
by Tolga
Full of DMA.CPP

Code: Select all

// DMA HEADER CODE

// PREPROCESSOR
#include "dma.h"
#include "system.h"


// DEFINITONS
// = Channels & Ports =
// 8 Bit
#define dma_channel_0_address_port      0x00
#define dma_channel_0_count_port      0x01
#define dma_channel_0_page_port         0x87

#define dma_channel_1_address_port      0x02
#define dma_channel_1_count_port      0x03
#define dma_channel_1_page_port         0x83

#define dma_channel_2_address_port      0x04
#define dma_channel_2_count_port      0x05
#define dma_channel_2_page_port         0x81

#define dma_channel_3_address_port      0x06
#define dma_channel_3_count_port      0x07
#define dma_channel_3_page_port         0x82

// 16 Bit
#define dma_channel_4_address_port      0xC0
#define dma_channel_4_count_port      0xC2
#define dma_channel_4_page_port         0x8F

#define dma_channel_5_address_port      0xC4
#define dma_channel_5_count_port      0xC6
#define dma_channel_5_page_port         0x8B

#define dma_channel_6_address_port      0xC8
#define dma_channel_6_count_port      0xCA
#define dma_channel_6_page_port         0x89

#define dma_channel_7_address_port      0xCC
#define dma_channel_7_count_port      0xCE
#define dma_channel_7_page_port         0x8A


// = Write Mode =
#define dma_8_bit_write_mode         0x0B
#define dma_16_bit_write_mode         0xD6


// = Single Mask Register =
#define dma_8_bit_single_mask_register   0x0A
#define dma_16_bit_single_mask_register   0xD4


// = Clear Byte Pointer =
#define dma_8_bit_clear_byte_pointer   0x0C
#define dma_16_bit_clear_byte_pointer   0xD8



// CLASS CODE
// Select Channel
void tdma::select_channel( unsigned char dma_channel_number )
{
   // Control
   if(dma_channel_number < 8)
   dma_channel   = dma_channel_number;
}


// Set Ports
void tdma::set_ports()
{
   // Set Ports
   switch(dma_channel)
   {
      case 0:
         dma_address_port   = dma_channel_0_address_port;
         dma_count_port      = dma_channel_0_count_port;
         dma_page_port      = dma_channel_0_page_port;
         break;

      case 1:
         dma_address_port   = dma_channel_1_address_port;
         dma_count_port      = dma_channel_1_count_port;
         dma_page_port      = dma_channel_1_page_port;
         break;

      case 2:
         dma_address_port   = dma_channel_2_address_port;
         dma_count_port      = dma_channel_2_count_port;
         dma_page_port      = dma_channel_2_page_port;
         break;

      case 3:
         dma_address_port   = dma_channel_3_address_port;
         dma_count_port      = dma_channel_3_count_port;
         dma_page_port      = dma_channel_3_page_port;
         break;

      case 4:
         dma_address_port   = dma_channel_4_address_port;
         dma_count_port      = dma_channel_4_count_port;
         dma_page_port      = dma_channel_4_page_port;
         break;

      case 5:
         dma_address_port   = dma_channel_5_address_port;
         dma_count_port      = dma_channel_5_count_port;
         dma_page_port      = dma_channel_5_page_port;
         break;

      case 6:
         dma_address_port   = dma_channel_6_address_port;
         dma_count_port      = dma_channel_6_count_port;
         dma_page_port      = dma_channel_6_page_port;
         break;

      case 7:
         dma_address_port   = dma_channel_7_address_port;
         dma_count_port      = dma_channel_7_count_port;
         dma_page_port      = dma_channel_7_page_port;
         break;
   }


   // Register
   if(dma_channel < 4)
   {
      dma_mode_register   = dma_8_bit_write_mode;
      dma_mask_register   = dma_8_bit_single_mask_register;
      dma_clear_register   = dma_8_bit_clear_byte_pointer;
   }
   else
   {
      dma_mode_register   = dma_16_bit_write_mode;
      dma_mask_register   = dma_16_bit_single_mask_register;
      dma_clear_register   = dma_16_bit_clear_byte_pointer;
   }
}


// Enable Channel
void tdma::enable_channel()
{
   // Enable Channel
   outport( dma_mask_register, (dma_channel % 4) );
}


// Disable Channel
void tdma::disable_channel()
{
   // Disable Channel
   outport( dma_mask_register, 4 + (dma_channel % 4) );
}


// Clear Flip Flop
void tdma::clear_flip_flop()
{
   // Clear Flip Flop
   outport( dma_clear_register, 0 );
}


// Set Transfer Length
void tdma::set_transfer_length( unsigned short tlength )
{
   // Assign
   dma_transfer_length      = tlength;

   // Set Transfer Length
   outport( dma_count_port, ((tlength - 1) & 0xFF) );
   outport( dma_count_port, ((tlength - 1) >> 8) & 0xFF );
}


// Set Control Byte
void tdma::set_control_byte( unsigned char mode_selection, unsigned char addr_inc_dec, unsigned char auto_int, unsigned char transfer_type )
{
   // Set Control Byte
   outport( dma_mode_register, mode_selection + addr_inc_dec + auto_int + transfer_type + dma_channel );
}


// Set Memory Address
void tdma::set_address( unsigned long maddr )
{
   // Variables
   unsigned short   offset_addr;
   unsigned char   page_addr;

   // Assign
   dma_memory_address   = maddr;

   // Calculate
   offset_addr      = maddr & 0xFFFF;
   page_addr      = (maddr >> 16) & 0xFF;

   // Control
   if(dma_channel > 3)
   {
      offset_addr   = offset_addr >> 1;
   }

   // Send
   outport( dma_page_port, page_addr );
   outport( dma_address_port, (offset_addr & 0xFF) );
   outport( dma_address_port, (offset_addr >> 8) & 0xFF );
}

Re:Floppy Reading Problem

Posted: Thu Aug 03, 2006 5:10 am
by Tolga
I wrote the code. Is there any reply?

Re:Floppy Reading Problem

Posted: Thu Aug 03, 2006 8:47 am
by Kemp
Just a quick note for the future, with long code listings it's usually considered polite to attach them rather than dump them in the post.

Re:Floppy Reading Problem

Posted: Thu Aug 03, 2006 10:53 am
by Tolga
Thanks for warning. But i need help for pursuance of my os.

Re:Floppy Reading Problem

Posted: Fri Aug 04, 2006 6:03 am
by Pype.Clicker
Maybe there are people here that can tell you what's been wrong with your DMA transfer "just like that", but when it come to floppy, i can't.

So what i'd try to see is:
A) whether the floppy actually undertsood the command or not (i guess the fact the 'next sector' is two is a good clue, tough i cannot be assured).
B) whether the DMA did transfer things or not. Iirc, you should have some "byte counter" associated with each DMA channel, right ? if the channel was properly programmed and the transfer did take place, you should end up with a "remaining byte count" of 0 in the DMA registers.
C) whether the data you transferred were written or not. the internal debugger of bochs or qemu should help you do that.

If i can afford a suggestion, i'd say using the realmode IVT may not be the best location around... I'd rather use anything else as a transfer buffer (including using the VRAM directly as buffer :)

Re:Floppy Reading Problem

Posted: Fri Aug 04, 2006 7:25 am
by Tolga
1. I found the problem. I used DMA_Write(01b) for DMA transfer type and it has been running. But i dont understand. Is "DMA_Write"'s mean that write to memory? (I understand that write to disk; and this is wrong idea. ;)

2. If i want to read many sectors, must i do recalibration, start motor and others for each sector reading?

Re:Floppy Reading Problem

Posted: Fri Aug 04, 2006 7:48 pm
by blip
1. According to the OsFaq, 01b would mean read from device and write to memory.

2. If you keep the motor going, you don't need to start it again. Recalibrate only on error conditions and don't infinitely retry operations.

Pype.Clicker: Does that actually work? At any rate, I don't think it's a good idea to try DMA'ing to VRAM for testing like this. I don't think it would work, but I've never actually tried, and even if it did I wouldn't count on it working on every machine out there. Maybe it would overwrite the SMI handler and data on some machines?

Re:Floppy Reading Problem

Posted: Sat Aug 05, 2006 4:24 pm
by Pype.Clicker
@blip: honnestly i see no reason why it wouldn't work. If you were requesting the BIOS to load a bmp from floppy sectors straight on screen, that'd be what you'll be doing, right ?
That's not like if DMA chip was somehow hardwired with your main memory. It just initiates memory read/write cycles, and i don't see why issueing cycles to 0xB8000 would be different from issueing cycles to 0x08000. I've done it in the past, and have even been using DMA to move stuff from VRAM to VRAM to implement a DMA-assisted scrolling (well, that was just before i learnt about VGA registers :P)

Now, maybe there exist some odd laptops where something magic occurs when you write things from the CPU to 0xB8000 and where those things wouldn't occur if you write directly from a IO device such as floppy, HDD or whatever. If you have the proof of such evil laptop existence, that just comformts me that i'm going to focus more on nintendo DS than PC in the next years.