I've been working on a project from scratch using as little Assembly as possible. But, I can't seem to figure out why my function read_disk() isn't reading into the buffer in bx register. To me it looks okay, but when I display the sector in hex to the screen it's all zeroed (not loaded). But I did have it working on an old commit Feb 16th of this year. Tried everything I could think of that might be the issue and none of it fixed the problem. The buffer was still blank. Any help in resolving this issue would be much appreciated. Thanks in advance.
P.S.: If you need help finding where something is in the code let me know and I'll be happy to guide you to where it's located at.
My ASM/C Floppy OS (Hobby OS)
EDIT: I fixed the issue, but I don't know how. Was messing around with setting up registers inside stdio.h in setup(). Also, changing linker scripts and now it works. Like I said, though I'm not sure how I fixed it. But this I guess is solved. Thanks all for your insight it was helpful.
Buffer not filled while reading disk in C/ASM, need help.
-
- Member
- Posts: 40
- Joined: Tue Jul 16, 2019 8:40 pm
Buffer not filled while reading disk in C/ASM, need help.
Last edited by psimonson1988 on Mon Feb 24, 2020 4:47 pm, edited 2 times in total.
Re: Buffer not filled while reading disk in C/ASM, need help
I didn't know your code as all, but if you want read/write to disc with int 0x13 you should use code like this:
Please, use that one head have 18 sectors and one cylinder have two heads 0 and 1. You can read very little part of disc.
But, if you work in C, I suggest you to write PIO driver for reading disc. You will can read all hard disc with it.
Code: Select all
mov ax, 0x1000 ;segment for data
mov es, ax ;set segment
mov bx, 0 ;offset for data
mov ah, 0x02 ;read function
mov al, 0 ;number of loaded sectors
mov ch, 0 ;cylinder
mov dh, 0 ;head
mov cl, 1 ;sector
mov dl, 0x80 ;hard disc
int 13h ;read
But, if you work in C, I suggest you to write PIO driver for reading disc. You will can read all hard disc with it.
Code: Select all
//my PIO48 driver
uint32_t paralel_ata(uint32_t base, uint64_t sector, uint16_t number_of_sectors, uint32_t type, uint32_t memory_pointer) {
uint16_t *buffer = (uint16_t *) memory_pointer;
uint32_t cycle=0;
uint32_t offset=0;
//PIO48
outb(base+2, (unsigned char)(number_of_sectors >> 8));
outb(base+3, (unsigned char)(sector >> 24));
outb(base+4, (unsigned char)(sector >> 32));
outb(base+5, (unsigned char)(sector >> 40));
outb(base+2, (unsigned char)number_of_sectors);
outb(base+3, (unsigned char)sector);
outb(base+4, (unsigned char)(sector >> 8));
outb(base+5, (unsigned char)(sector >> 16));
//type
if(type==READ) {
outb(base+7, 0x24); //Send command read
}
else {
outb(base+7, 0x34); //Send command write
}
//wait for BSY clear and DRQ set
cycle=0;
for(int i=0; i<1000; i++) {
wait(1);
if( (inb(base+0x206) & 0x88)==0x08 ) { //drq is set
cycle=1;
break;
}
}
if(cycle==0) { //Something is wrong
if( (inb(base+0x206) & 0x01)==0x01 ) { //bad block
ata_error();
}
return 0;
}
if( (inb(base+0x206) & 0x01)==0x01 ) { //bad block
ata_error();
}
for(int i=0; i<number_of_sectors; i++) {
for (int j=0; j<256; j++) {
if(type==READ) {
buffer[offset] = inw(base + 0);
}
else {
outw(base + 0, buffer[offset]);
}
offset++;
}
}
return 1;
}
Re: Buffer not filled while reading disk in C/ASM, need help
In boot.asm the disk read code looks fine, so you already know how to do it.
But in disk.c I can't find any register being set. They are used like %ax, %al and so on.
Did I overlook something or did you miss that?
But in disk.c I can't find any register being set. They are used like %ax, %al and so on.
Did I overlook something or did you miss that?
-
- Member
- Posts: 5575
- Joined: Mon Mar 25, 2013 7:01 pm
Re: Buffer not filled while reading disk in C/ASM, need help
Set a breakpoint on the INT 0x13 instruction and dump all of the registers (including segment registers) to see what values they have before the BIOS is called. Do all the registers (including segment registers) have sensible values? Check afterwards too, in case the BIOS is reporting an error but your code isn't recognizing it.psimonson1988 wrote:Any help in resolving this issue would be much appreciated.
If you're a retro hardware enthusiast, you might want to keep in mind that the geometry for a floppy disk is not necessarily the same as the geometry of the floppy disk drive. (This is unlikely to be a concern if you're only using 1.44MB disks.)
This is handled by the constraints in the inline assembly. You can read about it in the GCC manual.PeterX wrote:But in disk.c I can't find any register being set.
-
- Member
- Posts: 40
- Joined: Tue Jul 16, 2019 8:40 pm
Re: Buffer not filled while reading disk in C/ASM, need help
Well bx is being set, that's why I can't figure out why it doesn't work anymore. It used to I haven't changed my disk functions all that much. If you clone that url with git and then check out the last commit on Feb 16th. That code works and I've compared the two and can't understand why the older one works and the new one does not.
Oh by the way, "a"(val), "b"(buffer), "c"((c << 8) | s), "d"((h << 8) | p->drive) is how you set ax, bx, cx, and dx in GNU inline assembly. Just in case you didn't know.
@Klakap Thanks for the suggestion and sample driver code.
@Octocontrabass Thanks for the debugging tip.
EDIT: What debugger can I use on a custom OS? bochs or gdb or ... ???
Oh by the way, "a"(val), "b"(buffer), "c"((c << 8) | s), "d"((h << 8) | p->drive) is how you set ax, bx, cx, and dx in GNU inline assembly. Just in case you didn't know.
@Klakap Thanks for the suggestion and sample driver code.
@Octocontrabass Thanks for the debugging tip.
EDIT: What debugger can I use on a custom OS? bochs or gdb or ... ???