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