示例#1
0
文件: 8271.c 项目: gwtnz/Beebdroid
void callback8271()
{
        int diff=i8271.params[0]-i8271.curtrack[curdrive];
        fdctime=0;
//        printf("Callback 8271 - command %02X\n",i8271.command);
        switch (i8271.command)
        {
                case 0x0B: /*Write*/
                if (!i8271.phase)
                {
                        i8271.curtrack[curdrive]=i8271.params[0];
                        disc_writesector(curdrive,i8271.cursector,i8271.params[0],(i8271.drvout&0x20)?1:0,0);
                        i8271.phase=1;
                        
                        i8271.status=0x8C;
                        i8271.result=0;
                        NMI8271();
                        return;
                }
                i8271.sectorsleft--;
                if (!i8271.sectorsleft)
                {
                        i8271.status=0x18;
                        i8271.result=0;
                        NMI8271();
                        setspindown8271();
                        verify8271=0;
                        return;
                }
                i8271.cursector++;
                disc_writesector(curdrive,i8271.cursector,i8271.params[0],(i8271.drvout&0x20)?1:0,0);
                byte=0;
                i8271.status=0x8C;
                i8271.result=0;
                NMI8271();
                break;

                case 0x13: /*Read*/
                case 0x1F: /*Verify*/
                if (!i8271.phase)
                {
//                        printf("Seek to %i\n",i8271.params[0]);
                        i8271.curtrack[curdrive]=i8271.params[0];
//                        i8271.realtrack+=diff;
//                        disc_seek(0,i8271.realtrack);
//                        printf("Re-seeking - track now %i %i\n",i8271.curtrack,i8271.realtrack);
                        disc_readsector(curdrive,i8271.cursector,i8271.params[0],(i8271.drvout&0x20)?1:0,0);
                        i8271.phase=1;
                        return;
                }
                i8271.sectorsleft--;
                if (!i8271.sectorsleft)
                {
                        i8271.status=0x18;
                        i8271.result=0;
                        NMI8271();
                        setspindown8271();
                        verify8271=0;
                        return;
                }
                i8271.cursector++;
                disc_readsector(curdrive,i8271.cursector,i8271.params[0],(i8271.drvout&0x20)?1:0,0);
                byte=0;
                break;
                
                case 0x1B: /*Read ID*/
//                printf("Read ID callback %i\n",i8271.phase);
                if (!i8271.phase)
                {
                        i8271.curtrack[curdrive]=i8271.params[0];
//                        i8271.realtrack+=diff;
//                        disc_seek(0,i8271.realtrack);
                        disc_readaddress(curdrive,i8271.params[0],(i8271.drvout&0x20)?1:0,0);
                        i8271.phase=1;
                        return;
                }
//                printf("Read ID track %i %i\n",i8271.params[0],i8271.sectorsleft);
                i8271.sectorsleft--;
                if (!i8271.sectorsleft)
                {
                        i8271.status=0x18;
                        i8271.result=0;
                        NMI8271();
//                        printf("8271 : ID read done!\n");
                        setspindown8271();
                        return;
                }
                i8271.cursector++;
                disc_readaddress(curdrive,i8271.params[0],(i8271.drvout&0x20)?1:0,0);
                byte=0;
                break;

                case 0x23: /*Format*/
                if (!i8271.phase)
                {
                        i8271.curtrack[curdrive]=i8271.params[0];
                        disc_writesector(curdrive,i8271.cursector,i8271.params[0],(i8271.drvout&0x20)?1:0,0);
                        i8271.phase=1;

                        i8271.status=0x8C;
                        i8271.result=0;
                        NMI8271();
                        return;
                }
                if (i8271.phase==2)
                {
                        i8271.status=0x18;
                        i8271.result=0;
                        NMI8271();
                        setspindown8271();
                        verify8271=0;
                        return;
                }
                disc_format(curdrive,i8271.params[0],(i8271.drvout&0x20)?1:0,0);
                i8271.phase=2;
                break;

                case 0x29: /*Seek*/
                i8271.curtrack[curdrive]=i8271.params[0];
//                i8271.realtrack+=diff;
                i8271.status=0x18;
                i8271.result=0;
                NMI8271();
//                disc_seek(0,i8271.realtrack);
//                printf("Seek done!\n");
                setspindown8271();
                break;
                
                case 0xFF: break;
                
                default: break;
                printf("Unknown 8271 command %02X 3\n",i8271.command);
                dumpregs();
                exit(-1);
        }
}
示例#2
0
void fdc_write(uint16_t addr, uint8_t val, void *priv)
{
//        pclog("Write FDC %04X %02X %04X:%04X %i %02X %i rate=%i  %i\n",addr,val,cs>>4,pc,ins,fdc.st0,ins,fdc.rate, fdc.data_ready);
	int drive;

        switch (addr&7)
        {
                case 1: return;
                case 2: /*DOR*/
//                if (val == 0xD && (cs >> 4) == 0xFC81600 && ins > 769619936) output = 3;
//                printf("DOR was %02X\n",fdc.dor);
                if (fdc.pcjr)
                {
                        if ((fdc.dor & 0x40) && !(val & 0x40))
                        {
                                fdc.watchdog_timer = 1000 * TIMER_USEC;
                                fdc.watchdog_count = 1000;
                                picintc(1 << 6);
//                                pclog("watchdog set %i %i\n", fdc.watchdog_timer, TIMER_USEC);
                        }
                        if ((val & 0x80) && !(fdc.dor & 0x80))
                        {
        			timer_process();
                                disctime = 128 * (1 << TIMER_SHIFT);
                                timer_update_outstanding();
                                discint=-1;
                                fdc_reset();
                        }
                        motoron = val & 0x01;
                        fdc.drive = 0;
/*                        if (motoron)
                                output = 3;
                        else
                                output = 0;*/
                }
                else
                {
                        if (val&4)
                        {
                                fdc.stat=0x80;
                                fdc.pnum=fdc.ptot=0;
                        }
                        if ((val&4) && !(fdc.dor&4))
                        {
        			timer_process();
                                disctime = 128 * (1 << TIMER_SHIFT);
                                timer_update_outstanding();
                                discint=-1;
                                fdc_reset();
                        }
			timer_process();
                        motoron = (val & 0xf0) ? 1 : 0;
			timer_update_outstanding();
                        fdc.drive = val & 3;
                }
                fdc.dor=val;
//                printf("DOR now %02X\n",val);
                return;
		case 3:
		/* TDR */
		if (fdc.enh_mode)
		{
			drive = (fdc.dor & 1) ^ fdd_swap;
			fdc.rwc[drive] = (val & 0x30) >> 4;
		}
		return;
                case 4:
                if (val & 0x80)
                {
			timer_process();
                        disctime = 128 * (1 << TIMER_SHIFT);
                        timer_update_outstanding();
                        discint=-1;
                        fdc_reset();
                }
                return;
                case 5: /*Command register*/
                if ((fdc.stat & 0xf0) == 0xb0)
                {
			if (fdc.pcjr || !fdc.fifo)
			{
	                        fdc.dat = val;
        	                fdc.stat &= ~0x80;
			}
			else
			{
				fdc_fifo_buf_write(val);
				if (fdc.fifobufpos == 0)  fdc.stat &= ~0x80;
			}
                        break;
                }
//                if (fdc.inread)
//                        rpclog("c82c711_fdc_write : writing while inread! %02X\n", val);
//                rpclog("Write command reg %i %i\n",fdc.pnum, fdc.ptot);
                if (fdc.pnum==fdc.ptot)
                {
                        fdc.tc = 0;
                        fdc.data_ready = 0;
                        
                        fdc.command=val;
//                        pclog("Starting FDC command %02X\n",fdc.command);
                        switch (fdc.command&0x1F)
                        {
				case 1: /*Mode*/
				if (!fdc.is_nsc)  goto bad_command;
                                fdc.pnum=0;
                                fdc.ptot=4;
                                fdc.stat=0x90;
                                fdc.pos=0;
                                fdc.format_state = 0;
                                break;

                                case 2: /*Read track*/
                                fdc.pnum=0;
                                fdc.ptot=8;
                                fdc.stat=0x90;
                                fdc.pos=0;
                                break;
                                case 3: /*Specify*/
                                fdc.pnum=0;
                                fdc.ptot=2;
                                fdc.stat=0x90;
                                break;
                                case 4: /*Sense drive status*/
                                fdc.pnum=0;
                                fdc.ptot=1;
                                fdc.stat=0x90;
                                break;
                                case 5: /*Write data*/
//                                printf("Write data!\n");
                                fdc.pnum=0;
                                fdc.ptot=8;
                                fdc.stat=0x90;
                                fdc.pos=0;
//                                readflash=1;
                                break;
                                case 6: /*Read data*/
                                fdc.pnum=0;
                                fdc.ptot=8;
                                fdc.stat=0x90;
                                fdc.pos=0;
                                break;
                                case 7: /*Recalibrate*/
                                fdc.pnum=0;
                                fdc.ptot=1;
                                fdc.stat=0x90;
                                break;
                                case 8: /*Sense interrupt status*/
//                                printf("Sense interrupt status %i\n",curdrive);
                                fdc.lastdrive = fdc.drive;
//                                fdc.stat = 0x10 | (fdc.stat & 0xf);
//                                fdc_time=1024;
                                discint = 8;
                                fdc.pos = 0;
                                fdc_callback();
                                break;
                                case 10: /*Read sector ID*/
                                fdc.pnum=0;
                                fdc.ptot=1;
                                fdc.stat=0x90;
                                fdc.pos=0;
                                break;
                                case 0x0d: /*Format track*/
                                fdc.pnum=0;
                                fdc.ptot=5;
                                fdc.stat=0x90;
                                fdc.pos=0;
                                fdc.format_state = 0;
                                break;
                                case 15: /*Seek*/
                                fdc.pnum=0;
                                fdc.ptot=2;
                                fdc.stat=0x90;
                                break;
                                case 0x0e: /*Dump registers*/
                                fdc.lastdrive = fdc.drive;
                                discint = 0x0e;
                                fdc.pos = 0;
                                fdc_callback();
                                break;
                                case 0x10: /*Get version*/
                                fdc.lastdrive = fdc.drive;
                                discint = 0x10;
                                fdc.pos = 0;
                                fdc_callback();
                                break;
                                case 0x12: /*Set perpendicular mode*/
                                fdc.pnum=0;
                                fdc.ptot=1;
                                fdc.stat=0x90;
                                fdc.pos=0;
                                break;
                                case 0x13: /*Configure*/
                                fdc.pnum=0;
                                fdc.ptot=3;
                                fdc.stat=0x90;
                                fdc.pos=0;
                                break;
                                case 0x14: /*Unlock*/
                                case 0x94: /*Lock*/
                                fdc.lastdrive = fdc.drive;
                                discint = fdc.command;
                                fdc.pos = 0;
                                fdc_callback();
                                break;

                                case 0x18:
				if (!fdc.is_nsc)  goto bad_command;			
                                fdc.lastdrive = fdc.drive;
                                discint = 0x10;
                                fdc.pos = 0;
                                fdc_callback();
                                /* fdc.stat = 0x10;
                                discint  = 0xfc;
                                fdc_callback(); */
                                break;

                                default:
bad_command:
                                // fatal("Bad FDC command %02X\n",val);
//                                dumpregs();
//                                exit(-1);
                                fdc.stat=0x10;
                                discint=0xfc;
        			timer_process();
        			disctime = 200 * (1 << TIMER_SHIFT);
        			timer_update_outstanding();
                                break;
                        }
                }
                else
                {
                        fdc.params[fdc.pnum++]=val;
                        if (fdc.pnum==fdc.ptot)
                        {
//                                pclog("Got all params %02X\n", fdc.command);
                                fdc.stat=0x30;
                                discint=fdc.command&0x1F;
        			timer_process();
        			disctime = 1024 * (1 << TIMER_SHIFT);
        			timer_update_outstanding();
//                                fdc.drive = fdc.params[0] & 3;
                                disc_drivesel = fdc.drive & 1;
                                fdc_reset_stat = 0;
                                disc_set_drivesel(fdc.drive & 1);
                                switch (discint)
                                {
                                        case 2: /*Read a track*/
					fdc_rate(fdc.drive);
                                        fdc.head=fdc.params[2];
                                        fdc.sector=fdc.params[3];
                                        fdc.eot[fdc.drive] = fdc.params[5];
                                        if (fdc.config & 0x40)
                                                fdd_seek(fdc.drive, fdc.params[1] - fdc.track[fdc.drive]);
                                        fdc.track[fdc.drive]=fdc.params[1];
//                                        pclog("Read a track track=%i head=%i sector=%i eot=%i\n", fdc.track[fdc.drive], fdc.head, fdc.sector, fdc.eot[fdc.drive]);
                                        disc_readsector(fdc.drive, SECTOR_FIRST, fdc.track[fdc.drive], fdc.head, fdc.rate, fdc.params[4]);
                                        disctime = 0;
                                        readflash = 1;
                                        fdc.inread = 1;
                                        break;

                                        case 3: /*Specify*/
                                        fdc.stat=0x80;
                                        fdc.specify[0] = fdc.params[0];
                                        fdc.specify[1] = fdc.params[1];
                                        fdc.dma = (fdc.specify[1] & 1) ^ 1;
                                        disctime = 0;
                                        break;

                                        case 5: /*Write data*/
					fdc_rate(fdc.drive);
                                        fdc.head=fdc.params[2];
                                        fdc.sector=fdc.params[3];
                                        fdc.eot[fdc.drive] = fdc.params[5];
                                        if (fdc.config & 0x40)
                                                fdd_seek(fdc.drive, fdc.params[1] - fdc.track[fdc.drive]);
                                        fdc.track[fdc.drive]=fdc.params[1];
                                        fdc.rw_track = fdc.params[1];
                                        
                                        disc_writesector(fdc.drive, fdc.sector, fdc.track[fdc.drive], fdc.head, fdc.rate, fdc.params[4]);
                                        disctime = 0;
                                        fdc.written = 0;
                                        readflash = 1;
                                        fdc.pos = 0;
                                        if (fdc.pcjr)
                                                fdc.stat = 0xb0;
//                                        ioc_fiq(IOC_FIQ_DISC_DATA);
                                        break;
                                        
                                        case 6: /*Read data*/
					fdc_rate(fdc.drive);
                                        fdc.head=fdc.params[2];
                                        fdc.sector=fdc.params[3];
                                        fdc.eot[fdc.drive] = fdc.params[5];
                                        if (fdc.config & 0x40)
                                                fdd_seek(fdc.drive, fdc.params[1] - fdc.track[fdc.drive]);
                                        fdc.track[fdc.drive]=fdc.params[1];
                                        fdc.rw_track = fdc.params[1];
                                        
                                        disc_readsector(fdc.drive, fdc.sector, fdc.track[fdc.drive], fdc.head, fdc.rate, fdc.params[4]);
                                        disctime = 0;
                                        readflash = 1;
                                        fdc.inread = 1;
                                        break;
                                        
                                        case 7: /*Recalibrate*/
                                        fdc.stat =  1 << fdc.drive;
                                        disctime = 0;
                                        fdd_seek(fdc.drive, SEEK_RECALIBRATE);
                                        break;

                                        case 0x0d: /*Format*/
					fdc_rate(fdc.drive);
                                        fdc.head = (fdc.params[0] & 4) ? 1 : 0;
                                        fdc.format_state = 1;
                                        fdc.pos = 0;
                                        fdc.stat = 0x30;
                                        break;
                                        
                                        case 0xf: /*Seek*/
                                        fdc.stat =  1 << fdc.drive;
                                        fdc.head = (fdc.params[0] & 4) ? 1 : 0;
                                        disctime = 0;
                                        fdd_seek(fdc.drive, fdc.params[1] - fdc.track[fdc.drive]);
//                                        pclog("Seek to %i\n", fdc.params[1]);
                                        break;
                                        
                                        case 10: /*Read sector ID*/
					fdc_rate(fdc.drive);
                                        disctime = 0;
                                        fdc.head = (fdc.params[0] & 4) ? 1 : 0;                                        
//                                        pclog("Read sector ID %i %i\n", fdc.rate, fdc.drive);
                                        disc_readaddress(fdc.drive, fdc.track[fdc.drive], fdc.head, fdc.rate);
                                        break;
                                }
                        }
                }
                return;
                case 7:
                        if (!AT) return;
                fdc.rate=val&3;

                disc_3f7=val;
                return;
        }