atapi cdrom read problem
Posted: Thu Jun 09, 2016 5:08 am
I am writing code in atapi. I used codes in osdev for atapi topic(just under that),i pass through the first interrupt for outting atapi commands and in my interrupt handler i received the size of
all the bytes.but why i can't interrupt once again in reading data?(i had added some programs for sending the EOI.)below is my code.I use the bochs vm.
this is my interrupt codes
And in main code
In the idt code
and this is my first question,i hope some guy qualify can point some errors.Thanks.
all the bytes.but why i can't interrupt once again in reading data?(i had added some programs for sending the EOI.)below is my code.I use the bochs vm.
Code: Select all
/*cdrom.c*/
/*cdrom.c*/
/* The default and seemingly universal sector size for CD-ROMs. */
#define ATAPI_SECTOR_SIZE 2048
/* The default ISA IRQ numbers of the ATA controllers. */
#define ATA_IRQ_PRIMARY 0x0E
#define ATA_IRQ_SECONDARY 0x0F
/* The necessary I/O ports, indexed by "bus". */
#define ATA_DATA(x) (x)
#define ATA_FEATURES(x) (x+1)
#define ATA_SECTOR_COUNT(x) (x+2)
#define ATA_ADDRESS1(x) (x+3)
#define ATA_ADDRESS2(x) (x+4)
#define ATA_ADDRESS3(x) (x+5)
#define ATA_DRIVE_SELECT(x) (x+6)
#define ATA_COMMAND(x) (x+7)
#define ATA_DCR(x) (x+0x206) /* device control register */
/* valid values for "bus" */
#define ATA_BUS_PRIMARY 0x1F0
#define ATA_BUS_SECONDARY 0x170
/* valid values for "drive" */
#define ATA_DRIVE_MASTER 0xA0
#define ATA_DRIVE_SLAVE 0xB0
char *cds;
int cd_read_flag;
int cd_irq_2;
int size;
DWORD bus = ATA_BUS_PRIMARY;
DWORD drive = ATA_DRIVE_SLAVE;
WORD cdbuffer[1024];
//cdrom irq handler
void inthandler2e(int *esp){//this is my interrupt handler it is link with idt and assembly codes
struct BOOTINFO *binfo = (struct BOOTINFO *)ADR_BOOTINFO;
int i;
[b] io_out8(PIC1_OCW2, 0x66); /* IRQ-14 call is done tell the PIC1 PIC1_OCW2=a0h*/
io_out8(PIC0_OCW2, 0x62); /* IRQ-02 call is done tell the PIC0 PIC0_OCW2=20h*/[/b]
if(cd_irq_2==1){
putfonts8_asc(binfo->vram, binfo->scrnx, 0, 96, COL8_FFFFFF, "get irq ata cd 2");//printing codes
}else{
size =(((int) io_in8(ATA_ADDRESS3 (bus))) << 8) |(int) (io_in8(ATA_ADDRESS2 (bus)));
if(size!=ATAPI_SECTOR_SIZE){
return;
}
cdbuffer[0]=0x11;
cd_irq_2=1;
io_in16(ATA_DATA (bus));// i have read bochs code ,firstly reading is reading all the bytes into a buffer pointer
for(i=0;i<(size/2);i++){
cdbuffer[i]=io_in16(ATA_DATA (bus));
}
}
return;
}
void init_cdrom(char *vram,short scrnx){
DWORD lba = 0x10;//in the 10h for iso there is some nozero data.
/* 0xA8 is READ SECTORS command byte. */
BYTE read_cmd[12] = { 0xA8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
BYTE status;
int i;
/* Tell the scheduler that this process is using the ATA subsystem. */
//ata_grab ();
/* Select drive (only the slave-bit is set) */
io_out8 ( ATA_DRIVE_SELECT (bus),drive&(1<<4));
io_nop();
io_out8 (ATA_FEATURES (bus), 0x0); /* PIO mode */
//io_out8(ATA_SECTOR_COUNT(bus),0x01);
io_out8 (ATA_ADDRESS2 (bus), (BYTE)(ATAPI_SECTOR_SIZE & 0xFF));
io_out8 (ATA_ADDRESS3 (bus), (BYTE)(ATAPI_SECTOR_SIZE >> 8));
io_out8 (ATA_COMMAND (bus), 0xA0); /* ATA PACKET command */
status = io_in8 (ATA_COMMAND (bus));
while(status==0x80);
io_nop();
status = io_in8 (ATA_COMMAND (bus));
while(!(status&0x8)&&!(status&0x01));
sprintf(cds,"STATUS:%d",status);
putfonts8_asc(vram, scrnx, 0, 64, COL8_FFFFFF, cds);
read_cmd[9] = 1; /* 1 sector */
read_cmd[2] = (lba >> 0x18) & 0xFF; /* most sig. byte of LBA */
read_cmd[3] = (lba >> 0x10) & 0xFF;
read_cmd[4] = (lba >> 0x08) & 0xFF;
read_cmd[5] = (lba >> 0x00) & 0xFF; /* least sig. byte of LBA */
/* Send ATAPI/SCSI command */
//outsw (ATA_DATA (bus), (WORD *) read_cmd, 6);
for(i=0;i<12;i=+2){
io_out16(ATA_DATA (bus),(read_cmd[i])|read_cmd[i+1]<<8);
}
}
Code: Select all
#define PIC0_ICW1 0x0020
#define PIC0_OCW2 0x0020
#define PIC0_IMR 0x0021
#define PIC0_ICW2 0x0021
#define PIC0_ICW3 0x0021
#define PIC0_ICW4 0x0021
#define PIC1_ICW1 0x00a0
#define PIC1_OCW2 0x00a0
#define PIC1_IMR 0x00a1
#define PIC1_ICW2 0x00a1
#define PIC1_ICW3 0x00a1
#define PIC1_ICW4 0x00a1
void init_pic(void)
/* PIC init*/
{
io_out8(PIC0_IMR, 0xff );
io_out8(PIC1_IMR, 0xff );
io_out8(PIC0_ICW1, 0x11 );
io_out8(PIC0_ICW2, 0x20 );
io_out8(PIC0_ICW3, 1 << 2);
io_out8(PIC0_ICW4, 0x01 );
io_out8(PIC1_ICW1, 0x11 );
io_out8(PIC1_ICW2, 0x28 );
io_out8(PIC1_ICW3, 2 );
io_out8(PIC1_ICW4, 0x01 );
io_out8(PIC0_IMR, 0xfb );
io_out8(PIC1_IMR, 0xff );
return;
}
Code: Select all
io_out8(PIC0_IMR, 0xf9); /* PIC1 and keyboard allowed(11111001) */
io_out8(PIC1_IMR, 0xaf); /* mouse and ata0 allowed in pic1(10101111) */
Code: Select all
set_gatedesc(idt + 0x2c, (int) asm_inthandler2c, 2 * 8, AR_INTGATE32);//add in code for idt