mirror of
https://github.com/open-simh/simh.git
synced 2026-04-25 20:01:33 +00:00
Intel-Systems: Update and cleanup components
This commit is contained in:
committed by
Mark Pizzolato
parent
fac5bc96fb
commit
6af0958209
@@ -36,49 +36,258 @@
|
||||
|
||||
#include "system_defs.h"
|
||||
|
||||
#define UNIT_V_WPMODE (UNIT_V_UF) /* Write protect */
|
||||
#define UNIT_WPMODE (1 << UNIT_V_WPMODE)
|
||||
|
||||
/* master status register definitions */
|
||||
|
||||
#define RQM 0x80 /* Request for master */
|
||||
#define DIO 0x40 /* Data I/O Direction 0=W, 1=R */
|
||||
#define NDM 0x20 /* Non-DMA mode */
|
||||
#define CB 0x10 /* FDC busy */
|
||||
#define D3B 0x08 /* FDD 3 busy */`
|
||||
#define D2B 0x04 /* FDD 2 busy */`
|
||||
#define D1B 0x02 /* FDD 1 busy */`
|
||||
#define D0B 0x01 /* FDD 0 busy */`
|
||||
|
||||
/* status register 0 definitions */
|
||||
|
||||
#define IC 0xC0 /* Interrupt code */
|
||||
#define IC_NORM 0x00 /* normal completion */
|
||||
#define IC_ABNORM 0x40 /* abnormal completion */
|
||||
#define IC_INVC 0x80 /* invalid command */
|
||||
#define IC_RC 0xC0 /* drive not ready */
|
||||
#define SE 0x20 /* Seek end */
|
||||
#define EC 0x10 /* Equipment check */
|
||||
#define NR 0x08 /* Not ready */
|
||||
#define HD 0x04 /* Head selected */
|
||||
#define US 0x03 /* Unit selected */
|
||||
#define US_0 0x00 /* Unit 0 */
|
||||
#define US_1 0x01 /* Unit 1 */
|
||||
#define US_2 0x02 /* Unit 2 */
|
||||
#define US_3 0x03 /* Unit 3 */
|
||||
|
||||
/* status register 1 definitions */
|
||||
|
||||
#define EN 0x80 /* End of cylinder */
|
||||
#define DE 0x20 /* Data error */
|
||||
#define OR 0x10 /* Overrun */
|
||||
#define ND 0x04 /* No data */
|
||||
#define NW 0x02 /* Not writable */
|
||||
#define MA 0x01 /* Missing address mark */
|
||||
|
||||
/* status register 2 definitions */
|
||||
|
||||
#define CM 0x40 /* Control mark */
|
||||
#define DD 0x20 /* Data error in data field */
|
||||
#define WC 0x10 /* Wrong cylinder */
|
||||
#define BC 0x02 /* Bad cylinder */
|
||||
#define MD 0x01 /* Missing address mark in data field */
|
||||
|
||||
/* status register 3/fddst72 definitions */
|
||||
|
||||
#define FT 0x80 /* Fault */
|
||||
#define WP 0x40 /* Write protect */
|
||||
#define RDY 0x20 /* Ready */
|
||||
#define T0 0x10 /* Track 0 */
|
||||
#define TS 0x08 /* Two sided */
|
||||
// dups in register 0 definitions
|
||||
//#define HD 0x04 /* Head selected */
|
||||
//#define US 0x03 /* Unit selected */
|
||||
|
||||
/* FDC command definitions */
|
||||
|
||||
#define READTRK 0x02
|
||||
#define SPEC 0x03
|
||||
#define SENDRV 0x04
|
||||
#define WRITE 0x05
|
||||
#define READ 0x06
|
||||
#define HOME 0x07
|
||||
#define SENINT 0x08
|
||||
#define WRITEDEL 0x09
|
||||
#define READID 0x0A
|
||||
#define READDEL 0x0C
|
||||
#define FMTTRK 0x0D
|
||||
#define SEEK 0x0F
|
||||
#define SCANEQ 0x11
|
||||
#define SCANLOEQ 0x19
|
||||
#define SCANHIEQ 0x1D
|
||||
|
||||
#define FDD_NUM 4
|
||||
|
||||
int32 i8272_devnum = 0; //actual number of 8272 instances + 1
|
||||
uint16 i8272_port[4]; //base port registered to each instance
|
||||
|
||||
//disk geometry values
|
||||
#define MDSSD 256256 //single density FDD size
|
||||
#define MDSDD 512512 //double density FDD size
|
||||
#define MAXSECSD 26 //single density last sector
|
||||
#define MAXSECDD 52 //double density last sector
|
||||
#define MAXTRK 76 //last track
|
||||
|
||||
/* external globals */
|
||||
|
||||
extern uint16 port;
|
||||
extern uint16 port; //port called in dev_table[port]
|
||||
extern int32 PCX;
|
||||
|
||||
#define UNIT_V_ANSI (UNIT_V_UF + 0) /* ANSI mode */
|
||||
#define UNIT_ANSI (1 << UNIT_V_ANSI)
|
||||
|
||||
#define TXR 0x01
|
||||
#define RXR 0x02
|
||||
#define TXE 0x04
|
||||
#define SD 0x40
|
||||
|
||||
extern uint16 reg_dev(uint8 (*routine)(t_bool, uint8), uint16);
|
||||
|
||||
/* function prototypes */
|
||||
/* internal function prototypes */
|
||||
|
||||
t_stat i8272_svc (UNIT *uptr);
|
||||
t_stat i8272_reset (DEVICE *dptr, uint16 base);
|
||||
void i8272_reset1(uint8 devnum);
|
||||
uint8 i8272_get_dn(void);
|
||||
uint8 i8251s(t_bool io, uint8 data);
|
||||
uint8 i8251d(t_bool io, uint8 data);
|
||||
t_stat i8272_attach (UNIT *uptr, CONST char *cptr);
|
||||
t_stat i8272_set_mode (UNIT *uptr, int32 val, CONST char *cptr, void *desc);
|
||||
uint8 i8272_r00(t_bool io, uint8 data);
|
||||
uint8 i8272_r01(t_bool io, uint8 data);
|
||||
|
||||
/* globals */
|
||||
/* external function prototypes */
|
||||
|
||||
int32 i8272_devnum = 0; //initially, no 8272 instances
|
||||
uint16 i8272_port[4]; //base port assigned to each 8272 instance
|
||||
extern uint16 reg_dev(uint8 (*routine)(t_bool, uint8), uint16);
|
||||
extern void multibus_put_mbyte(uint16 addr, uint8 val);
|
||||
extern uint8 multibus_get_mbyte(uint16 addr);
|
||||
|
||||
/* i8272 Standard I/O Data Structures */
|
||||
/* up to 4 i8282 devices */
|
||||
/* 8272 physical register definitions */
|
||||
/* 8272 command register stack*/
|
||||
|
||||
UNIT i8272_unit[4] = {
|
||||
{ UDATA (&i8272_svc, 0, 0), KBD_POLL_WAIT },
|
||||
{ UDATA (&i8272_svc, 0, 0), KBD_POLL_WAIT },
|
||||
{ UDATA (&i8272_svc, 0, 0), KBD_POLL_WAIT },
|
||||
{ UDATA (&i8272_svc, 0, 0), KBD_POLL_WAIT }
|
||||
uint8 i8272_w0[4]; // MT+MFM+SK+command
|
||||
uint8 i8272_w1[4]; // HDS [HDS=H << 2] + DS1 + DS0
|
||||
uint8 i8272_w2[4]; // cylinder # (0-XX)
|
||||
uint8 i8272_w3[4]; // head # (0 or 1)
|
||||
uint8 i8272_w4[4]; // sector # (1-XX)
|
||||
uint8 i8272_w5[4]; // number of bytes (128 << N)
|
||||
uint8 i8272_w6[4]; // End of track (last sector # on cylinder)
|
||||
uint8 i8272_w7[4]; // Gap length
|
||||
uint8 i8272_w8[4]; // Data length (when N=0, size to read or write)
|
||||
|
||||
/* 8272 status register stack */
|
||||
|
||||
uint8 i8272_msr[4]; // main status
|
||||
uint8 i8272_r0[4]; // ST 0
|
||||
uint8 i8272_r1[4]; // ST 1
|
||||
uint8 i8272_r2[4]; // ST 2
|
||||
uint8 i8272_r3[4]; // ST 3
|
||||
|
||||
/* data obtained from analyzing command registers/attached file length */
|
||||
|
||||
int32 wsp72[4] = {0, 0, 0, 0}; // indexes to write stacks (8272 data)
|
||||
int32 rsp72[4] = {0, 0, 0, 0}; // indexes to read stacks (8272 data)
|
||||
int32 cyl[4]; // current cylinder
|
||||
int32 hed[4]; // current head [ h << 2]
|
||||
int32 h[4]; // current head
|
||||
int32 sec[4]; // current sector
|
||||
int32 drv[4]; // current drive
|
||||
uint8 cmd[4], pcmd[4]; // current command
|
||||
int32 secn[4]; // N 0-128, 1-256, etc
|
||||
int32 spt[4]; // sectors per track
|
||||
int32 ssize[4]; // sector size (128 << N)
|
||||
int32 nd[4]; //non-DMA mode
|
||||
|
||||
uint8 *i8272_buf[4][FDD_NUM] = { /* FDD buffer pointers */
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL
|
||||
};
|
||||
|
||||
REG i8272_reg[4] = {
|
||||
{ HRDATA (DATA, i8272_unit[0].buf, 8) },
|
||||
{ HRDATA (STAT, i8272_unit[0].u3, 8) },
|
||||
{ HRDATA (MODE, i8272_unit[0].u4, 8) },
|
||||
{ HRDATA (CMD, i8272_unit[0].u5, 8) }
|
||||
int32 fddst72[4][FDD_NUM] = { // in ST3 format
|
||||
0, // status of FDD 0
|
||||
0, // status of FDD 1
|
||||
0, // status of FDD 2
|
||||
0 // status of FDD 3
|
||||
};
|
||||
|
||||
int8 maxcyl72[4][FDD_NUM] = {
|
||||
0, // last cylinder + 1 of FDD 0
|
||||
0, // last cylinder + 1 of FDD 1
|
||||
0, // last cylinder + 1 of FDD 2
|
||||
0 // last cylinder + 1 of FDD 3
|
||||
};
|
||||
|
||||
/* i8272 Standard I/O Data Structures */
|
||||
/* up to 4 i8272 devices */
|
||||
|
||||
UNIT i8272_unit[] = {
|
||||
{ UDATA (0, UNIT_ATTABLE+UNIT_DISABLE+UNIT_BUFABLE+UNIT_MUSTBUF, MDSDD), 20 },
|
||||
{ UDATA (0, UNIT_ATTABLE+UNIT_DISABLE+UNIT_BUFABLE+UNIT_MUSTBUF, MDSDD), 20 },
|
||||
{ UDATA (0, UNIT_ATTABLE+UNIT_DISABLE+UNIT_BUFABLE+UNIT_MUSTBUF, MDSDD), 20 },
|
||||
{ UDATA (0, UNIT_ATTABLE+UNIT_DISABLE+UNIT_BUFABLE+UNIT_MUSTBUF, MDSDD), 20 }
|
||||
};
|
||||
|
||||
REG i8272_reg[] = {
|
||||
{ HRDATA (STAT720, i8272_msr[0], 8) },
|
||||
{ HRDATA (STAT7200, i8272_r0[0], 8) },
|
||||
{ HRDATA (STAT7210, i8272_r1[0], 8) },
|
||||
{ HRDATA (STAT7220, i8272_r2[0], 8) },
|
||||
{ HRDATA (STAT7230, i8272_r3[0], 8) },
|
||||
{ HRDATA (CMD7200, i8272_w0[0], 8) },
|
||||
{ HRDATA (CMD7210, i8272_w1[0], 8) },
|
||||
{ HRDATA (CMD7220, i8272_w2[0], 8) },
|
||||
{ HRDATA (CMD7230, i8272_w3[0], 8) },
|
||||
{ HRDATA (CMD7240, i8272_w4[0], 8) },
|
||||
{ HRDATA (CMD7250, i8272_w5[0], 8) },
|
||||
{ HRDATA (CMD7260, i8272_w6[0], 8) },
|
||||
{ HRDATA (CMD7270, i8272_w7[0], 8) },
|
||||
{ HRDATA (CMD7280, i8272_w8[0], 8) },
|
||||
{ HRDATA (FDC0FDD0, fddst72[0][0], 8) },
|
||||
{ HRDATA (FDC0FDD1, fddst72[0][1], 8) },
|
||||
{ HRDATA (FDC0FDD2, fddst72[0][2], 8) },
|
||||
{ HRDATA (FDC0FDD3, fddst72[0][3], 8) },
|
||||
{ HRDATA (STAT721, i8272_msr[1], 8) },
|
||||
{ HRDATA (STAT7201, i8272_r0[1], 8) },
|
||||
{ HRDATA (STAT7211, i8272_r1[1], 8) },
|
||||
{ HRDATA (STAT7221, i8272_r2[1], 8) },
|
||||
{ HRDATA (STAT7231, i8272_r3[1], 8) },
|
||||
{ HRDATA (CMD7201, i8272_w0[1], 8) },
|
||||
{ HRDATA (CMD7211, i8272_w1[1], 8) },
|
||||
{ HRDATA (CMD7221, i8272_w2[1], 8) },
|
||||
{ HRDATA (CMD7231, i8272_w3[1], 8) },
|
||||
{ HRDATA (CMD7241, i8272_w4[1], 8) },
|
||||
{ HRDATA (CMD7251, i8272_w5[1], 8) },
|
||||
{ HRDATA (CMD7261, i8272_w6[1], 8) },
|
||||
{ HRDATA (CMD7271, i8272_w7[1], 8) },
|
||||
{ HRDATA (CMD7281, i8272_w8[1], 8) },
|
||||
{ HRDATA (FDC1FDD0, fddst72[1][0], 8) },
|
||||
{ HRDATA (FDC1FDD1, fddst72[1][1], 8) },
|
||||
{ HRDATA (FDC1FDD2, fddst72[1][2], 8) },
|
||||
{ HRDATA (FDC1FDD3, fddst72[1][3], 8) },
|
||||
{ HRDATA (STAT722, i8272_msr[2], 8) },
|
||||
{ HRDATA (STAT7202, i8272_r0[2], 8) },
|
||||
{ HRDATA (STAT7212, i8272_r1[2], 8) },
|
||||
{ HRDATA (STAT7222, i8272_r2[2], 8) },
|
||||
{ HRDATA (STAT7232, i8272_r3[2], 8) },
|
||||
{ HRDATA (CMD7202, i8272_w0[2], 8) },
|
||||
{ HRDATA (CMD7212, i8272_w1[2], 8) },
|
||||
{ HRDATA (CMD7222, i8272_w2[2], 8) },
|
||||
{ HRDATA (CMD7232, i8272_w3[2], 8) },
|
||||
{ HRDATA (CMD7242, i8272_w4[2], 8) },
|
||||
{ HRDATA (CMD7252, i8272_w5[2], 8) },
|
||||
{ HRDATA (CMD7262, i8272_w6[2], 8) },
|
||||
{ HRDATA (CMD7272, i8272_w7[2], 8) },
|
||||
{ HRDATA (CMD7282, i8272_w8[2], 8) },
|
||||
{ HRDATA (FDC2FDD0, fddst72[2][0], 8) },
|
||||
{ HRDATA (FDC2FDD1, fddst72[2][1], 8) },
|
||||
{ HRDATA (FDC2FDD2, fddst72[2][2], 8) },
|
||||
{ HRDATA (FDC2FDD3, fddst72[2][3], 8) },
|
||||
{ HRDATA (STAT72_0, i8272_msr[3], 8) },
|
||||
{ HRDATA (STAT720_0, i8272_r0[3], 8) },
|
||||
{ HRDATA (STAT721_0, i8272_r1[3], 8) },
|
||||
{ HRDATA (STAT722_0, i8272_r2[3], 8) },
|
||||
{ HRDATA (STAT723_0, i8272_r3[3], 8) },
|
||||
{ HRDATA (CMD7203, i8272_w0[3], 8) },
|
||||
{ HRDATA (CMD7213, i8272_w1[3], 8) },
|
||||
{ HRDATA (CMD7223, i8272_w2[3], 8) },
|
||||
{ HRDATA (CMD7233, i8272_w3[3], 8) },
|
||||
{ HRDATA (CMD7243, i8272_w4[3], 8) },
|
||||
{ HRDATA (CMD7253, i8272_w5[3], 8) },
|
||||
{ HRDATA (CMD7263, i8272_w6[3], 8) },
|
||||
{ HRDATA (CMD7273, i8272_w7[3], 8) },
|
||||
{ HRDATA (CMD7283, i8272_w8[3], 8) },
|
||||
{ HRDATA (FDC3FDD0, fddst72[3][0], 8) },
|
||||
{ HRDATA (FDC3FDD1, fddst72[3][1], 8) },
|
||||
{ HRDATA (FDC3FDD2, fddst72[3][2], 8) },
|
||||
{ HRDATA (FDC3FDD3, fddst72[3][3], 8) },
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
DEBTAB i8272_debug[] = {
|
||||
@@ -93,8 +302,8 @@ DEBTAB i8272_debug[] = {
|
||||
};
|
||||
|
||||
MTAB i8272_mod[] = {
|
||||
{ UNIT_ANSI, 0, "TTY", "TTY", NULL },
|
||||
{ UNIT_ANSI, UNIT_ANSI, "ANSI", "ANSI", NULL },
|
||||
{ UNIT_WPMODE, 0, "RW", "RW", &i8272_set_mode },
|
||||
{ UNIT_WPMODE, UNIT_WPMODE, "WP", "WP", &i8272_set_mode },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
@@ -105,7 +314,7 @@ DEVICE i8272_dev = {
|
||||
i8272_unit, //units
|
||||
i8272_reg, //registers
|
||||
i8272_mod, //modifiers
|
||||
1, //numunits
|
||||
FDD_NUM, //numunits
|
||||
16, //aradix
|
||||
16, //awidth
|
||||
1, //aincr
|
||||
@@ -113,10 +322,9 @@ DEVICE i8272_dev = {
|
||||
8, //dwidth
|
||||
NULL, //examine
|
||||
NULL, //deposit
|
||||
// &i8272_reset, //reset
|
||||
NULL, //reset
|
||||
NULL, //boot
|
||||
NULL, //attach
|
||||
&i8272_attach, //attach
|
||||
NULL, //detach
|
||||
NULL, //ctxt
|
||||
0, //flags
|
||||
@@ -132,97 +340,555 @@ DEVICE i8272_dev = {
|
||||
|
||||
t_stat i8272_svc(UNIT *uptr)
|
||||
{
|
||||
int32 temp;
|
||||
uint32 i;
|
||||
int32 imgadr, data;
|
||||
int c;
|
||||
int32 bpt, bpc;
|
||||
FILE *fp;
|
||||
uint8 devnum;
|
||||
|
||||
sim_activate(&i8272_unit[uptr->u6], i8272_unit[uptr->u6].wait); /* continue poll */
|
||||
if (uptr->u6 >= i8272_devnum) return SCPE_OK;
|
||||
if ((temp = sim_poll_kbd()) < SCPE_KFLAG)
|
||||
return temp; /* no char or error? */
|
||||
//sim_printf("i8272_svc: received character temp=%04X devnum=%d\n", temp, uptr->u6);
|
||||
i8272_unit[uptr->u6].buf = temp & 0xFF; /* Save char */
|
||||
i8272_unit[uptr->u6].u3 |= RXR; /* Set status */
|
||||
devnum = uptr->u5; //get FDC instance
|
||||
if ((i8272_msr[devnum] & CB) && cmd[devnum] && (uptr->u6 == drv[devnum])) { /* execution phase */
|
||||
sim_debug (DEBUG_flow, &i8272_dev, "8272_svc: Entered execution phase\n");
|
||||
switch (cmd[devnum]) {
|
||||
case READ: /* 0x06 */
|
||||
// sim_printf("READ-e: fddst72=%02X", fddst72[devnum][uptr->u6]);
|
||||
h[devnum] = i8272_w3[devnum]; // h = 0 or 1
|
||||
hed[devnum] = i8272_w3[devnum] << 2; // hed = 0 or 4 [h << 2]
|
||||
sec[devnum] = i8272_w4[devnum]; // sector number (1-XX)
|
||||
secn[devnum] = i8272_w5[devnum]; // N (0-5)
|
||||
spt[devnum] = i8272_w6[devnum]; // sectors/track
|
||||
ssize[devnum] = 128 << secn[devnum]; // size of sector (bytes)
|
||||
bpt = ssize[devnum] * spt[devnum]; // bytes/track
|
||||
bpc = bpt * 2; // bytes/cylinder
|
||||
// sim_printf(" d=%d h=%d c=%d s=%d\n", drv[devnum], h[devnum], cyl[devnum], sec[devnum]);
|
||||
sim_debug (DEBUG_flow, &i8272_dev,
|
||||
"8272_svc: FDC read: h=%d, hed=%d, sec=%d, secn=%d, spt=%d, ssize=%04X, bpt=%04X, bpc=%04X\n",
|
||||
h[devnum], hed[devnum], sec[devnum], secn[devnum], spt[devnum], ssize[devnum], bpt, bpc);
|
||||
sim_debug (DEBUG_flow, &i8272_dev,
|
||||
"8272_svc: FDC read: d=%d h=%d c=%d s=%d N=%d spt=%d fddst72=%02X\n",
|
||||
drv[devnum], h[devnum], cyl[devnum], sec[devnum], secn[devnum], spt[devnum], fddst72[devnum][uptr->u6]);
|
||||
sim_debug (DEBUG_read, &i8272_dev, "8272_svc: FDC read of d=%d h=%d c=%d s=%d\n",
|
||||
drv[devnum], h[devnum], cyl[devnum], sec[devnum]);
|
||||
if ((fddst72[devnum][uptr->u6] & RDY) == 0) { // drive not ready
|
||||
i8272_r0[devnum] = IC_ABNORM + NR + hed[devnum] + drv[devnum]; /* command done - Not ready error*/
|
||||
i8272_r3[devnum] = fddst72[devnum][uptr->u6];
|
||||
i8272_msr[devnum] |= (RQM + DIO + CB); /* enter result phase */
|
||||
sim_debug (DEBUG_flow, &i8272_dev, "8272_svc: FDC read: Not Ready\n");
|
||||
} else { // get image addr for this d, h, c, s
|
||||
imgadr = (cyl[devnum] * bpc) + (h[devnum] * bpt) + ((sec[devnum] - 1) * ssize[devnum]);
|
||||
// sim_debug (DEBUG_read, &i8272_dev,
|
||||
// "8272_svc: FDC read: DMA addr=%04X cnt=%04X imgadr=%04X\n",
|
||||
// i8237_r0, i8237_r1, imgadr);
|
||||
for (i=0; i<=ssize[devnum]; i++) { /* copy selected sector to memory */
|
||||
data = *(i8272_buf[devnum][uptr->u6] + (imgadr + i));
|
||||
// multibus_put_mbyte(i8237_r0 + i, data);
|
||||
}
|
||||
//*** need to step return results IAW table 3-11 in 143078-001
|
||||
i8272_w4[devnum] = ++sec[devnum]; /* next sector */
|
||||
i8272_r0[devnum] = hed[devnum] + drv[devnum]; /* command done - no error */
|
||||
i8272_r3[devnum] = fddst72[devnum][uptr->u6];
|
||||
}
|
||||
i8272_r1[devnum] = 0;
|
||||
i8272_r2[devnum] = 0;
|
||||
i8272_w2[devnum] = cyl[devnum]; /* generate a current address mark */
|
||||
i8272_w3[devnum] = h[devnum];
|
||||
if (i8272_w4[devnum] > i8272_w6[devnum]) { // beyond last sector of track?
|
||||
i8272_w4[devnum] = 1; // yes, set to sector 1;
|
||||
if (h[devnum]) { // on head one?
|
||||
i8272_w2[devnum]++; // yes, step cylinder
|
||||
h[devnum] = 0; // back to head 0
|
||||
}
|
||||
}
|
||||
i8272_w5[devnum] = secn[devnum];
|
||||
i8272_msr[devnum] |= (RQM + DIO + CB); /* enter result phase */
|
||||
rsp72[devnum] = wsp72[devnum] = 0; /* reset indexes */
|
||||
// set_irq(I8272_INT); /* set interrupt */
|
||||
// sim_printf("READ-x: fddst72=%02X\n", fddst72[devnum][uptr->u6]);
|
||||
break;
|
||||
case WRITE: /* 0x05 */
|
||||
// sim_printf("WRITE-e: fddst72=%02X\n", fddst72[devnum][uptr->u6]);
|
||||
h[devnum] = i8272_w3[devnum]; // h = 0 or 1
|
||||
hed[devnum] = i8272_w3[devnum] << 2; // hed = 0 or 4 [h << 2]
|
||||
sec[devnum] = i8272_w4[devnum]; // sector number (1-XX)
|
||||
secn[devnum] = i8272_w5[devnum]; // N (0-5)
|
||||
spt[devnum] = i8272_w6[devnum]; // sectors/track
|
||||
ssize[devnum] = 128 << secn[devnum]; // size of sector (bytes)
|
||||
bpt = ssize[devnum] * spt[devnum]; // bytes/track
|
||||
bpc = bpt * 2; // bytes/cylinder
|
||||
sim_debug (DEBUG_flow, &i8272_dev,
|
||||
"8272_svc: FDC write: hed=%d, sec=%d, secn=%d, spt=%d, ssize=%04X, bpt=%04X, bpc=%04X\n",
|
||||
hed[devnum], sec[devnum], secn[devnum], spt[devnum], ssize[devnum], bpt, bpc);
|
||||
sim_debug (DEBUG_flow, &i8272_dev,
|
||||
"8272_svc: FDC write: d=%d h=%d c=%d s=%d N=%d spt=%d fddst72=%02X\n",
|
||||
drv[devnum], h[devnum], cyl[devnum], sec[devnum], secn[devnum], spt[devnum], fddst72[devnum][uptr->u6]);
|
||||
sim_debug (DEBUG_write, &i8272_dev, "8272_svc: FDC write of d=%d h=%d c=%d s=%d\n",
|
||||
drv[devnum], h[devnum], cyl[devnum], sec[devnum]);
|
||||
i8272_r1[devnum] = 0; // clear ST1
|
||||
i8272_r2[devnum] = 0; // clear ST2
|
||||
if ((fddst72[devnum][uptr->u6] & RDY) == 0) {
|
||||
i8272_r0[devnum] = IC_ABNORM + NR + hed[devnum] + drv[devnum]; /* Not ready error*/
|
||||
i8272_r3[devnum] = fddst72[devnum][uptr->u6];
|
||||
i8272_msr[devnum] |= (RQM + DIO + CB); /* enter result phase */
|
||||
sim_debug (DEBUG_flow, &i8272_dev, "8272_svc: FDC write: Not Ready\n");
|
||||
// } else if (fddst72[devnum][uptr->u6] & WP) {
|
||||
// i8272_r0[devnum] = IC_ABNORM + hed[devnum] + drv[devnum]; /* write protect error */
|
||||
// i8272_r1[devnum] = NW; // set not writable in ST1
|
||||
// i8272_r3[devnum] = fddst72[devnum][uptr->u6] + WP;
|
||||
// i8272_msr[devnum] |= (RQM + DIO + CB); /* enter result phase */
|
||||
// sim_printf("\nWrite Protected fddst72[%d]=%02X\n", uptr->u6, fddst72[devnum][uptr->u6]);
|
||||
// if (i8272_dev.dctrl & DEBUG_flow)
|
||||
// sim_printf("8272_svc: FDC write: Write Protected\n");
|
||||
} else { // get image addr for this d, h, c, s
|
||||
imgadr = (cyl[devnum] * bpc) + (h[devnum] * bpt) + ((sec[devnum] - 1) * ssize[devnum]);
|
||||
// sim_debug (DEBUG_write, &i8272_dev,
|
||||
// "8272_svc: FDC write: DMA adr=%04X cnt=%04X imgadr=%04X\n",
|
||||
// i8237_r0, i8237_r1, imgadr);
|
||||
for (i=0; i<=ssize[devnum]; i++) { /* copy selected memory to image */
|
||||
// data = multibus_get_mbyte(i8237_r0 + i);
|
||||
*(i8272_buf[devnum][uptr->u6] + (imgadr + i)) = data;
|
||||
}
|
||||
//*** quick fix. Needs more thought!
|
||||
// fp = fopen(uptr->filename, "wb"); // write out modified image
|
||||
// for (i=0; i<uptr->capac; i++) {
|
||||
// c = *(i8272_buf[devnum][uptr->u6] + i) & 0xFF;
|
||||
// fputc(c, fp);
|
||||
// }
|
||||
// fclose(fp);
|
||||
//*** need to step return results IAW table 3-11 in 143078-001
|
||||
i8272_w2[devnum] = cyl[devnum]; /* generate a current address mark */
|
||||
i8272_w3[devnum] = hed[devnum] >> 2;
|
||||
i8272_w4[devnum] = ++sec[devnum]; /* next sector */
|
||||
i8272_w5[devnum] = secn[devnum];
|
||||
i8272_r0[devnum] = hed[devnum] + drv[devnum]; /* command done - no error */
|
||||
i8272_r3[devnum] = fddst72[devnum][uptr->u6];
|
||||
i8272_msr[devnum] |= (RQM + DIO + CB); /* enter result phase */
|
||||
}
|
||||
rsp72[devnum] = wsp72[devnum] = 0; /* reset indexes */
|
||||
// set_irq(I8272_INT); /* set interrupt */
|
||||
// sim_printf("WRITE-x: fddst72=%02X\n", fddst72[devnum][uptr->u6]);
|
||||
break;
|
||||
case FMTTRK: /* 0x0D */
|
||||
if ((fddst72[devnum][uptr->u6] & RDY) == 0) {
|
||||
i8272_r0[devnum] = IC_ABNORM + NR + hed[devnum] + drv[devnum]; /* Not ready error*/
|
||||
i8272_msr[devnum] |= (RQM + DIO + CB); /* enter result phase */
|
||||
sim_debug (DEBUG_flow, &i8272_dev, "8272_svc: Not Ready\n");
|
||||
} else if (fddst72[devnum][uptr->u6] & WP) {
|
||||
i8272_r0[devnum] = IC_ABNORM + hed[devnum] + drv[devnum]; /* write protect error*/
|
||||
i8272_r3[devnum] = fddst72[devnum][uptr->u6] + WP;
|
||||
i8272_msr[devnum] |= (RQM + DIO + CB); /* enter result phase */
|
||||
sim_debug (DEBUG_flow, &i8272_dev, "8272_svc: Write Protected\n");
|
||||
} else {
|
||||
; /* do nothing for now */
|
||||
i8272_msr[devnum] |= (RQM + DIO + CB); /* enter result phase */
|
||||
}
|
||||
rsp72[devnum] = wsp72[devnum] = 0; /* reset indexes */
|
||||
// set_irq(I8272_INT); /* set interrupt */
|
||||
break;
|
||||
case SENINT: /* 0x08 */
|
||||
i8272_msr[devnum] |= (RQM + DIO + CB); /* enter result phase */
|
||||
i8272_r0[devnum] = hed[devnum] + drv[devnum]; /* command done - no error */
|
||||
i8272_r1[devnum] = 0;
|
||||
i8272_r2[devnum] = 0;
|
||||
rsp72[devnum] = wsp72[devnum] = 0; /* reset indexes */
|
||||
// clr_irq(I8272_INT); /* clear interrupt */
|
||||
break;
|
||||
case SENDRV: /* 0x04 */
|
||||
sim_debug (DEBUG_flow, &i8272_dev, "8272_svc: FDC sense drive: d=%d fddst72=%02X\n",
|
||||
drv[devnum], fddst72[devnum][uptr->u6]);
|
||||
i8272_msr[devnum] |= (RQM + DIO + CB); /* enter result phase */
|
||||
i8272_r0[devnum] = hed[devnum] + drv[devnum]; /* command done - no error */
|
||||
i8272_r1[devnum] = 0;
|
||||
i8272_r2[devnum] = 0;
|
||||
i8272_r3[devnum] = fddst72[devnum][drv[devnum]]; /* drv status */
|
||||
rsp72[devnum] = wsp72[devnum] = 0; /* reset indexes */
|
||||
break;
|
||||
case HOME: /* 0x07 */
|
||||
// sim_printf("HOME-e: fddst72=%02X\n", fddst72[devnum][uptr->u6]);
|
||||
sim_debug (DEBUG_flow, &i8272_dev, "8272_svc: FDC home: d=%d fddst72=%02X\n",
|
||||
drv[devnum], fddst72[devnum][uptr->u6]);
|
||||
if ((fddst72[devnum][uptr->u6] & RDY) == 0) {
|
||||
i8272_r0[devnum] = IC_ABNORM + NR + hed[devnum] + drv[devnum]; /* Not ready error*/
|
||||
i8272_r3[devnum] = fddst72[devnum][uptr->u6];
|
||||
sim_debug (DEBUG_flow, &i8272_dev, "8272_svc: Not Ready\n");
|
||||
} else {
|
||||
cyl[devnum] = 0; /* now on cylinder 0 */
|
||||
fddst72[devnum][drv[devnum]] |= T0; /* set status flag */
|
||||
i8272_r0[devnum] = SE + hed[devnum] + drv[devnum]; /* seek end - no error */
|
||||
}
|
||||
i8272_r1[devnum] = 0;
|
||||
i8272_r2[devnum] = 0;
|
||||
i8272_msr[devnum] &= ~(RQM + DIO + CB + hed[devnum] + drv[devnum]); /* execution phase done*/
|
||||
i8272_msr[devnum] |= RQM; /* enter COMMAND phase */
|
||||
rsp72[devnum] = wsp72[devnum] = 0; /* reset indexes */
|
||||
// set_irq(I8272_INT); /* set interrupt */
|
||||
// sim_printf("HOME-x: fddst72=%02X\n", fddst72[devnum][uptr->u6]);
|
||||
break;
|
||||
case SPEC: /* 0x03 */
|
||||
fddst72[devnum][0] |= TS; //*** bad, bad, bad!
|
||||
fddst72[devnum][1] |= TS;
|
||||
fddst72[devnum][2] |= TS;
|
||||
fddst72[devnum][3] |= TS;
|
||||
// sim_printf("SPEC-e: fddst72[%d]=%02X\n", uptr->u6, fddst72[devnum][uptr->u6]);
|
||||
sim_debug (DEBUG_flow, &i8272_dev,
|
||||
"8272_svc: FDC specify: SRT=%d ms HUT=%d ms HLT=%d ms ND=%d\n",
|
||||
16 - (drv[devnum] >> 4), 16 * (drv[devnum] & 0x0f), i8272_w2[devnum] & 0xfe, nd[devnum]);
|
||||
i8272_r0[devnum] = hed[devnum] + drv[devnum]; /* command done - no error */
|
||||
i8272_r1[devnum] = 0;
|
||||
i8272_r2[devnum] = 0;
|
||||
// i8272_msr[devnum] &= ~(RQM + DIO + CB); /* execution phase done*/
|
||||
i8272_msr[devnum] = 0; // force 0 for now, where does 0x07 come from?
|
||||
i8272_msr[devnum] |= RQM + (nd[devnum] ? ND : 0); /* enter command phase */
|
||||
rsp72[devnum] = wsp72[devnum] = 0; /* reset indexes */
|
||||
// sim_printf("SPEC-x: fddst72[%d]=%02X\n", uptr->u6, fddst72[devnum][uptr->u6]);
|
||||
break;
|
||||
case READID: /* 0x0A */
|
||||
if ((fddst72[devnum][uptr->u6] & RDY) == 0) {
|
||||
i8272_r0[devnum] = IC_RC + NR + hed[devnum] + drv[devnum]; /* Not ready error*/
|
||||
i8272_r3[devnum] = fddst72[devnum][uptr->u6];
|
||||
sim_debug (DEBUG_flow, &i8272_dev, "8272_svc: Not Ready\n");
|
||||
} else {
|
||||
i8272_w2[devnum] = cyl[devnum]; /* generate a valid address mark */
|
||||
i8272_w3[devnum] = hed[devnum] >> 2;
|
||||
i8272_w4[devnum] = 1; /* always sector 1 */
|
||||
i8272_w5[devnum] = secn[devnum];
|
||||
i8272_r0[devnum] = hed[devnum] + drv[devnum]; /* command done - no error */
|
||||
i8272_msr[devnum] &= ~(RQM + DIO + CB); /* execution phase done*/
|
||||
i8272_msr[devnum] |= RQM; /* enter command phase */
|
||||
}
|
||||
i8272_r1[devnum] = 0;
|
||||
i8272_r2[devnum] = 0;
|
||||
rsp72[devnum] = wsp72[devnum] = 0; /* reset indexes */
|
||||
break;
|
||||
case SEEK: /* 0x0F */
|
||||
// sim_printf("SEEK-e: fddst72=%02X\n", fddst72[devnum][uptr->u6]);
|
||||
sim_debug (DEBUG_flow, &i8272_dev, "8272_svc: FDC seek: d=%d c=%d fddst72=%02X\n",
|
||||
drv[devnum], i8272_w2, fddst72[devnum][uptr->u6]);
|
||||
if ((fddst72[devnum][uptr->u6] & RDY) == 0) { /* Not ready? */
|
||||
i8272_r0[devnum] = IC_ABNORM + NR + hed[devnum] + drv[devnum]; /* error*/
|
||||
i8272_r3[devnum] = fddst72[devnum][uptr->u6];
|
||||
sim_debug (DEBUG_flow, &i8272_dev, "8272_svc: FDC seek: Not Ready\n");
|
||||
} else if (i8272_w2[devnum] >= maxcyl72[devnum][uptr->u6]) {
|
||||
i8272_r0[devnum] = IC_ABNORM + RDY + hed[devnum] + drv[devnum]; /* seek error*/
|
||||
sim_debug (DEBUG_flow, &i8272_dev, "8272_svc: FDC seek: Invalid Cylinder %d\n", i8272_w2);
|
||||
} else {
|
||||
i8272_r0[devnum] |= SE + hed[devnum] + drv[devnum]; /* command done - no error */
|
||||
cyl[devnum] = i8272_w2[devnum]; /* new cylinder number */
|
||||
if (cyl[devnum] == 0) { /* if cyl 0, set flag */
|
||||
fddst72[devnum][drv[devnum]] |= T0; /* set T0 status flag */
|
||||
i8272_r3[devnum] |= T0;
|
||||
} else {
|
||||
fddst72[devnum][drv[devnum]] &= ~T0; /* clear T0 status flag */
|
||||
i8272_r3[devnum] &= ~T0;
|
||||
}
|
||||
}
|
||||
i8272_r1[devnum] = 0;
|
||||
i8272_r2[devnum] = 0;
|
||||
i8272_msr[devnum] &= ~(RQM + DIO + CB + hed[devnum] + drv[devnum]); /* execution phase done*/
|
||||
i8272_msr[devnum] |= RQM; /* enter command phase */
|
||||
rsp72[devnum] = wsp72[devnum] = 0; /* reset indexes */
|
||||
// set_irq(I8272_INT); /* set interrupt */
|
||||
// sim_printf("SEEK-x: fddst72=%02X\n", fddst72[devnum][uptr->u6]);
|
||||
break;
|
||||
default:
|
||||
i8272_msr[devnum] &= ~(RQM + DIO + CB); /* execution phase done*/
|
||||
i8272_msr[devnum] |= RQM; /* enter command phase */
|
||||
i8272_r0[devnum] = IC_INVC + hed[devnum] + drv[devnum]; /* set bad command error */
|
||||
i8272_r1[devnum] = 0;
|
||||
i8272_r2[devnum] = 0;
|
||||
rsp72[devnum] = wsp72[devnum] = 0; /* reset indexes */
|
||||
break;
|
||||
}
|
||||
pcmd[devnum] = cmd[devnum]; /* save for result phase */
|
||||
cmd[devnum] = 0; /* reset command */
|
||||
sim_debug (DEBUG_flow, &i8272_dev,
|
||||
"8272_svc: Exit: msr=%02X ST0=%02X ST1=%02X ST2=%02X ST3=%02X\n",
|
||||
i8272_msr[devnum], i8272_r0[devnum], i8272_r1[devnum], i8272_r2[devnum], i8272_r3);
|
||||
}
|
||||
sim_activate (&i8272_unit[uptr->u6], i8272_unit[uptr->u6].wait);
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
/* Reset routine */
|
||||
/* i8272 hardware reset routine */
|
||||
|
||||
t_stat i8272_reset(DEVICE *dptr, uint16 base)
|
||||
{
|
||||
if (i8272_devnum >= i8272_NUM) {
|
||||
sim_printf("8251_reset: too many devices!\n");
|
||||
if (i8272_devnum >= I8272_NUM) {
|
||||
sim_printf("8272_reset: too many devices!\n");
|
||||
return 0;
|
||||
}
|
||||
i8272_reset1(i8272_devnum);
|
||||
sim_printf(" 8251-%d: Registered at %03X\n", i8272_devnum, base);
|
||||
i8272_port[i8272_devnum] = reg_dev(i8251d, base);
|
||||
reg_dev(i8251s, base + 1);
|
||||
i8272_unit[i8272_devnum].u6 = i8272_devnum;
|
||||
sim_activate(&i8272_unit[i8272_devnum], i8272_unit[i8272_devnum].wait); /* activate unit */
|
||||
i8272_devnum++;
|
||||
if (I8272_NUM) {
|
||||
sim_printf(" I8272-%d: Hardware Reset\n", i8272_devnum);
|
||||
sim_printf(" I8272-%d: Registered at %04X\n", i8272_devnum, base);
|
||||
i8272_port[i8272_devnum] = reg_dev(i8272_r00, I8272_BASE + 0);
|
||||
reg_dev(i8272_r01, I8272_BASE + 1);
|
||||
if ((i8272_dev.flags & DEV_DIS) == 0)
|
||||
i8272_reset1(i8272_devnum);
|
||||
i8272_devnum++;
|
||||
} else {
|
||||
sim_printf(" No isbc208 installed\n");
|
||||
}
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
/* i8272 software reset routine */
|
||||
|
||||
void i8272_reset1(uint8 devnum)
|
||||
{
|
||||
i8272_unit[devnum].u3 = TXR + TXE; /* status */
|
||||
i8272_unit[devnum].u4 = 0; /* mode instruction */
|
||||
i8272_unit[devnum].u5 = 0; /* command instruction */
|
||||
i8272_unit[devnum].buf = 0;
|
||||
i8272_unit[devnum].pos = 0;
|
||||
sim_printf(" 8251-%d: Reset\n", devnum);
|
||||
int32 i;
|
||||
UNIT *uptr;
|
||||
static int flag = 1;
|
||||
|
||||
if (flag) sim_printf("I8272: Initializing\n");
|
||||
for (i = 0; i < FDD_NUM; i++) { /* handle all units */
|
||||
uptr = i8272_dev.units + i;
|
||||
if (uptr->capac == 0) { /* if not configured */
|
||||
// sim_printf(" i8272%d: Not configured\n", i);
|
||||
// if (flag) {
|
||||
// sim_printf(" ALL: \"set isbc208 en\"\n");
|
||||
// sim_printf(" EPROM: \"att isbc2080 <filename>\"\n");
|
||||
// flag = 0;
|
||||
// }
|
||||
uptr->capac = 0; /* initialize unit */
|
||||
uptr->u3 = 0;
|
||||
uptr->u4 = 0;
|
||||
uptr->u5 = devnum; // i8272 device instance - only set here!
|
||||
uptr->u6 = i; /* FDD number - only set here! */
|
||||
fddst72[devnum][i] = WP + T0 + i; /* initial drive status */
|
||||
uptr->flags |= UNIT_WPMODE; /* set WP in unit flags */
|
||||
sim_activate (&i8272_unit[uptr->u6], i8272_unit[uptr->u6].wait);
|
||||
} else {
|
||||
fddst72[devnum][i] = RDY + WP + T0 + i; /* initial attach drive status */
|
||||
// sim_printf(" i8272%d: Configured, Attached to %s\n", i, uptr->filename);
|
||||
}
|
||||
}
|
||||
i8272_msr[devnum] = RQM; /* 8272 ready for start of command */
|
||||
rsp72[devnum] = wsp72[devnum] = 0; /* reset indexes */
|
||||
cmd[devnum] = 0; /* clear command */
|
||||
sim_printf(" i8272-%d: Software Reset\n", i8272_devnum);
|
||||
if (flag) {
|
||||
sim_printf(" 8272 Reset\n");
|
||||
}
|
||||
flag = 0;
|
||||
}
|
||||
|
||||
uint8 i8272_get_dn(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i=0; i<i8272_NUM; i++)
|
||||
if (port >=i8272_port[i] && port <= i8272_port[i] + 1)
|
||||
for (i=0; i<I8272_NUM; i++)
|
||||
if (port >= i8272_port[i] && port <= i8272_port[i] + 1)
|
||||
return i;
|
||||
sim_printf("i8272_get_dn: port %03X not in 8251 device table\n", port);
|
||||
sim_printf("i8272_get_dn: port %03X not in 8272 device table\n", port);
|
||||
return 0xFF;
|
||||
}
|
||||
|
||||
/* i8272 attach - attach an .IMG file to an FDD on a FDC */
|
||||
|
||||
t_stat i8272_attach (UNIT *uptr, CONST char *cptr)
|
||||
{
|
||||
t_stat r;
|
||||
uint8 fdcnum, fddnum, devnum;
|
||||
int i;
|
||||
long flen;
|
||||
|
||||
sim_debug (DEBUG_flow, &i8272_dev, " i8272_attach: Entered with cptr=%s\n", cptr);
|
||||
if ((r = attach_unit (uptr, cptr)) != SCPE_OK) {
|
||||
sim_printf(" i8272_attach: Attach error\n");
|
||||
return r;
|
||||
}
|
||||
devnum = fdcnum = uptr->u5;
|
||||
fddnum = uptr->u6;
|
||||
flen = uptr->capac;
|
||||
fddst72[devnum][uptr->u6] |= RDY; /* set unit ready */
|
||||
for (i=0; i<fddnum; i++) { //for each disk drive
|
||||
if (flen == 368640) { /* 5" 360K DSDD */
|
||||
maxcyl72[devnum][uptr->u6] = 40;
|
||||
fddst72[devnum][uptr->u6] |= TS; // two sided
|
||||
}
|
||||
else if (flen == 737280) { /* 5" 720K DSQD / 3.5" 720K DSDD */
|
||||
maxcyl72[devnum][uptr->u6] = 80;
|
||||
fddst72[devnum][uptr->u6] |= TS; // two sided
|
||||
}
|
||||
else if (flen == 1228800) { /* 5" 1.2M DSHD */
|
||||
maxcyl72[devnum][uptr->u6] = 80;
|
||||
fddst72[devnum][uptr->u6] |= TS; // two sided
|
||||
}
|
||||
else if (flen == 1474560) { /* 3.5" 1.44M DSHD */
|
||||
maxcyl72[devnum][uptr->u6] = 80;
|
||||
fddst72[devnum][uptr->u6] |= TS; // two sided
|
||||
}
|
||||
sim_printf(" Drive-%d: %d bytes of disk image %s loaded, fddst72=%02X\n",
|
||||
uptr->u6, i, uptr->filename, fddst72[devnum][uptr->u6]);
|
||||
}
|
||||
sim_debug (DEBUG_flow, &i8272_dev, " i8272_attach: Done\n");
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
/* i8272 set mode */
|
||||
/* Handle write protect */
|
||||
|
||||
t_stat i8272_set_mode (UNIT *uptr, int32 val, CONST char *cptr, void *desc)
|
||||
{
|
||||
uint8 devnum;
|
||||
|
||||
sim_debug (DEBUG_flow, &i8272_dev, " i8272_set_mode: Entered with val=%08XH uptr->flags=%08X\n",
|
||||
val, uptr->flags);
|
||||
devnum = uptr->u5;
|
||||
if (val & UNIT_WPMODE) { /* write protect */
|
||||
fddst72[devnum][uptr->u6] |= WP;
|
||||
uptr->flags |= val;
|
||||
} else { /* read write */
|
||||
fddst72[devnum][uptr->u6] &= ~WP;
|
||||
uptr->flags &= ~val;
|
||||
}
|
||||
// sim_printf("fddst72[%d]=%02XH uptr->flags=%08X\n", uptr->u6, fddst72[devnum][uptr->u6], uptr->flags);
|
||||
sim_debug (DEBUG_flow, &i8272_dev, " i8272_set_mode: Done\n");
|
||||
return SCPE_OK;
|
||||
}
|
||||
/* I/O instruction handlers, called from the CPU module when an
|
||||
IN or OUT instruction is issued.
|
||||
*/
|
||||
|
||||
uint8 i8251s(t_bool io, uint8 data)
|
||||
uint8 i8272_r00(t_bool io, uint8 data)
|
||||
{
|
||||
uint8 devnum;
|
||||
|
||||
if ((devnum = i8272_get_dn()) != 0xFF) {
|
||||
if (io == 0) { /* read status port */
|
||||
return i8272_unit[devnum].u3;
|
||||
} else { /* write status port */
|
||||
if (i8272_unit[devnum].u6) { /* if mode, set cmd */
|
||||
i8272_unit[devnum].u5 = data;
|
||||
sim_printf(" 8251-%d: Command Instruction=%02X\n", devnum, data);
|
||||
if (data & SD) /* reset port! */
|
||||
i8272_reset1(devnum);
|
||||
} else { /* set mode */
|
||||
i8272_unit[devnum].u4 = data;
|
||||
sim_printf(" 8251-%d: Mode Instruction=%02X\n", devnum, data);
|
||||
i8272_unit[devnum].u6 = 1; /* set cmd received */
|
||||
if (io == 0) { /* read FDC status register */
|
||||
sim_debug (DEBUG_reg, &i8272_dev, "i8272_msr read as %02X\n", i8272_msr[devnum]);
|
||||
return i8272_msr[devnum];
|
||||
} else {
|
||||
sim_debug (DEBUG_reg, &i8272_dev, "Illegal write to i8272_r0\n");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// read/write FDC data register stack
|
||||
|
||||
uint8 i8272_r01(t_bool io, uint8 data)
|
||||
{
|
||||
uint8 devnum;
|
||||
|
||||
if ((devnum = i8272_get_dn()) != 0xFF) {
|
||||
if (io == 0) { /* read FDC data register */
|
||||
wsp72[devnum] = 0; /* clear write stack index */
|
||||
switch (rsp72[devnum]) { /* read from next stack register */
|
||||
case 0:
|
||||
sim_debug (DEBUG_reg, &i8272_dev, "i8272_r1 read as %02X\n", i8272_r1[devnum]);
|
||||
sim_debug (DEBUG_reg, &i8272_dev, "i8272_r3 read as %02X\n", i8272_r3[devnum]);
|
||||
rsp72[devnum]++; /* step read stack index */
|
||||
// clr_irq(I8272_INT); /* clear interrupt */
|
||||
if (pcmd[devnum] == SENDRV) {
|
||||
i8272_msr[devnum] = RQM; /* result phase SENDRV done */
|
||||
return i8272_r1[devnum]; // SENDRV return ST1
|
||||
}
|
||||
return i8272_r0[devnum]; /* ST0 */
|
||||
case 1:
|
||||
sim_debug (DEBUG_reg, &i8272_dev, "i8272_r2 read as %02X\n", i8272_r2[devnum]);
|
||||
rsp72[devnum]++; /* step read stack index */
|
||||
if (pcmd[devnum] == SENINT) {
|
||||
i8272_msr[devnum] = RQM; /* result phase SENINT done */
|
||||
return cyl[devnum]; // SENINT return current cylinder
|
||||
}
|
||||
return i8272_r1[devnum]; /* ST1 */
|
||||
case 2:
|
||||
sim_debug (DEBUG_reg, &i8272_dev, "i8272_r3 read as %02X\n", i8272_r3[devnum]);
|
||||
rsp72[devnum]++; /* step read stack index */
|
||||
return i8272_r2[devnum]; /* ST2 */
|
||||
case 3:
|
||||
sim_debug (DEBUG_reg, &i8272_dev, "i8272_w2 read as %02X\n", i8272_w2);
|
||||
rsp72[devnum]++; /* step read stack index */
|
||||
return i8272_w2[devnum]; /* C - cylinder */
|
||||
case 4:
|
||||
sim_debug (DEBUG_reg, &i8272_dev, "i8272_w3 read as %02X\n", i8272_w3[devnum]);
|
||||
rsp72[devnum]++; /* step read stack index */
|
||||
return i8272_w3[devnum]; /* H - head */
|
||||
case 5:
|
||||
sim_debug (DEBUG_reg, &i8272_dev, "i8272_w4 read as %02X\n", i8272_w4[devnum]);
|
||||
rsp72[devnum]++; /* step read stack index */
|
||||
return i8272_w4[devnum]; /* R - sector */
|
||||
case 6:
|
||||
sim_debug (DEBUG_reg, &i8272_dev, "i8272_w5 read as %02X\n", i8272_w5[devnum]);
|
||||
i8272_msr[devnum] = RQM; /* result phase ALL OTHERS done */
|
||||
return i8272_w5[devnum]; /* N - sector size*/
|
||||
}
|
||||
} else { /* write FDC data register */
|
||||
rsp72[devnum] = 0; /* clear read stack index */
|
||||
switch (wsp72[devnum]) { /* write to next stack register */
|
||||
case 0:
|
||||
i8272_w0[devnum] = data; /* rws = MT + MFM + SK + cmd */
|
||||
cmd[devnum] = data & 0x1F; /* save the current command */
|
||||
sim_debug (DEBUG_reg, &i8272_dev, "i8272_w0 set to %02X\n", data);
|
||||
if (cmd[devnum] == SENINT) {
|
||||
i8272_msr[devnum] = CB; /* command phase SENINT done */
|
||||
return 0;
|
||||
}
|
||||
wsp72[devnum]++; /* step write stack index */
|
||||
break;
|
||||
case 1:
|
||||
i8272_w1[devnum] = data; /* rws = hed + drv */
|
||||
if (cmd[devnum] != SPEC)
|
||||
drv[devnum] = data & 0x03;
|
||||
sim_debug (DEBUG_reg, &i8272_dev, "i8272_w1 set to %02X\n", data);
|
||||
if (cmd[devnum] == HOME || cmd[devnum] == SENDRV || cmd[devnum] == READID) {
|
||||
i8272_msr[devnum] = CB + hed[devnum] + drv[devnum]; /* command phase HOME, READID and SENDRV done */
|
||||
return 0;
|
||||
}
|
||||
wsp72[devnum]++; /* step write stack index */
|
||||
break;
|
||||
case 2:
|
||||
i8272_w2[devnum] = data; /* rws = C */
|
||||
sim_debug (DEBUG_reg, &i8272_dev, "i8272_w2 set to %02X\n", data);
|
||||
if (cmd[devnum] == SPEC || cmd[devnum] == SEEK) {
|
||||
i8272_msr[devnum] = CB + hed[devnum] + drv[devnum]; /* command phase SPECIFY and SEEK done */
|
||||
return 0;
|
||||
}
|
||||
wsp72[devnum]++; /* step write stack index */
|
||||
break;
|
||||
case 3:
|
||||
i8272_w3[devnum] = data; /* rw = H */
|
||||
hed[devnum] = data;
|
||||
wsp72[devnum]++; /* step write stack index */
|
||||
sim_debug (DEBUG_reg, &i8272_dev, "i8272_w3 set to %02X\n", data);
|
||||
break;
|
||||
case 4:
|
||||
i8272_w4[devnum] = data; /* rw = R */
|
||||
sec[devnum] = data;
|
||||
wsp72[devnum]++; /* step write stack index */
|
||||
sim_debug (DEBUG_reg, &i8272_dev, "i8272_w4 set to %02X\n", data);
|
||||
break;
|
||||
case 5:
|
||||
i8272_w5[devnum] = data; /* rw = N */
|
||||
sim_debug (DEBUG_reg, &i8272_dev, "i8272_w5 set to %02X\n", data);
|
||||
if (cmd[devnum] == FMTTRK) {
|
||||
i8272_msr[devnum] = CB + hed[devnum] + drv[devnum]; /* command phase FMTTRK done */
|
||||
return 0;
|
||||
}
|
||||
wsp72[devnum]++; /* step write stack index */
|
||||
break;
|
||||
case 6:
|
||||
i8272_w6[devnum] = data; /* rw = last sector number */
|
||||
wsp72[devnum]++; /* step write stack index */
|
||||
sim_debug (DEBUG_reg, &i8272_dev, "i8272_w6 set to %02X\n", data);
|
||||
break;
|
||||
case 7:
|
||||
i8272_w7[devnum] = data; /* rw = gap length */
|
||||
wsp72[devnum]++; /* step write stack index */
|
||||
sim_debug (DEBUG_reg, &i8272_dev, "i8272_w7 set to %02X\n", data);
|
||||
break;
|
||||
case 8:
|
||||
i8272_w8[devnum] = data; /* rw = bytes to transfer */
|
||||
sim_debug (DEBUG_reg, &i8272_dev, "i8272_w8 set to %02X\n", data);
|
||||
if (cmd[devnum] == READ || cmd[devnum] == WRITE)
|
||||
i8272_msr[devnum] = CB + hed[devnum] + drv[devnum]; /* command phase all others done */
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint8 i8251d(t_bool io, uint8 data)
|
||||
{
|
||||
uint8 devnum;
|
||||
|
||||
if ((devnum = i8272_get_dn()) != 0xFF) {
|
||||
if (io == 0) { /* read data port */
|
||||
i8272_unit[devnum].u3 &= ~RXR;
|
||||
return (i8272_unit[devnum].buf);
|
||||
} else { /* write data port */
|
||||
sim_putchar(data);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* end of i8272.c */
|
||||
|
||||
Reference in New Issue
Block a user