So I rewrote it from scratch (both the DMA "driver" and the FDC driver) and the same exact thing happens, same junk. It's just faster. (which is irrelevant)
Honestly I'm at a dead end. I've looked over the code many times and I don't see anything wrong. I would assume it's with the DMA but it looks fine to me.
DMA:
Code: Select all
void dma_mask_channel(uint8_t channel){
if (channel<=4){
outportb(0x0a,(1 << (channel-1)));
}else{
outportb(0xd4,(1 << (channel-5)));
}
}
void dma_unmask(uint8_t channel){//Chan2=0x6
if (channel<=4){
outportb(0x0a,channel);
}else{
outportb(0xd4,channel);
}
}
void dma_unmask_all(){
outportb(0xdc,0xff);
}
void dma_reset(){
outportb(0x0c,0xff);
}
void dma_reset_flipflop(){
outportb(0xd8,0xff);
}
void dma_set_address(uint8_t low, uint8_t high){
outportb(0x04,low);
outportb(0x04,high);
}
void dma_set_count(uint8_t low, uint8_t high){
outportb(0x05,low);
outportb(0x05,high);
}
void dma_set_epr(uint8_t addr){
outportb(0x81,addr);
}
export void _cdecl dma_set_read(){
dma_mask_channel(2);
outportb(0x0b,0x56);
dma_unmask_all();
}
export void _cdecl dma_set_write(){
dma_mask_channel(2);
outportb(0x0b,0x5a);
dma_unmask_all();
}
export bool _cdecl dma_initialize_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)0x500;//buffer
c.l=(unsigned)length-1;
//Check for buffer issues
if ((a.l >> 24) || (c.l >> 16) || (((a.l & 0xffff)+c.l) >> 16)){
#ifdef _DEBUG
_asm{
mov eax, 0x1337
cli
hlt
}
#endif
return false;
}
dma_reset();//Hard reset
dma_mask_channel(2);//Mask channel 2
dma_reset_flipflop();//Flipflop reset
dma_set_address(a.byte[0],a.byte[1]);//Buffer address
dma_set_epr(a.byte[2]);//Set page register
dma_reset_flipflop();//Flipflop reset
dma_set_count(c.byte[0],c.byte[1]);//Set count
outportb(0x0b,0x56);//Set the dma to read when initialized
dma_unmask_all();//Unmask channel 2
return true;
}
So I guess what I'm asking is does anyone see anything wrong with that?
If not, any ideas on what could possibly cause this?