AltairZ80: Add Tarbell Double-Density FDC
This controller is based the wd179x, adding a couple of Tarbell-specific registers.
This commit is contained in:
parent
6c398df0ae
commit
f77485ca99
2 changed files with 183 additions and 0 deletions
|
@ -68,6 +68,7 @@ extern DEVICE hdc1001_dev;
|
|||
|
||||
extern DEVICE jade_dev;
|
||||
extern DEVICE tarbell_dev;
|
||||
extern DEVICE tdd_dev;
|
||||
extern DEVICE icom_dev;
|
||||
extern DEVICE dj2d_dev;
|
||||
extern DEVICE m2sio0_dev;
|
||||
|
@ -129,6 +130,7 @@ DEVICE *sim_devices[] = {
|
|||
&jade_dev,
|
||||
/* Tarbell Devices */
|
||||
&tarbell_dev,
|
||||
&tdd_dev,
|
||||
/* iCOM Devices */
|
||||
&icom_dev,
|
||||
/* Disk Jockey 2D Devices */
|
||||
|
|
181
AltairZ80/s100_tdd.c
Normal file
181
AltairZ80/s100_tdd.c
Normal file
|
@ -0,0 +1,181 @@
|
|||
/*************************************************************************
|
||||
* *
|
||||
* 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 } };
|
||||
static TDD_INFO *tdd_info = &tdd_info_data;
|
||||
|
||||
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;
|
||||
}
|
Loading…
Add table
Reference in a new issue