mirror of
https://github.com/simh/simh.git
synced 2026-04-27 20:38:04 +00:00
Altair8800: SIMH device and WD17XX API corrections
SIMH: Adds support for wildcard filename transfers WD17XX: Corrects a problem with DRQ status
This commit is contained in:
@@ -36,13 +36,15 @@
|
|||||||
#include "s100_cpu.h"
|
#include "s100_cpu.h"
|
||||||
#include "s100_simh.h"
|
#include "s100_simh.h"
|
||||||
|
|
||||||
static t_stat simh_dev_reset(DEVICE *dptr);
|
static t_stat simh_reset(DEVICE *dptr);
|
||||||
static int32 simh_io_status(const int32 port, const int32 io, const int32 data);
|
static int32 simh_io_status(const int32 port, const int32 io, const int32 data);
|
||||||
static int32 simh_io_data(const int32 port, const int32 io, const int32 data);
|
static int32 simh_io_data(const int32 port, const int32 io, const int32 data);
|
||||||
static int32 simh_io_cmd(const int32 port, const int32 io, const int32 data);
|
static int32 simh_io_cmd(const int32 port, const int32 io, const int32 data);
|
||||||
static int32 simh_cmd_in(const int32 port);
|
static int32 simh_cmd_in(const int32 port);
|
||||||
static int32 simh_cmd_out(const int32 port, const int32 data);
|
static int32 simh_cmd_out(const int32 port, const int32 data);
|
||||||
static t_stat simh_show_help(FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, const char *cptr);
|
static t_stat simh_show_help(FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, const char *cptr);
|
||||||
|
static void deleteNameList(void);
|
||||||
|
static void processDirEntry(const char *directory, const char *filename, t_offset FileSize, const struct stat *filestat, void *context);
|
||||||
static void createCPMCommandLine(void);
|
static void createCPMCommandLine(void);
|
||||||
static void attachCPM(UNIT *uptr, int32 readOnly);
|
static void attachCPM(UNIT *uptr, int32 readOnly);
|
||||||
static void detachCPM(UNIT *uptr);
|
static void detachCPM(UNIT *uptr);
|
||||||
@@ -121,13 +123,23 @@ const char* simh_description(DEVICE *dptr) {
|
|||||||
DEVICE simh_dev = {
|
DEVICE simh_dev = {
|
||||||
"SIMH", &simh_unit, simh_reg, simh_mod,
|
"SIMH", &simh_unit, simh_reg, simh_mod,
|
||||||
1, ADDRRADIX, ADDRWIDTH, 1, DATARADIX, DATAWIDTH,
|
1, ADDRRADIX, ADDRWIDTH, 1, DATARADIX, DATAWIDTH,
|
||||||
NULL, NULL, &simh_dev_reset,
|
NULL, NULL, &simh_reset,
|
||||||
NULL, NULL, NULL,
|
NULL, NULL, NULL,
|
||||||
NULL, (DEV_DISABLE | DEV_DEBUG), 0,
|
NULL, (DEV_DISABLE | DEV_DEBUG), 0,
|
||||||
generic_dt, NULL, NULL, &simh_show_help, NULL, NULL, &simh_description
|
generic_dt, NULL, NULL, &simh_show_help, NULL, NULL, &simh_description
|
||||||
};
|
};
|
||||||
|
|
||||||
|
typedef struct NameNode {
|
||||||
|
char *name;
|
||||||
|
struct NameNode *next;
|
||||||
|
} NameNode_t;
|
||||||
|
|
||||||
static char cpmCommandLine[CPM_COMMAND_LINE_LENGTH];
|
static char cpmCommandLine[CPM_COMMAND_LINE_LENGTH];
|
||||||
|
static NameNode_t *nameListHead = NULL;
|
||||||
|
static NameNode_t *currentName = NULL;
|
||||||
|
static int32 currentNameIndex = 0;
|
||||||
|
static int32 lastPathSeparatorIndex = 0;
|
||||||
|
static int32 firstPathCharacterIndex = 0;
|
||||||
|
|
||||||
/* Z80 or 8080 programs communicate with the SIMH pseudo device via port 0xfe.
|
/* Z80 or 8080 programs communicate with the SIMH pseudo device via port 0xfe.
|
||||||
The following principles apply:
|
The following principles apply:
|
||||||
@@ -183,6 +195,7 @@ static char cpmCommandLine[CPM_COMMAND_LINE_LENGTH];
|
|||||||
#define setZ80CPUCmd 19 /* 19 set the CPU to a Z80 */
|
#define setZ80CPUCmd 19 /* 19 set the CPU to a Z80 */
|
||||||
#define set8080CPUCmd 20 /* 20 set the CPU to an 8080 */
|
#define set8080CPUCmd 20 /* 20 set the CPU to an 8080 */
|
||||||
#define getHostOSPathSeparatorCmd 28 /* 28 obtain the file path separator of the OS under which SIMH runs */
|
#define getHostOSPathSeparatorCmd 28 /* 28 obtain the file path separator of the OS under which SIMH runs */
|
||||||
|
#define getHostFilenamesCmd 29 /* 29 perform wildcard expansion and obtain list of file names */
|
||||||
#define kSimhPseudoDeviceCommands 35 /* Highest AltairZ80 SIMH command */
|
#define kSimhPseudoDeviceCommands 35 /* Highest AltairZ80 SIMH command */
|
||||||
|
|
||||||
static const char *cmdNames[kSimhPseudoDeviceCommands] = {
|
static const char *cmdNames[kSimhPseudoDeviceCommands] = {
|
||||||
@@ -215,7 +228,7 @@ static const char *cmdNames[kSimhPseudoDeviceCommands] = {
|
|||||||
"Undefined",
|
"Undefined",
|
||||||
"Undefined",
|
"Undefined",
|
||||||
"getHostOSPathSeparator",
|
"getHostOSPathSeparator",
|
||||||
"Undefined",
|
"getHostFilenames",
|
||||||
"Undefined",
|
"Undefined",
|
||||||
"Undefined",
|
"Undefined",
|
||||||
"Undefined",
|
"Undefined",
|
||||||
@@ -225,7 +238,7 @@ static const char *cmdNames[kSimhPseudoDeviceCommands] = {
|
|||||||
|
|
||||||
static char version[] = "SIMH005";
|
static char version[] = "SIMH005";
|
||||||
|
|
||||||
static t_stat simh_dev_reset(DEVICE *dptr) {
|
static t_stat simh_reset(DEVICE *dptr) {
|
||||||
if (dptr->flags & DEV_DIS) {
|
if (dptr->flags & DEV_DIS) {
|
||||||
s100_bus_remio(0xfe, 1, &simh_io_cmd); /* Command Port */
|
s100_bus_remio(0xfe, 1, &simh_io_cmd); /* Command Port */
|
||||||
}
|
}
|
||||||
@@ -245,6 +258,32 @@ static t_stat simh_dev_reset(DEVICE *dptr) {
|
|||||||
return SCPE_OK;
|
return SCPE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void deleteNameList(void)
|
||||||
|
{
|
||||||
|
while (nameListHead != NULL) {
|
||||||
|
NameNode_t *next = nameListHead -> next;
|
||||||
|
free(nameListHead -> name);
|
||||||
|
free(nameListHead);
|
||||||
|
nameListHead = next;
|
||||||
|
}
|
||||||
|
|
||||||
|
currentName = NULL;
|
||||||
|
currentNameIndex = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void processDirEntry(const char *directory, const char *filename, t_offset FileSize, const struct stat *filestat, void *context)
|
||||||
|
{
|
||||||
|
if (filename != NULL) {
|
||||||
|
NameNode_t *top = (NameNode_t *) malloc(sizeof(NameNode_t));
|
||||||
|
if (top) {
|
||||||
|
top->name = strdup(filename);
|
||||||
|
top->next = nameListHead;
|
||||||
|
nameListHead = top;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static void createCPMCommandLine(void) {
|
static void createCPMCommandLine(void) {
|
||||||
int32 i, len = (s100_bus_memr(FCBAddress) & 0x7f); /* 0x80 contains length of command line, discard first char */
|
int32 i, len = (s100_bus_memr(FCBAddress) & 0x7f); /* 0x80 contains length of command line, discard first char */
|
||||||
for (i = 0; i < len - 1; i++) {
|
for (i = 0; i < len - 1; i++) {
|
||||||
@@ -332,17 +371,43 @@ static int32 simh_cmd_in(const int32 port)
|
|||||||
result = sim_file_path_separator;
|
result = sim_file_path_separator;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case getHostFilenamesCmd:
|
||||||
|
if (nameListHead != NULL) {
|
||||||
|
if (currentName == NULL) {
|
||||||
|
deleteNameList();
|
||||||
|
lastCommand = 0;
|
||||||
|
}
|
||||||
|
else if (firstPathCharacterIndex <= lastPathSeparatorIndex) {
|
||||||
|
result = cpmCommandLine[firstPathCharacterIndex++];
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
result = currentName -> name[currentNameIndex];
|
||||||
|
|
||||||
|
if (result == 0) {
|
||||||
|
currentName = currentName -> next;
|
||||||
|
firstPathCharacterIndex = currentNameIndex = 0;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
currentNameIndex++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
sim_debug(VERBOSE_MSG, &simh_dev, "SIMH: " ADDRESS_FORMAT
|
sim_debug(VERBOSE_MSG, &simh_dev, "SIMH: " ADDRESS_FORMAT
|
||||||
" Undefined IN from SIMH pseudo device on port %03xh ignored.\n",
|
" Undefined IN from SIMH pseudo device on port %03xh ignored.\n",
|
||||||
s100_bus_get_addr(), port);
|
s100_bus_get_addr(), port);
|
||||||
|
|
||||||
result = lastCommand = 0;
|
result = lastCommand = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int32 simh_cmd_out(const int32 port, const int32 data) {
|
static int32 simh_cmd_out(const int32 port, const int32 data)
|
||||||
|
{
|
||||||
|
t_stat result;
|
||||||
|
|
||||||
switch(lastCommand) {
|
switch(lastCommand) {
|
||||||
default: /* lastCommand not yet set */
|
default: /* lastCommand not yet set */
|
||||||
@@ -394,6 +459,40 @@ static int32 simh_cmd_out(const int32 port, const int32 data) {
|
|||||||
case getHostOSPathSeparatorCmd:
|
case getHostOSPathSeparatorCmd:
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case getHostFilenamesCmd: /* list files of host file directory */
|
||||||
|
if (nameListHead == NULL) {
|
||||||
|
|
||||||
|
createCPMCommandLine();
|
||||||
|
|
||||||
|
lastPathSeparatorIndex = 0;
|
||||||
|
|
||||||
|
while (cpmCommandLine[lastPathSeparatorIndex]) {
|
||||||
|
lastPathSeparatorIndex++;
|
||||||
|
}
|
||||||
|
|
||||||
|
while ((lastPathSeparatorIndex >= 0) && (cpmCommandLine[lastPathSeparatorIndex] != sim_file_path_separator)) {
|
||||||
|
lastPathSeparatorIndex--;
|
||||||
|
}
|
||||||
|
|
||||||
|
firstPathCharacterIndex = 0;
|
||||||
|
|
||||||
|
deleteNameList();
|
||||||
|
|
||||||
|
result = sim_dir_scan(cpmCommandLine, processDirEntry, NULL);
|
||||||
|
|
||||||
|
if (result == SCPE_OK) {
|
||||||
|
currentName = nameListHead;
|
||||||
|
currentNameIndex = 0;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
deleteNameList();
|
||||||
|
|
||||||
|
sim_debug(VERBOSE_MSG, &simh_dev, "SIMH: " ADDRESS_FORMAT " Cannot expand '%s'. Error is %s.\n",
|
||||||
|
s100_bus_get_addr(), cpmCommandLine, sim_error_text(result));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
sim_debug(CMD_MSG, &simh_dev, "SIMH: " ADDRESS_FORMAT
|
sim_debug(CMD_MSG, &simh_dev, "SIMH: " ADDRESS_FORMAT
|
||||||
" Unknown command (%i) to SIMH pseudo device on port %03xh ignored.\n",
|
" Unknown command (%i) to SIMH pseudo device on port %03xh ignored.\n",
|
||||||
@@ -404,20 +503,22 @@ static int32 simh_cmd_out(const int32 port, const int32 data) {
|
|||||||
return 0xff; /* ignored, since OUT */
|
return 0xff; /* ignored, since OUT */
|
||||||
}
|
}
|
||||||
|
|
||||||
/* port 0xfc is a device for communication SIMH <--> Altair machine */
|
/* port 0x12 is a device for communication SIMH <--> Altair machine */
|
||||||
static int32 simh_io_status(const int32 port, const int32 io, const int32 data)
|
static int32 simh_io_status(const int32 port, const int32 io, const int32 data)
|
||||||
{
|
{
|
||||||
if (io == S100_IO_READ) { /* IN */
|
if (io == S100_IO_READ) { /* IN */
|
||||||
if ((simh_unit.flags & UNIT_ATT) == 0) { /* SIMH is not attached */
|
if ((simh_unit.flags & UNIT_ATT) == 0) { /* SIMH is not attached */
|
||||||
if ((simh_dev.dctrl & VERBOSE_MSG) && (warnUnattachedSIMH < warnLevelSIMH)) {
|
if ((simh_dev.dctrl & VERBOSE_MSG) && (warnUnattachedSIMH < warnLevelSIMH)) {
|
||||||
warnUnattachedSIMH++;
|
warnUnattachedSIMH++;
|
||||||
/*06*/ sim_debug(VERBOSE_MSG, &simh_dev, "PTR: " ADDRESS_FORMAT
|
|
||||||
|
sim_debug(VERBOSE_MSG, &simh_dev, "PTR: " ADDRESS_FORMAT
|
||||||
" Attempt to test status of unattached SIMH[0x%02x]. 0x02 returned.\n", s100_bus_get_addr(), port);
|
" Attempt to test status of unattached SIMH[0x%02x]. 0x02 returned.\n", s100_bus_get_addr(), port);
|
||||||
}
|
}
|
||||||
|
|
||||||
return SIMH_CAN_WRITE;
|
return SIMH_CAN_WRITE;
|
||||||
}
|
}
|
||||||
/* if EOF then SIMH_CAN_WRITE else
|
|
||||||
(SIMH_CAN_WRITE and SIMH_CAN_READ) */
|
/* if EOF then SIMH_CAN_WRITE else (SIMH_CAN_WRITE and SIMH_CAN_READ) */
|
||||||
return simh_unit.u3 ? SIMH_CAN_WRITE : (SIMH_CAN_READ | SIMH_CAN_WRITE);
|
return simh_unit.u3 ? SIMH_CAN_WRITE : (SIMH_CAN_READ | SIMH_CAN_WRITE);
|
||||||
} /* OUT follows */
|
} /* OUT follows */
|
||||||
if (data == SIMH_RESET) {
|
if (data == SIMH_RESET) {
|
||||||
@@ -425,47 +526,58 @@ static int32 simh_io_status(const int32 port, const int32 io, const int32 data)
|
|||||||
sim_debug(CMD_MSG, &simh_dev, "SIMH: " ADDRESS_FORMAT
|
sim_debug(CMD_MSG, &simh_dev, "SIMH: " ADDRESS_FORMAT
|
||||||
" Command OUT(0x%03x) = 0x%02x\n", s100_bus_get_addr(), port, data);
|
" Command OUT(0x%03x) = 0x%02x\n", s100_bus_get_addr(), port, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0x00; /* ignored since OUT */
|
return 0x00; /* ignored since OUT */
|
||||||
}
|
}
|
||||||
|
|
||||||
/* port 0xfd is a device for communication SIMH <--> Altair machine */
|
/* port 0x13 is a device for communication SIMH <--> Altair machine */
|
||||||
static int32 simh_io_data(const int32 port, const int32 io, const int32 data)
|
static int32 simh_io_data(const int32 port, const int32 io, const int32 data)
|
||||||
{
|
{
|
||||||
int32 ch;
|
int32 ch;
|
||||||
|
|
||||||
if (io == S100_IO_READ) { /* IN */
|
if (io == S100_IO_READ) { /* IN */
|
||||||
if (simh_unit.u3) { /* EOF reached, no more data available */
|
if (simh_unit.u3) { /* EOF reached, no more data available */
|
||||||
if ((simh_dev.dctrl & VERBOSE_MSG) && (warnSIMHEOF < warnLevelSIMH)) {
|
if ((simh_dev.dctrl & VERBOSE_MSG) && (warnSIMHEOF < warnLevelSIMH)) {
|
||||||
warnSIMHEOF++;
|
warnSIMHEOF++;
|
||||||
/*07*/ sim_debug(VERBOSE_MSG, &simh_dev, "PTR: " ADDRESS_FORMAT
|
|
||||||
|
sim_debug(VERBOSE_MSG, &simh_dev, "PTR: " ADDRESS_FORMAT
|
||||||
" SIMH[0x%02x] attempted to read past EOF. 0x00 returned.\n", s100_bus_get_addr(), port);
|
" SIMH[0x%02x] attempted to read past EOF. 0x00 returned.\n", s100_bus_get_addr(), port);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0x00;
|
return 0x00;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((simh_unit.flags & UNIT_ATT) == 0) { /* not attached */
|
if ((simh_unit.flags & UNIT_ATT) == 0) { /* not attached */
|
||||||
if ((simh_dev.dctrl & VERBOSE_MSG) && (warnUnattachedSIMH < warnLevelSIMH)) {
|
if ((simh_dev.dctrl & VERBOSE_MSG) && (warnUnattachedSIMH < warnLevelSIMH)) {
|
||||||
warnUnattachedSIMH++;
|
warnUnattachedSIMH++;
|
||||||
/*08*/ sim_debug(VERBOSE_MSG, &simh_dev, "SIMH: " ADDRESS_FORMAT
|
sim_debug(VERBOSE_MSG, &simh_dev, "SIMH: " ADDRESS_FORMAT
|
||||||
" Attempt to read from unattached SIMH[0x%02x]. 0x00 returned.\n", s100_bus_get_addr(), port);
|
" Attempt to read from unattached SIMH[0x%02x]. 0x00 returned.\n", s100_bus_get_addr(), port);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0x00;
|
return 0x00;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((ch = getc(simh_unit.fileref)) == EOF) { /* end of file? */
|
if ((ch = getc(simh_unit.fileref)) == EOF) { /* end of file? */
|
||||||
simh_unit.u3 = TRUE; /* remember EOF reached */
|
simh_unit.u3 = TRUE; /* remember EOF reached */
|
||||||
sim_debug(VERBOSE_MSG, &simh_dev, "SIMH: " ADDRESS_FORMAT
|
sim_debug(VERBOSE_MSG, &simh_dev, "SIMH: " ADDRESS_FORMAT
|
||||||
" EOF on read\n", s100_bus_get_addr());
|
" EOF on read\n", s100_bus_get_addr());
|
||||||
|
|
||||||
return CONTROLZ_CHAR; /* ^Z denotes end of text file in CP/M */
|
return CONTROLZ_CHAR; /* ^Z denotes end of text file in CP/M */
|
||||||
}
|
}
|
||||||
|
|
||||||
return ch & 0xff;
|
return ch & 0xff;
|
||||||
} /* OUT follows */
|
} /* OUT follows */
|
||||||
if (simh_unit.flags & UNIT_ATT) /* unit must be attached */
|
|
||||||
|
if (simh_unit.flags & UNIT_ATT) { /* unit must be attached */
|
||||||
putc(data, simh_unit.fileref);
|
putc(data, simh_unit.fileref);
|
||||||
/* else ignore data */
|
}
|
||||||
else if ((simh_dev.dctrl & VERBOSE_MSG) && (warnUnattachedSIMH < warnLevelSIMH)) {
|
else if ((simh_dev.dctrl & VERBOSE_MSG) && (warnUnattachedSIMH < warnLevelSIMH)) {
|
||||||
warnUnattachedSIMH++;
|
warnUnattachedSIMH++;
|
||||||
/*09*/ sim_debug(VERBOSE_MSG, &simh_dev, "SIMH: " ADDRESS_FORMAT
|
|
||||||
|
sim_debug(VERBOSE_MSG, &simh_dev, "SIMH: " ADDRESS_FORMAT
|
||||||
" Attempt to output '0x%02x' to unattached SIMH[0x%02x] - ignored.\n", s100_bus_get_addr(), data, port);
|
" Attempt to output '0x%02x' to unattached SIMH[0x%02x] - ignored.\n", s100_bus_get_addr(), data, port);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0x00; /* ignored since OUT */
|
return 0x00; /* ignored since OUT */
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -481,7 +593,8 @@ static int32 simh_io_cmd(const int32 port, const int32 io, const int32 data)
|
|||||||
port, result, result,
|
port, result, result,
|
||||||
(32 <= (result & 0xff)) && ((result & 0xff) <= 127) ? (result & 0xff) : '?');
|
(32 <= (result & 0xff)) && ((result & 0xff) <= 127) ? (result & 0xff) : '?');
|
||||||
|
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
sim_debug(OUT_MSG, &simh_dev, "SIMH: " ADDRESS_FORMAT
|
sim_debug(OUT_MSG, &simh_dev, "SIMH: " ADDRESS_FORMAT
|
||||||
" OUT(0x%02x) <- %i (0x%02x, '%c')\n", s100_bus_get_addr(),
|
" OUT(0x%02x) <- %i (0x%02x, '%c')\n", s100_bus_get_addr(),
|
||||||
port, data, data,
|
port, data, data,
|
||||||
|
|||||||
@@ -45,6 +45,7 @@ static uint8 wd17xx_sec_len(WD17XX_INFO *wd);
|
|||||||
static t_stat wd17xx_read_sector(WD17XX_INFO *wd, uint8 *sbuf, int32 *bytesread);
|
static t_stat wd17xx_read_sector(WD17XX_INFO *wd, uint8 *sbuf, int32 *bytesread);
|
||||||
static t_stat wd17xx_write_sector(WD17XX_INFO *wd, uint8 *sbuf, int32 *byteswritten);
|
static t_stat wd17xx_write_sector(WD17XX_INFO *wd, uint8 *sbuf, int32 *byteswritten);
|
||||||
static void wd17xx_set_intrq(WD17XX_INFO *wd, int32 value);
|
static void wd17xx_set_intrq(WD17XX_INFO *wd, int32 value);
|
||||||
|
static void wd17xx_set_drq(WD17XX_INFO *wd, int32 value);
|
||||||
|
|
||||||
WD17XX_INFO * wd17xx_init(DEVICE *dptr)
|
WD17XX_INFO * wd17xx_init(DEVICE *dptr)
|
||||||
{
|
{
|
||||||
@@ -601,13 +602,13 @@ static void wd17xx_command(WD17XX_INFO *wd, uint8 cmd)
|
|||||||
|
|
||||||
wd->status |= (WD17XX_STAT_DRQ); /* Set DRQ */
|
wd->status |= (WD17XX_STAT_DRQ); /* Set DRQ */
|
||||||
wd->status |= (wd->dsk->unit->flags & UNIT_RO) ? WD17XX_STAT_WP : 0; /* Set WP */
|
wd->status |= (wd->dsk->unit->flags & UNIT_RO) ? WD17XX_STAT_WP : 0; /* Set WP */
|
||||||
wd->drq = 1;
|
|
||||||
wd->fdc_datacount = dsk_sector_size(wd->dsk, wd->track, wd->side);
|
wd->fdc_datacount = dsk_sector_size(wd->dsk, wd->track, wd->side);
|
||||||
wd->fdc_dataindex = 0;
|
wd->fdc_dataindex = 0;
|
||||||
wd->fdc_write = TRUE;
|
wd->fdc_write = TRUE;
|
||||||
wd->fdc_write_track = FALSE;
|
wd->fdc_write_track = FALSE;
|
||||||
wd->fdc_read = FALSE;
|
wd->fdc_read = FALSE;
|
||||||
wd->fdc_readadr = FALSE;
|
wd->fdc_readadr = FALSE;
|
||||||
|
wd17xx_set_drq(wd, 1);
|
||||||
|
|
||||||
sbuf[wd->fdc_dataindex] = wd->data;
|
sbuf[wd->fdc_dataindex] = wd->data;
|
||||||
break;
|
break;
|
||||||
@@ -626,11 +627,11 @@ static void wd17xx_command(WD17XX_INFO *wd, uint8 cmd)
|
|||||||
wd17xx_set_intrq(wd, TRUE);
|
wd17xx_set_intrq(wd, TRUE);
|
||||||
} else {
|
} else {
|
||||||
wd->status = (WD17XX_STAT_DRQ | WD17XX_STAT_BUSY); /* Set DRQ, BUSY */
|
wd->status = (WD17XX_STAT_DRQ | WD17XX_STAT_BUSY); /* Set DRQ, BUSY */
|
||||||
wd->drq = 1;
|
|
||||||
wd->fdc_datacount = 6;
|
wd->fdc_datacount = 6;
|
||||||
wd->fdc_dataindex = 0;
|
wd->fdc_dataindex = 0;
|
||||||
wd->fdc_read = TRUE;
|
wd->fdc_read = TRUE;
|
||||||
wd->fdc_readadr = TRUE;
|
wd->fdc_readadr = TRUE;
|
||||||
|
wd17xx_set_drq(wd, 1);
|
||||||
|
|
||||||
sbuf[0] = wd->track;
|
sbuf[0] = wd->track;
|
||||||
sbuf[1] = wd->side;
|
sbuf[1] = wd->side;
|
||||||
@@ -676,13 +677,13 @@ static void wd17xx_command(WD17XX_INFO *wd, uint8 cmd)
|
|||||||
sim_debug(wd->dbg_command, wd->dptr, WD17XX_NAME ADDRESS_FORMAT " CMD=FORCE_INTR\n", s100_bus_get_addr());
|
sim_debug(wd->dbg_command, wd->dptr, WD17XX_NAME ADDRESS_FORMAT " CMD=FORCE_INTR\n", s100_bus_get_addr());
|
||||||
if ((cmd & WD17XX_CMD_MASK) == 0) { /* I0-I3 == 0, no intr, but clear BUSY and terminate command */
|
if ((cmd & WD17XX_CMD_MASK) == 0) { /* I0-I3 == 0, no intr, but clear BUSY and terminate command */
|
||||||
wd->status &= ~(WD17XX_STAT_DRQ | WD17XX_STAT_BUSY); /* Clear DRQ, BUSY */
|
wd->status &= ~(WD17XX_STAT_DRQ | WD17XX_STAT_BUSY); /* Clear DRQ, BUSY */
|
||||||
wd->drq = 0;
|
|
||||||
wd->fdc_write = FALSE;
|
wd->fdc_write = FALSE;
|
||||||
wd->fdc_read = FALSE;
|
wd->fdc_read = FALSE;
|
||||||
wd->fdc_write_track = FALSE;
|
wd->fdc_write_track = FALSE;
|
||||||
wd->fdc_readadr = FALSE;
|
wd->fdc_readadr = FALSE;
|
||||||
wd->fdc_datacount = 0;
|
wd->fdc_datacount = 0;
|
||||||
wd->fdc_dataindex = 0;
|
wd->fdc_dataindex = 0;
|
||||||
|
wd17xx_set_drq(wd, 0);
|
||||||
}
|
}
|
||||||
else if (cmd & 0x08) { /* Immediate Interrupt */
|
else if (cmd & 0x08) { /* Immediate Interrupt */
|
||||||
wd17xx_set_intrq(wd, TRUE);
|
wd17xx_set_intrq(wd, TRUE);
|
||||||
@@ -757,7 +758,7 @@ static void wd17xx_command(WD17XX_INFO *wd, uint8 cmd)
|
|||||||
s100_bus_int(1 << wd->intvector, wd->intvector * 2);
|
s100_bus_int(1 << wd->intvector, wd->intvector * 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
wd->drq = 1;
|
wd17xx_set_drq(wd, 1);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/* Type IV Commands */
|
/* Type IV Commands */
|
||||||
@@ -840,6 +841,12 @@ static void wd17xx_set_intrq(WD17XX_INFO *wd, int32 value)
|
|||||||
wd->drq = !wd->intrq;
|
wd->drq = !wd->intrq;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void wd17xx_set_drq(WD17XX_INFO *wd, int32 value)
|
||||||
|
{
|
||||||
|
wd->drq = (value) ? TRUE : FALSE; /* INTRQ and DRQ are mutually exclusive */
|
||||||
|
wd->intrq = !wd->drq;
|
||||||
|
}
|
||||||
|
|
||||||
void wd17xx_show(WD17XX_INFO *wd)
|
void wd17xx_show(WD17XX_INFO *wd)
|
||||||
{
|
{
|
||||||
sim_debug(wd->dbg_verbose, wd->dptr, "fdctype: %02X\n", wd->fdctype);
|
sim_debug(wd->dbg_verbose, wd->dptr, "fdctype: %02X\n", wd->fdctype);
|
||||||
|
|||||||
Reference in New Issue
Block a user