simh-testsetgenerator/AltairZ80/s100_tdd.c
Mark Pizzolato decbe5b76b Various simulators: Set line endings to CRLF for consistency, remove stray tabs
Project standard source code has tabs converted to spaces and CRLF line
endings.

Other text files have CRLF line endings.
2023-03-19 16:51:27 -04:00

180 lines
7.9 KiB
C

/*************************************************************************
* *
* Copyright (c) 2022 Howard M. Harte. *
* https://github.com/hharte *
* *
* Permission is hereby granted, free of charge, to any person obtaining *
* a copy of this software and associated documentation files (the *
* "Software"), to deal in the Software without restriction, including *
* without limitation the rights to use, copy, modify, merge, publish, *
* distribute, sublicense, and/or sell copies of the Software, and to *
* permit persons to whom the Software is furnished to do so, subject to *
* the following conditions: *
* *
* The above copyright notice and this permission notice shall be *
* included in all copies or substantial portions of the Software. *
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, *
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF *
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON- *
* INFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE *
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN *
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN *
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE *
* SOFTWARE. *
* *
* Except as contained in this notice, the names of The Authors shall *
* not be used in advertising or otherwise to promote the sale, use or *
* other dealings in this Software without prior written authorization *
* from the Authors. *
* *
* Based on s100_64fdc.c *
* *
* Module Description: *
* Tarbell Double-Density Floppy Controller module for SIMH. *
* This module is a wrapper around the wd179x FDC module. *
* *
* Reference: *
* http://www.bitsavers.org/pdf/tarbell/Tarbell_Double_Density_Floppy_Disk_Interface_Jul81.pdf
* *
*************************************************************************/
#include "altairz80_defs.h"
#include "sim_defs.h"
#include "wd179x.h"
#define DEV_NAME "TDD"
/* Debug flags */
#define STATUS_MSG (1 << 0)
#define DRIVE_MSG (1 << 1)
#define VERBOSE_MSG (1 << 2)
#define IRQ_MSG (1 << 3)
#define TDD_MAX_DRIVES 4
#define TDD_IO_BASE 0x7C
#define TDD_IO_SIZE 0x2
#define TDD_IO_MASK (TDD_IO_SIZE - 1)
typedef struct {
PNP_INFO pnp; /* Plug and Play */
} TDD_INFO;
extern WD179X_INFO_PUB *wd179x_infop;
static TDD_INFO tdd_info_data = { { 0x0000, 0, TDD_IO_BASE, TDD_IO_SIZE } };
extern t_stat set_iobase(UNIT *uptr, int32 val, CONST char *cptr, void *desc);
extern t_stat show_iobase(FILE *st, UNIT *uptr, int32 val, CONST void *desc);
extern uint32 sim_map_resource(uint32 baseaddr, uint32 size, uint32 resource_type,
int32 (*routine)(const int32, const int32, const int32), const char* name, uint8 unmap);
extern uint32 PCX; /* external view of PC */
#define TDD_CAPACITY (77*1*26*128) /* Default SSSD 8" (IBM 3740) Disk Capacity */
static t_stat tdd_reset(DEVICE *tdd_dev);
static int32 tdd_control(const int32 port, const int32 io, const int32 data);
static const char* tdd_description(DEVICE *dptr);
#define TDD_FLAG_EOJ (1 << 7) /* End of Job (INTRQ) */
static UNIT tdd_unit[] = {
{ UDATA (NULL, UNIT_FIX + UNIT_ATTABLE + UNIT_DISABLE + UNIT_ROABLE, TDD_CAPACITY) },
{ UDATA (NULL, UNIT_FIX + UNIT_ATTABLE + UNIT_DISABLE + UNIT_ROABLE, TDD_CAPACITY) },
{ UDATA (NULL, UNIT_FIX + UNIT_ATTABLE + UNIT_DISABLE + UNIT_ROABLE, TDD_CAPACITY) },
{ UDATA (NULL, UNIT_FIX + UNIT_ATTABLE + UNIT_DISABLE + UNIT_ROABLE, TDD_CAPACITY) }
};
static REG tdd_reg[] = {
{ NULL }
};
#define TDD_NAME "Tarbell Double-Density FDC"
static const char* tdd_description(DEVICE *dptr) {
if (dptr == NULL) {
return NULL;
}
return TDD_NAME;
}
static MTAB tdd_mod[] = {
{ MTAB_XTD|MTAB_VDV, 0, "IOBASE", "IOBASE",
&set_iobase, &show_iobase, NULL, "Sets disk controller I/O base address" },
{ 0 }
};
/* Debug Flags */
static DEBTAB tdd_dt[] = {
{ "STATUS", STATUS_MSG, "Status messages" },
{ "DRIVE", DRIVE_MSG, "Drive messages" },
{ "VERBOSE", VERBOSE_MSG, "Verbose messages" },
{ "IRQ", IRQ_MSG, "IRQ messages" },
{ NULL, 0 }
};
DEVICE tdd_dev = {
DEV_NAME, tdd_unit, tdd_reg, tdd_mod,
TDD_MAX_DRIVES, 10, 31, 1, TDD_MAX_DRIVES, TDD_MAX_DRIVES,
NULL, NULL, &tdd_reset,
NULL, &wd179x_attach, &wd179x_detach,
&tdd_info_data, (DEV_DISABLE | DEV_DIS | DEV_DEBUG), 0,
tdd_dt, NULL, NULL, NULL, NULL, NULL, &tdd_description
};
/* Reset routine */
static t_stat tdd_reset(DEVICE *dptr)
{
PNP_INFO *pnp = (PNP_INFO *)dptr->ctxt;
if(dptr->flags & DEV_DIS) { /* Disconnect ROM and I/O Ports */
/* Unmap I/O Ports */
sim_map_resource(pnp->io_base, 1, RESOURCE_TYPE_IO, &tdd_control, "tdd_control", TRUE);
} else {
/* Connect TDD Disk Flags and Control Register */
if(sim_map_resource(pnp->io_base, pnp->io_size, RESOURCE_TYPE_IO, &tdd_control, "tdd_control", FALSE) != 0) {
sim_printf("%s: error mapping I/O resource at 0x%04x\n", __FUNCTION__, pnp->io_base);
return SCPE_ARG;
}
}
return SCPE_OK;
}
/* Tarbell pp. 12-5 Disk Control/Status */
static int32 tdd_control(const int32 port, const int32 io, const int32 data)
{
int32 result = 0;
if(io) { /* I/O Write */
if ((port & TDD_IO_MASK) == 0) {
wd179x_infop->fdc_head = (data & 0x40) >> 6;
wd179x_infop->sel_drive = (data & 0x30) >> 4;
wd179x_infop->ddens = (data & 0x08) >> 3;
sim_debug(DRIVE_MSG, &tdd_dev, DEV_NAME ": " ADDRESS_FORMAT " WR CTRL(0x%02x) = 0x%02x: Drive: %d, Head: %d, %s-Density.\n",
PCX, port,
data & 0xFF,
wd179x_infop->sel_drive,
wd179x_infop->fdc_head,
wd179x_infop->ddens == 1 ? "Double" : "Single");
} else {
sim_debug(STATUS_MSG, &tdd_dev, DEV_NAME ": " ADDRESS_FORMAT
" Write Extended Address, Port 0x%02x=0x%02x\n", PCX, port, data);
}
} else { /* I/O Read */
if ((port & TDD_IO_MASK) == 0) {
result = (wd179x_infop->intrq) ? 0 : TDD_FLAG_EOJ;
sim_debug(STATUS_MSG, &tdd_dev, DEV_NAME ": " ADDRESS_FORMAT
" Read EOJ, Port 0x%02x Result 0x%02x\n", PCX, port, result);
} else {
result = (wd179x_infop->drq) ? TDD_FLAG_EOJ : 0;
sim_debug(STATUS_MSG, &tdd_dev, DEV_NAME ": " ADDRESS_FORMAT
" Read DRQ, Port 0x%02x Result 0x%02x\n", PCX, port, result);
}
}
return result;
}