uint8_t read8271(uint16_t addr) { uint8_t val; // if ((addr&7)!=4) rpclog("Read 8271 %04X\n",addr); switch (addr & 7) { case 0: /*Status register*/ // rpclog("Read status reg %04X %02X\n",pc,i8271.status); return i8271.status; case 1: /*Result register*/ i8271.status &= ~0x18; NMI8271(); val = i8271.result; // printf("Read result reg %04X %02X\n",pc,i8271.status); // output=1; timetolive=50; // rpclog("Read result reg %02X\n",i8271.result); i8271.result = 0; return val; case 4: /*Data register*/ i8271.status &= ~0xC; NMI8271(); // printf("Read data reg %04X %02X\n",pc,i8271.status); return i8271.data; } return 0; }
void writeprotect8271() { i8271.result=0x12; i8271.status=0x18; NMI8271(); fdctime=0; }
void headercrcerror8271() { i8271.result=0x0C; i8271.status=0x18; NMI8271(); fdctime=0; // printf("CRChead 8271\n"); }
void datacrcerror8271() { i8271.result=0x0E; i8271.status=0x18; NMI8271(); fdctime=0; // printf("CRCdat 8271\n"); }
void notfound8271() { i8271.result=0x18; i8271.status=0x18; NMI8271(); fdctime=0; // printf("Not found 8271\n"); }
void data8271(uint8_t dat) { if (verify8271) return; i8271.data=dat; i8271.status=0x8C; i8271.result=0; NMI8271(); // printf("%02X : Data %02X\n",byte,dat); byte++; }
uint8_t read8271(uint16_t addr) { // printf("Read 8271 %04X\n",addr); switch (addr&7) { case 0: /*Status register*/ // printf("Read status reg %04X %02X\n",pc,i8271.status); return i8271.status; case 1: /*Result register*/ i8271.status&=~0x18; NMI8271(); // printf("Read result reg %04X %02X\n",pc,i8271.status); return i8271.result; case 4: /*Data register*/ i8271.status&=~0xC; NMI8271(); // printf("Read data reg %04X %02X\n",pc,i8271.status); return i8271.data; } return 0; }
int getdata8271(int last) { // printf("Disc get data %i\n",byte); byte++; if (!i8271.written) return -1; if (!last) { i8271.status=0x8C; i8271.result=0; NMI8271(); } i8271.written=0; return i8271.data; }
int getdata8271(int last) { // rpclog("Disc get data %i %i\n",byte,last); byte++; if (!i8271.written) return -1; if (!last) { // rpclog("Get data nmi\n"); i8271.status = 0x8C; i8271.result = 0; NMI8271(); } i8271.written = 0; return i8271.data; }
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); } }
void write8271(uint16_t addr, uint8_t val) { // printf("Write 8271 %04X %02X\n",addr,val); switch (addr&7) { case 0: /*Command register*/ if (i8271.status&0x80) return; i8271.command=val&0x3F; if (i8271.command==0x17) i8271.command=0x13; // printf("8271 command %02X!\n",i8271.command); i8271.drivesel=val>>6; if (val&0x80) curdrive=1; else curdrive=0; i8271.paramnum=0; i8271.paramreq=getparams8271(); i8271.status=0x80; if (!i8271.paramreq) { switch (i8271.command) { case 0x2C: /*Read drive status*/ i8271.status=0x10; i8271.result=0x80|8|track0; if (i8271.drivesel&1) i8271.result|=0x04; if (i8271.drivesel&2) i8271.result|=0x40; // printf("Status %02X\n",i8271.result); break; default: i8271.result=0x18; i8271.status=0x18; NMI8271(); fdctime=0; break; // printf("Unknown 8271 command %02X 3\n",i8271.command); // dumpregs(); // exit(-1); } } break; case 1: /*Parameter register*/ if (i8271.paramnum<5) i8271.params[i8271.paramnum++]=val; if (i8271.paramnum==i8271.paramreq) { switch (i8271.command) { case 0x0B: /*Write sector*/ i8271.sectorsleft=i8271.params[2]&31; i8271.cursector=i8271.params[1]; spinup8271(); i8271.phase=0; if (i8271.curtrack[curdrive]!=i8271.params[0]) seek8271(); else fdctime=200; break; case 0x13: /*Read sector*/ i8271.sectorsleft=i8271.params[2]&31; i8271.cursector=i8271.params[1]; spinup8271(); i8271.phase=0; if (i8271.curtrack[curdrive]!=i8271.params[0]) seek8271(); else fdctime=200; break; case 0x1F: /*Verify sector*/ i8271.sectorsleft=i8271.params[2]&31; i8271.cursector=i8271.params[1]; spinup8271(); i8271.phase=0; if (i8271.curtrack[curdrive]!=i8271.params[0]) seek8271(); else fdctime=200; verify8271=1; break; case 0x1B: /*Read ID*/ // printf("8271 : Read ID start\n"); i8271.sectorsleft=i8271.params[2]&31; spinup8271(); i8271.phase=0; if (i8271.curtrack[curdrive]!=i8271.params[0]) seek8271(); else fdctime=200; break; case 0x23: /*Format track*/ spinup8271(); i8271.phase=0; if (i8271.curtrack[curdrive]!=i8271.params[0]) seek8271(); else fdctime=200; break; break; case 0x29: /*Seek*/ // fdctime=10000; seek8271(); spinup8271(); break; case 0x35: /*Specify*/ i8271.status=0; break; case 0x3A: /*Write special register*/ i8271.status=0; // printf("Write special %02X\n",i8271.params[0]); switch (i8271.params[0]) { case 0x12: i8271.curtrack[0]=val; /*printf("Write real track now %i\n",val);*/ break; case 0x17: break; /*Mode register*/ case 0x1A: i8271.curtrack[1]=val; /*printf("Write real track now %i\n",val);*/ break; case 0x23: i8271.drvout=i8271.params[1]; break; default: i8271.result=0x18; i8271.status=0x18; NMI8271(); fdctime=0; break; // default: // printf("8271 Write bad special register %02X\n",i8271.params[0]); // dumpregs(); // exit(-1); } break; case 0x3D: /*Read special register*/ i8271.status=0x10; i8271.result=0; switch (i8271.params[0]) { case 0x06: i8271.result=0; break; case 0x12: i8271.result=i8271.curtrack[0]; break; case 0x1A: i8271.result=i8271.curtrack[1]; break; case 0x23: i8271.result=i8271.drvout; break; default: i8271.result=0x18; i8271.status=0x18; NMI8271(); fdctime=0; break; // default: // printf("8271 Read bad special register %02X\n",i8271.params[0]); // dumpregs(); // exit(-1); } break; default: i8271.result=0x18; i8271.status=0x18; NMI8271(); fdctime=0; break; // printf("Unknown 8271 command %02X 2\n",i8271.command); // dumpregs(); // exit(-1); } } break; case 2: /*Reset register*/ if (val&1) reset8271(); break; case 4: /*Data register*/ i8271.data=val; i8271.written=1; i8271.status&=~0xC; NMI8271(); break; } }