1
0
mirror of https://github.com/open-simh/simh.git synced 2026-04-28 21:07:43 +00:00

ISYS8010, ISYS8020: Latest update

This commit is contained in:
Bill Beech
2016-12-05 12:54:15 -07:00
parent 0ef87fac53
commit 2947c39ffe
34 changed files with 4084 additions and 897 deletions

View File

@@ -26,7 +26,7 @@
MODIFICATIONS:
?? ??? 10 - Original file.
16 Dec 12 - Modified to use isbc_80_10.cfg file to set base and size.
16 Dec 12 - Modified to use isbc_80_10.cfg file to set baseport and size.
24 Apr 15 -- Modified to use simh_debug
NOTES:
@@ -111,6 +111,10 @@
#include "system_defs.h"
/* external globals */
extern uint16 port; //port called in dev_table[port]
#define UNIT_V_ANSI (UNIT_V_UF + 0) /* ANSI mode */
#define UNIT_ANSI (1 << UNIT_V_ANSI)
@@ -119,14 +123,22 @@
#define TXE 0x04
#define SD 0x40
extern uint8 reg_dev(uint8 (*routine)(t_bool, uint8, uint8), uint16, uint8);
/* external function prototypes */
extern uint16 reg_dev(uint8 (*routine)(t_bool, uint8), uint16, uint8);
/* globals */
int32 i8251_devnum = 0; //actual number of 8251 instances + 1
uint16 i8251_port[4]; //baseport port registered to each instance
/* function prototypes */
t_stat i8251_svc (UNIT *uptr);
t_stat i8251_reset (DEVICE *dptr, uint16 base, uint8 devnum);
uint8 i8251s(t_bool io, uint8 data, uint8 devnum);
uint8 i8251d(t_bool io, uint8 data, uint8 devnum);
t_stat i8251_reset (DEVICE *dptr, uint16 baseport);
uint8 i8251_get_dn(void);
uint8 i8251s(t_bool io, uint8 data);
uint8 i8251d(t_bool io, uint8 data);
void i8251_reset1(uint8 devnum);
/* i8251 Standard I/O Data Structures */
@@ -164,20 +176,20 @@ MTAB i8251_mod[] = {
/* address width is set to 16 bits to use devices in 8086/8088 implementations */
DEVICE i8251_dev = {
"8251", //name
"I8251", //name
&i8251_unit, //units
i8251_reg, //registers
i8251_mod, //modifiers
1, //numunits
16, //aradix
16, //awidth
16, //awidth
1, //aincr
16, //dradix
8, //dwidth
NULL, //examine
NULL, //deposit
// &i8251_reset, //reset
NULL, //reset
NULL, //reset
NULL, //boot
NULL, //attach
NULL, //detach
@@ -211,65 +223,23 @@ t_stat i8251_svc (UNIT *uptr)
/* Reset routine */
t_stat i8251_reset (DEVICE *dptr, uint16 base, uint8 devnum)
t_stat i8251_reset (DEVICE *dptr, uint16 baseport)
{
if (devnum >= I8251_NUM) {
sim_printf("8251_reset: Illegal Device Number %d\n", devnum);
if (i8251_devnum >= I8251_NUM) {
sim_printf("8251_reset: Illegal Device Number %d\n", i8251_devnum);
return 0;
}
reg_dev(i8251d, base, devnum);
reg_dev(i8251s, base + 1, devnum);
reg_dev(i8251d, base + 2, devnum);
reg_dev(i8251s, base + 3, devnum);
i8251_reset1(devnum);
sim_printf(" 8251-%d: Registered at %04X\n", devnum, base);
sim_printf(" 8251-%d: Hardware Reset\n", i8251_devnum);
sim_printf(" 8251-%d: Registered at %04X\n", i8251_devnum, baseport);
i8251_port[i8251_devnum] = baseport;
reg_dev(i8251d, baseport, i8251_devnum);
reg_dev(i8251s, baseport + 1, i8251_devnum);
i8251_reset1(i8251_devnum);
sim_activate (&i8251_unit, i8251_unit.wait); /* activate unit */
i8251_devnum++;
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 devnum)
{
if (devnum >= I8251_NUM) {
sim_printf("8251s: Illegal Device Number %d\n", devnum);
return 0;
}
// sim_printf("\nio=%d data=%04X\n", io, data);
if (io == 0) { /* read status port */
return i8251_unit.u3;
} else { /* write status port */
if (i8251_unit.u6) { /* if mode, set cmd */
i8251_unit.u5 = data;
sim_printf(" 8251-%d: Command Instruction=%02X\n", devnum, data);
if (data & SD) /* reset port! */
i8251_reset1(devnum);
} else { /* set mode */
i8251_unit.u4 = data;
sim_printf(" 8251-%d: Mode Instruction=%02X\n", devnum, data);
i8251_unit.u6 = 1; /* set cmd received */
}
return (0);
}
}
uint8 i8251d(t_bool io, uint8 data, uint8 devnum)
{
if (devnum >= I8251_NUM) {
sim_printf("8251d: Illegal Device Number %d\n", devnum);
return 0;
}
if (io == 0) { /* read data port */
i8251_unit.u3 &= ~RXR;
return (i8251_unit.buf);
} else { /* write data port */
sim_putchar(data);
}
return 0;
}
void i8251_reset1(uint8 devnum)
{
i8251_unit.u3 = TXR + TXE; /* status */
@@ -278,7 +248,61 @@ void i8251_reset1(uint8 devnum)
i8251_unit.u6 = 0;
i8251_unit.buf = 0;
i8251_unit.pos = 0;
sim_printf(" 8251-%d: Reset\n", devnum);
sim_printf(" 8251-%d: Software Reset\n", devnum);
}
uint8 i8251_get_dn(void)
{
int i;
for (i=0; i<I8251_NUM; i++)
if (port >= i8251_port[i] && port <= i8251_port[i] + 1)
return i;
sim_printf("i8251_get_dn: port %04X not in 8251 device table\n", port);
return 0xFF;
}
/* 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 devnum;
if ((devnum = i8251_get_dn()) != 0xFF) {
// sim_printf("\nio=%d data=%04X\n", io, data);
if (io == 0) { /* read status port */
return i8251_unit.u3;
} else { /* write status port */
if (i8251_unit.u6) { /* if mode, set cmd */
i8251_unit.u5 = data;
sim_printf(" 8251-%d: Command Instruction=%02X\n", devnum, data);
if (data & SD) /* reset port! */
i8251_reset1(devnum);
} else { /* set mode */
i8251_unit.u4 = data;
sim_printf(" 8251-%d: Mode Instruction=%02X\n", devnum, data);
i8251_unit.u6 = 1; /* set cmd received */
}
}
}
return 0;
}
uint8 i8251d(t_bool io, uint8 data)
{
uint8 devnum;
if ((devnum = i8251_get_dn()) != 0xFF) {
if (io == 0) { /* read data port */
i8251_unit.u3 &= ~RXR;
return (i8251_unit.buf);
} else { /* write data port */
sim_putchar(data);
}
}
return 0;
}
/* end of i8251.c */