uint8* TF20::get_sector(int drv, int trk, int sec) { // logical : trk = 0-39, sec = 1-64, secsize = 128bytes int total = trk * 64 + sec - 1; int half = total & 1; total >>= 1; int phys_sec = total & 15; total >>= 4; int phys_side = total & 1; int phys_trk = total >> 1; if(!disk_inserted(drv)) { return NULL; } if(!disk[drv]->get_sector(phys_trk, phys_side, phys_sec)) { return NULL; } return disk[drv]->sector + (half ? 128 : 0); }
bool TF20::process_cmd() { int drv, trk, sec, dst; uint8 *sctr, *sctw; switch(bufr[3]) { case FNC_RESET_P: case FNC_RESET_M: SET_HEAD(0); SET_CODE(ERR_SUCCESS); return true; case FNC_READ: drv = (bufr[1] == DID_FIRST) ? 0 : (bufr[1] == DID_SECOND) ? 2 : 4; drv += bufr[7] - 1; trk = bufr[8]; sec = bufr[9]; if(!disk_inserted(drv)) { // drive error SET_HEAD(0x80); for(int i = 0; i < 128; i++) { SET_DATA(0xff); } SET_CODE(ERR_DRIVE); return true; } if((sctr = get_sector(drv, trk, sec)) == NULL) { // read error SET_HEAD(0x80); for(int i = 0; i < 128; i++) { SET_DATA(0xff); } SET_CODE(ERR_READ); return true; } SET_HEAD(0x80); for(int i = 0; i < 128; i++) { SET_DATA(sctr[i]); } SET_CODE(ERR_SUCCESS); return true; case FNC_WRITE: drv = (bufr[1] == DID_FIRST) ? 0 : (bufr[1] == DID_SECOND) ? 2 : 4; drv += bufr[7] - 1; trk = bufr[8]; sec = bufr[9]; if(!disk_inserted(drv)) { // drive error SET_HEAD(0); SET_CODE(ERR_DRIVE); return true; } if(disk_protected(drv)) { // write protect SET_HEAD(0); SET_CODE(ERR_PROTECTED); return true; } if((sctw = get_sector(drv, trk, sec)) == NULL) { // write error SET_HEAD(0); SET_CODE(ERR_WRITE); return true; } // dont care write type for(int i = 0; i < 128; i++) { sctw[i] = bufr[11 + i]; } SET_HEAD(0); SET_CODE(ERR_SUCCESS); return true; case FNC_WRITEHST: SET_HEAD(0); SET_CODE(ERR_SUCCESS); return true; case FNC_COPY: drv = (bufr[1] == DID_FIRST) ? 0 : (bufr[1] == DID_SECOND) ? 2 : 4; drv += bufr[7] - 1; dst = (drv & ~1) | (~drv & 1); if(!disk_inserted(drv)) { // drive error SET_HEAD(0); SET_CODE(ERR_DRIVE); return true; } if(!disk_inserted(dst)) { // drive error SET_HEAD(0); SET_CODE(ERR_DRIVE); return true; } if(disk_protected(dst)) { // write protect SET_HEAD(0); SET_CODE(ERR_PROTECTED); return true; } for(trk = 0; trk < 40; trk++) { for(sec = 1; sec <= 64; sec++) { if((sctr = get_sector(drv, trk, sec)) == NULL) { // read error SET_HEAD(0); SET_CODE(ERR_READ); return true; } if((sctw = get_sector(dst, trk, sec)) == NULL) { // write error SET_HEAD(0); SET_CODE(ERR_WRITE); return true; } memcpy(sctw, sctr, 128); } SET_HEAD(2); SET_DATA(trk == 39 ? 0xff : 0); // high-order SET_DATA(trk == 39 ? 0xff : trk); // low-order SET_CODE(ERR_SUCCESS); } return true; case FNC_FORMAT: drv = (bufr[1] == DID_FIRST) ? 0 : (bufr[1] == DID_SECOND) ? 2 : 4; drv += bufr[7] - 1; if(!disk_inserted(drv)) { // drive error SET_HEAD(0); SET_CODE(ERR_DRIVE); return true; } if(disk_protected(drv)) { // write protect SET_HEAD(0); SET_CODE(ERR_PROTECTED); return true; } for(trk = 0; trk < 40; trk++) { for(sec = 1; sec <= 64; sec++) { if((sctw = get_sector(drv, trk, sec)) == NULL) { // write error SET_HEAD(0); SET_CODE(ERR_WRITE); return true; } memset(sctw, 0xe5, 128); } SET_HEAD(2); SET_DATA(trk == 39 ? 0xff : 0); // high-order SET_DATA(trk == 39 ? 0xff : trk); // low-order SET_CODE(ERR_SUCCESS); } return true; } // unknown command return false; }
bool UPD765A::disk_inserted() { int drv = hdu & DRIVE_MASK; return disk_inserted(drv); }