#include "compiler.h"
#include "dosio.h"
#include "pccore.h"
#include "iocore.h"
#include "fddfile.h"
#include "fdd_2d.h"
#include "fdd_mtr.h"
static WORD sec_now[4] = {0, 0, 0, 0};
static BYTE sec_write[4] = {0, 0, 0, 0};
static BYTE sec_data[4][256];
static BYTE hole = 0;
static BYTE changesector2d(void) {
FDDFILE fdd;
FILEH fh;
WORD sec;
long seekp;
short drv = fdc.drv;
if (fdc.s.media != DISKTYPE_2D) {
return(1);
}
fdd = fddfile + drv;
sec = (WORD)(((fdc.c) << 5) + (fdc.h << 4) + fdc.r - 1);
if (sec_now[drv] == sec) {
return(0);
}
fh = file_open(fdd->fname);
if (fh == FILEH_INVALID) {
sec_now[drv] = -1;
return(1);
}
if ((sec_write[drv]) && (sec_now[drv] != -1)) {
seekp = (long)sec_now[drv] << 8;
if ((file_seek(fh, seekp, FSEEK_SET) != seekp) ||
(file_write(fh, sec_data[drv], 256) != 256)) {
file_close(fh);
sec_now[drv] = -1;
return(1);
}
}
sec_write[drv] = 0;
sec_now[drv] = sec;
seekp = (long)sec << 8;
if ((file_seek(fh, seekp, FSEEK_SET) != seekp) ||
(file_read(fh, sec_data[drv], 256) != 256)) {
file_close(fh);
sec_now[drv] = -1;
return(1);
}
file_close(fh);
return(0);
}
//**********************************************************************
BRESULT fdd2d_crc(FDDFILE fdd) {
fdc.s.buffer[0] = fdc.c;
fdc.s.buffer[1] = fdc.h;
fdc.s.buffer[2] = fdc.r;
fdc.s.buffer[3] = 1;
fdc.s.buffer[4] = 0; // CRC(Lo)
fdc.s.buffer[5] = 0; // CRC(Hi)
fdc.s.bufsize = 6;
fdc.rreg = fdc.c; // メルヘンヴェール
(void)fdd;
return(SUCCESS);
}
BYTE fdd_stat_2d(void) {
FDDFILE fdd;
REG8 cmd;
BYTE type;
BYTE ans = 0;
fdd = fddfile + fdc.drv;
// NOT READY
if (fdd->type != DISKTYPE_BETA) {
return(0x80);
}
type = fdc.type;
cmd = (REG8)(fdc.cmd >> 4);
if (type == 0 || type == 1 || type == 4 || // !!!
cmd == 0x0a || cmd == 0x0b || cmd == 0x0f) {
if (fdd->protect) { // WRITE PROTECT
ans |= 0x40;
}
}
if ((type == 1 || type == 2) &&
((fdc.c >= 40) || (fdc.h > 1) || (fdc.r > 16) ||
(fdc.s.media != DISKTYPE_2D))) {
ans |= 0x10; // SEEK ERROR / RECORD NOT FOUND
}
if (type == 1 || type == 4) {
if (type == 1) {
ans |= 0x20; // HEAD ENGAGED (X1 デハ ツネニ 1)
if (fdc.c == 0) {
ans |= 0x04; // TRACK00
}
}
if (++hole < 8) {
ans |= 0x02; // INDEX
}
}
else if (!(ans & 0xf0)) {
if (FDDMTR_BUSY) {
ans |= 0x01;
}
if ((type == 2) && (fdc.r) && (fdc.off < 256)) {
ans |= 0x03; // DATA REQUEST / BUSY
}
else if (cmd == 0x0f) {
ans |= 0x04; // error!
}
}
return(ans);
}
//**********************************************************************
void fdd_read_2d(void) {
if (((fdd_stat_2d() & 0xf3) == 3) && (!changesector2d())) {
fdc.data = sec_data[fdc.drv][fdc.off];
}
}
void fdd_write_2d(void) {
if (((fdd_stat_2d() & 0xf3) == 3) && (!changesector2d())) {
sec_data[fdc.drv][fdc.off] = fdc.data;
sec_write[fdc.drv] = 1;
}
}
BYTE fdd_incoff_2d(void) {
REG8 cmd;
if (++fdc.off < 256) {
return(0);
}
cmd = (REG8)(fdc.cmd >> 4);
if ((cmd == 0x09) || (cmd == 0x0b)) {
if (fdc.r < 16) {
fdc.r++;
fdc.rreg++;
fdc.off = 0;
return(0);
}
fdc.rreg = fdc.r + 1;
}
fdc.off = 256;
return(1);
}
// ----
BRESULT fdd2d_set(FDDFILE fdd, REG8 drv, const OEMCHAR *fname) {
short attr;
attr = file_attr(fname);
if (attr & 0x18) {
return(FAILURE);
}
fdd->type = DISKTYPE_BETA;
fdd->protect = (UINT8)(attr & 1);
sec_now[drv] = -1;
sec_write[drv] = 0;
return(SUCCESS);
}
BRESULT fdd2d_eject(FDDFILE fdd, REG8 drv) {
FILEH fh;
long seekp;
BRESULT ret = 0;
while(1) {
if ((!sec_write[drv]) || (sec_now[drv] == -1)) {
break;
}
seekp = (long)sec_now[drv] << 8;
fh = file_open(fdd->fname);
if (fh == FILEH_INVALID) {
ret = 1;
break;
}
if ((file_seek(fh, seekp, FSEEK_SET) != seekp) ||
(file_write(fh, sec_data[drv], 256) != 256)) {
ret = 1;
}
if (file_close(fh)) {
ret = 1;
}
break;
}
fdd->fname[0] = '\0';
fdd->type = DISKTYPE_NOTREADY;
sec_now[drv] = -1;
sec_write[drv] = 0;
return(ret);
}
RetroPC.NET-CVS <cvs@retropc.net>