1
0
mirror of https://github.com/simh/simh.git synced 2026-04-12 15:07:31 +00:00

Intel-Systems: Merge MDS, SDK, OEM simulators into Intel-MDS simulator

14 separate simulators now internal to a general purpose simulator
This commit is contained in:
Bill Beech
2021-04-11 14:37:34 -07:00
parent b90b1eaf6f
commit 96c32fcb80
93 changed files with 2398 additions and 10619 deletions

View File

@@ -0,0 +1,84 @@
/* cpu.c: Intel MDS-800 CPU Module simulator
Copyright (c) 2010, William A. Beech
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 NONINFRINGEMENT. IN NO EVENT SHALL
WILLIAM A. BEECH 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 name of William A. Beech shall not be
used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from William A. Beech.
This software was written by Bill Beech, Dec 2010, to allow emulation of Multibus
Computer Systems.
5 October 2017 - Original file.
*/
#include "system_defs.h"
/* function prototypes */
t_stat SBC_config(void);
t_stat SBC_reset (DEVICE *dptr);
// globals
int onetime = 0;
/* external function prototypes */
extern t_stat monitor_reset (DEVICE *dptr);
extern t_stat monitor_cfg(uint16 base, uint16 devnum, uint8 dummy);
extern t_stat fp_reset (DEVICE *dptr);
extern t_stat fp_cfg(uint16 base, uint16 devnum, uint8 dummy);
extern t_stat i8080_reset (DEVICE *dptr); /* reset the 8080 emulator */
extern uint8 EPROM_get_mbyte(uint16 addr, uint8 devnum);
extern uint8 multibus_get_mbyte(uint16 addr);
extern void multibus_put_mbyte(uint16 addr, uint8 val);
extern uint8 reg_dev(uint8 (*routine)(t_bool, uint8, uint8), uint16, uint16, uint8);
extern uint8 unreg_dev(uint16);
extern t_stat i3214_cfg(uint16 base, uint16 devnum, uint8 dummy);
// external globals
extern uint8 monitor_boot;
extern DEVICE i8080_dev;
extern uint8 i3214_mask;
extern uint8 EPROM_enable;
extern uint8 i3214_cnt;
extern uint8 i3214_ram[16];
extern uint8 BUS_OVERRIDE;
t_stat SBC_config(void)
{
sim_printf("SBC_config: Configuring MDS-800 CPU Card\n Onboard Devices:\n");
return SCPE_OK;
}
/* SBC reset routine
put here to cause a reset of the entire MDS-800 system */
t_stat SBC_reset (DEVICE *dptr)
{
sim_printf("SBC_reset: \n");
EPROM_enable = 1;
BUS_OVERRIDE = 0;
return SCPE_OK;
}
/* end of cpu.c */

View File

@@ -0,0 +1,61 @@
/* front_panel.c: Intel MDS-800 Front Panel Module simulator
Copyright (c) 2010, William A. Beech
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 NONINFRINGEMENT. IN NO EVENT SHALL
WILLIAM A. BEECH 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 name of William A. Beech shall not be
used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from William A. Beech.
This software was written by Bill Beech, Dec 2010, to allow emulation of Multibus
Computer Systems.
5 October 2017 - Original file.
*/
#include "system_defs.h"
/* function prototypes */
t_stat fp_reset (DEVICE *dptr);
t_stat fp_cfg (uint16 base, uint16 size, uint8 devnum);
/* external function prototypes */
extern t_stat EPROM_reset(DEVICE *dptr);
extern t_stat EPROM_cfg(uint16 base, uint16 size, uint8 devnum);
/* external globals */
extern DEVICE EPROM_dev[];
t_stat fp_cfg(uint16 base, uint16 size, uint8 devnum)
{
return SCPE_OK;
}
/* CPU reset routine
put here to cause a reset of the entire IPC system */
t_stat fp_reset (DEVICE *dptr)
{
return SCPE_OK;
}
/* end of front_panel.c */

View File

@@ -39,16 +39,16 @@
*/
#include "system_defs.h"
#define IPC 0
#if defined (I3214_NUM) && (I3214_NUM > 0)
// 3214 status bits
#define i3214_NAME "Intel i3214 Perpherial Interrupt Contrlooer Chip"
/* external globals */
/* external function prototypes */
extern uint8 reg_dev(uint8 (*routine)(t_bool, uint8, uint8), uint8, uint8);
extern uint8 reg_dev(uint8 (*routine)(t_bool, uint8, uint8), uint16, uint16, uint8);
extern uint8 unreg_dev(uint16);
/* globals */
@@ -58,10 +58,18 @@ uint8 i3214_ram[16];
uint8 EPROM_enable = 1;
uint8 BUS_OVERRIDE = 0;
uint8 monitor_boot = 0x00;
static const char* i3214_desc(DEVICE *dptr) {
return i3214_NAME;
}
int i3214_baseport = -1; //base port
uint8 i3214_intnum = 0; //interrupt number
uint8 i3214_verb = 0; //verbose flag
/* function prototypes */
t_stat i3214_cfg(uint8 base, uint8 devnum);
t_stat i3214_cfg(uint16 base, uint16 devnum, uint8 dummy);
t_stat i3214_clr(void);
t_stat i3214_show_param (FILE *st, UNIT *uptr, int32 val, CONST void *desc);
t_stat i3214_reset (DEVICE *dptr);
t_stat i3214_reset_dev (uint8 devnum);
t_stat i3214_svc (UNIT *uptr);
@@ -96,6 +104,8 @@ DEBTAB i3214_debug[] = {
};
MTAB i3214_mod[] = {
{ MTAB_XTD | MTAB_VDV, 0, "PARAM", NULL, NULL, i3214_show_param, NULL,
"show configured parametes for i3214" },
{ 0 }
};
@@ -119,23 +129,52 @@ DEVICE i3214_dev = {
NULL, //attach
NULL, //detach
NULL, //ctxt
0, //flags
DEV_DEBUG+DEV_DISABLE+DEV_DIS, //flags
0, //dctrl
i3214_debug, //debflags
NULL, //msize
NULL //lname
NULL, //lname
NULL, //help routine
NULL, //attach help routine
NULL, //help context
&i3214_desc //device description
};
// i3214 configuration
t_stat i3214_cfg(uint8 base, uint8 devnum)
t_stat i3214_cfg(uint16 base, uint16 devnum, uint8 dummy)
{
sim_printf(" i3214[%d]: at base port 0%02XH\n",
devnum, base & 0xFF);
reg_dev(i3214_do_mask, base, devnum);
reg_dev(i3214_do_status, base + 1, devnum);
reg_dev(i3214_cpu_bus_override, base + 2, devnum);
reg_dev(i3214_monitor_do_boot, base + 3, devnum);
i3214_baseport = base & 0xff;
sim_printf(" i3214: at base port 0%02XH\n",
i3214_baseport);
reg_dev(i3214_do_mask, i3214_baseport, 0, 0);
reg_dev(i3214_do_status, i3214_baseport + 1, 0, 0);
reg_dev(i3214_cpu_bus_override, i3214_baseport + 2, 0, 0);
reg_dev(i3214_monitor_do_boot, i3214_baseport + 3, 0, 0);
return SCPE_OK;
}
t_stat i3214_clr(void)
{
unreg_dev(i3214_baseport);
unreg_dev(i3214_baseport + 1);
unreg_dev(i3214_baseport + 2);
unreg_dev(i3214_baseport + 3);
i3214_baseport = -1;
i3214_intnum = 0;
i3214_verb = 0;
return SCPE_OK;
}
// show configuration parameters
t_stat i3214_show_param (FILE *st, UNIT *uptr, int32 val, CONST void *desc)
{
if (uptr == NULL)
return SCPE_ARG;
fprintf(st, "%s, Base port 0%04XH, Interrupt # %d, %s",
((i3214_dev.flags & DEV_DIS) == 0) ? "Enabled" : "Disabled",
i3214_baseport, i3214_intnum, i3214_verb ? "Verbose" : "Quiet");
return SCPE_OK;
}
@@ -154,7 +193,7 @@ t_stat i3214_reset (DEVICE *dptr)
{
uint8 devnum;
for (devnum=0; devnum<I3214_NUM; devnum++) {
for (devnum=0; devnum<1; devnum++) {
i3214_reset_dev(devnum);
sim_activate (&i3214_unit[devnum], i3214_unit[devnum].wait); /* activate unit */
}
@@ -209,6 +248,4 @@ uint8 i3214_monitor_do_boot(t_bool io, uint8 data, uint8 devnum)
return 0;
}
#endif /* I3214_NUM > 0 */
/* end of i3214.c */

View File

@@ -157,6 +157,8 @@
#define BYTE_R 0xFF
#define WORD_R 0xFFFF
#define i8080_NAME "Intel i8080/85 Processor Chip"
/* storage for the rest of the registers */
uint32 PSW = 0; /* program status word */
uint32 A = 0; /* accumulator */
@@ -178,6 +180,10 @@ uint16 addr; //addr used for operand fetch
uint32 IR;
uint16 devnum = 0;
static const char* i8080_desc(DEVICE *dptr) {
return i8080_NAME;
}
/* function prototypes */
void set_cpuint(int32 int_num);
@@ -212,9 +218,10 @@ extern int32 sim_int_char;
extern uint32 sim_brk_types, sim_brk_dflt, sim_brk_summ; /* breakpoint info */
struct idev {
uint8 (*routine)(t_bool, uint8, uint8);
uint8 port;
uint8 devnum;
uint8 (*routine)(t_bool io, uint8 data, uint8 devnum);
uint16 port;
uint16 devnum;
uint8 dummy;
};
/* This is the I/O configuration table. There are 256 possible
@@ -298,7 +305,7 @@ DEVICE i8080_dev = {
NULL, //help routine
NULL, //attach help routine
NULL, //help context
NULL //device description
&i8080_desc //device description
};
/* tables for the disassembler */
@@ -398,14 +405,14 @@ void set_cpuint(int32 int_num)
int32 sim_instr(void)
{
extern int32 sim_interval;
uint32 OP, DAR, reason, adr, onetime = 0;
uint32 OP, DAR, reason, adr, i8080_onetime = 0;
PC = saved_PC & WORD_R; /* load local PC */
reason = 0;
uptr = i8080_dev.units;
if (onetime++ == 0) {
if (i8080_onetime++ == 0) {
if (uptr->flags & UNIT_8085)
sim_printf(" CPU = 8085\n");
else
@@ -478,10 +485,12 @@ int32 sim_instr(void)
IR = OP = fetch_byte(0); /* instruction fetch */
if (GET_XACK(1) == 0) { // no XACK for instruction fetch
// reason = STOP_XACK;
// sim_printf("Failed XACK for Instruction Fetch from %04X\n", PCX);
// continue;
if (uptr->flags & UNIT_XACK) {
if (GET_XACK(1) == 0) { // no XACK for instruction fetch
reason = STOP_XACK;
sim_printf("\nFailed XACK for Instruction Fetch from %04X", PCX);
continue;
}
}
// first instruction decode
@@ -886,15 +895,15 @@ int32 sim_instr(void)
break;
case 0xDB: /* IN */
SET_XACK(1); /* good I/O address */
port = fetch_byte(1);
A = dev_table[port].routine(0, 0, dev_table[port].devnum);
SET_XACK(1); /* good I/O address */
A = dev_table[port].routine(0, 0, dev_table[port].devnum & 0xff);
break;
case 0xD3: /* OUT */
SET_XACK(1); /* good I/O address */
port = fetch_byte(1);
dev_table[port].routine(1, A, dev_table[port].devnum);
SET_XACK(1); /* good I/O address */
dev_table[port].routine(1, A, dev_table[port].devnum & 0xff);
break;
default: /* undefined opcode */
@@ -906,14 +915,16 @@ int32 sim_instr(void)
}
loop_end:
if (GET_XACK(1) == 0) { // no XACK for operand fetch
// reason = STOP_XACK;
// if (OP == 0xD3 || OP == 0xDB) {
// sim_printf("Failed XACK for Port %02X Fetch from %04X\n", port, PCX);
// } else {
// sim_printf("Failed XACK for Operand %04X Fetch from %04X\n", addr, PCX);
// continue;
// }
if (uptr->flags & UNIT_XACK) {
if (GET_XACK(1) == 0) { // no XACK for operand fetch
// reason = STOP_XACK;
if (OP == 0xD3 || OP == 0xDB) {
sim_printf("\nFailed XACK for Port %02X Fetch from %04X", port, PCX);
} else {
sim_printf("\nFailed XACK for Operand %04X Fetch from %04X", addr, PCX);
continue;
}
}
}
}

View File

@@ -235,8 +235,6 @@
#include "system_defs.h"
#if defined (I8237_NUM) && (I8237_NUM > 0)
/* external globals */
/* internal function prototypes */
@@ -843,6 +841,4 @@ uint8 i8237_rFx(t_bool io, uint8 data, uint8 devnum)
return 0;
}
#endif /* I8237_NUM > 0 */
/* end of i8237.c */

View File

@@ -26,7 +26,7 @@
MODIFICATIONS:
?? ??? 10 - Original file.
16 Dec 12 - Modified to use isbc_80_10.cfg file to set baseport and size.
16 Dec 12 - Modified to use isbc_80_10.cfg file to set i8251_baseport and size.
24 Apr 15 -- Modified to use simh_debug
NOTES:
@@ -111,8 +111,6 @@
#include "system_defs.h"
#if defined (I8251_NUM) && (I8251_NUM > 0)
#define UNIT_V_ANSI (UNIT_V_UF + 0) /* ANSI mode */
#define UNIT_ANSI (1 << UNIT_V_ANSI)
@@ -123,17 +121,30 @@
#define TXE 0x04
#define SD 0x40
#define i8251_NAME "Intel i8251 UART Chip"
/* external globals */
/* external function prototypes */
extern uint8 reg_dev(uint8 (*routine)(t_bool, uint8, uint8), uint8, uint8);
extern uint8 reg_dev(uint8 (*routine)(t_bool, uint8, uint8), uint16, uint16, uint8);
extern uint8 unreg_dev(uint16);
/* globals */
static const char* i8251_desc(DEVICE *dptr) {
return i8251_NAME;
}
int i8251_num = 0;
int i8251_baseport[4] = { -1, -1, -1, -1 }; //base port
uint8 i8251_intnum[4] = { 0, 0, 0, 0 }; //interrupt number
uint8 i8251_verb[4] = { 0, 0, 0, 0 }; //verbose flag
/* function prototypes */
t_stat i8251_cfg(uint8 base, uint8 devnum);
t_stat i8251_cfg(uint16 base, uint16 devnum, uint8 dummy);
t_stat i8251_clr(void);
t_stat i8251_show_param (FILE *st, UNIT *uptr, int32 val, CONST void *desc);
t_stat i8251_svc (UNIT *uptr);
t_stat i8251_reset (DEVICE *dptr);
uint8 i8251s(t_bool io, uint8 data, uint8 devnum);
@@ -184,6 +195,8 @@ DEBTAB i8251_debug[] = {
MTAB i8251_mod[] = {
{ UNIT_ANSI, 0, "ANSI", "ANSI", NULL },
{ UNIT_ANSI, UNIT_ANSI, "TTY", "TTY", NULL },
{ MTAB_XTD | MTAB_VDV, 0, "PARAM", NULL, NULL, i8251_show_param, NULL,
"show configured parametes for i8251" },
{ 0 }
};
@@ -207,7 +220,7 @@ DEVICE i8251_dev = {
NULL, //attach
NULL, //detach
NULL, //ctxt
DEV_DISABLE, //flags
DEV_DEBUG+DEV_DISABLE+DEV_DIS, //flags
0, //dctrl
i8251_debug, //debflags
NULL, //memeory size change
@@ -215,21 +228,59 @@ DEVICE i8251_dev = {
NULL, //help routine
NULL, //attach help routine
NULL, //help context
NULL //device description
&i8251_desc //device description
};
// i8251 configuration
t_stat i8251_cfg(uint8 base, uint8 devnum)
t_stat i8251_cfg(uint16 base, uint16 devnum, uint8 dummy)
{
sim_printf(" i8251[%d]: at base port 0%02XH\n",
devnum, base & 0xFF);
reg_dev(i8251d, base, devnum);
reg_dev(i8251s, base + 1, devnum);
i8251_baseport[devnum] = base & 0xff;
sim_printf(" i8251%d: installed at base port 0%02XH\n",
devnum, i8251_baseport[devnum]);
reg_dev(i8251d, i8251_baseport[devnum], devnum, 0);
reg_dev(i8251s, i8251_baseport[devnum] + 1, devnum, 0);
i8251_num++; //next device
return SCPE_OK;
}
/* Service routines to handle simulator functions */
t_stat i8251_clr(void)
{
int i;
for (i=0; i<i8251_num; i++) {
unreg_dev(i8251_baseport[i]);
unreg_dev(i8251_baseport[i] + 1);
i8251_baseport[i] = -1;
i8251_intnum[i] = 0;
i8251_verb[i] = 0;
}
i8251_num = 0;
return SCPE_OK;
}
// show configuration parameters
t_stat i8251_show_param (FILE *st, UNIT *uptr, int32 val, CONST void *desc)
{
int i;
if (uptr == NULL)
return SCPE_ARG;
fprintf(st, "Device %s\n", ((i8251_dev.flags & DEV_DIS) == 0) ? "Enabled" : "Disabled");
for (i=0; i<i8251_num; i++) {
fprintf(st, "Unit %d at Base port ", i);
fprintf(st, "0%02XH, ", i8251_baseport[i]);
fprintf(st, "Interrupt # is ");
fprintf(st, "%d, ", i8251_intnum[i]);
fprintf(st, "Mode ");
fprintf(st, "%s", i8251_verb[i] ? "Verbose" : "Quiet");
if (i<i8251_num && i8251_num != 1) fprintf(st, "\n");
}
return SCPE_OK;
}
/* Service routines to handled simulator functions */
/* i8251_svc - actually gets char & places in buffer */
@@ -255,7 +306,8 @@ t_stat i8251_reset (DEVICE *dptr)
for (devnum=0; devnum<I8251_NUM; devnum++) {
i8251_reset_dev(devnum);
sim_activate (&i8251_unit[devnum], i8251_unit[devnum].wait); /* activate unit */
if (devnum == 0)
sim_activate (&i8251_unit[devnum], i8251_unit[devnum].wait); /* activate unit */
}
return SCPE_OK;
}
@@ -276,7 +328,7 @@ void i8251_reset_dev(uint8 devnum)
uint8 i8251s(t_bool io, uint8 data, uint8 devnum)
{
if (io == 0) { /* read status port */
if (io == 0) { /* read status port */
return i8251_unit[devnum].u3;
} else { /* write status port */
if (i8251_unit[devnum].u4) { /* if mode, set cmd */
@@ -302,6 +354,4 @@ uint8 i8251d(t_bool io, uint8 data, uint8 devnum)
return 0;
}
#endif /* I8251_NUM > 0 */
/* end of i8251.c */

View File

@@ -35,19 +35,29 @@
#include "system_defs.h"
#if defined (I8253_NUM) && (I8253_NUM > 0)
#define i8253_NAME "Intel i8253 PIT Chip"
/* external globals */
/* external function prototypes */
extern uint8 reg_dev(uint8 (*routine)(t_bool, uint8, uint8), uint8, uint8);
extern uint8 reg_dev(uint8 (*routine)(t_bool, uint8, uint8), uint16, uint16, uint8);
extern uint8 unreg_dev(uint16);
/* globals */
static const char* i8253_desc(DEVICE *dptr) {
return i8253_NAME;
}
int i8253_num = 0;
int i8253_baseport[] = { -1, -1, -1, -1 }; //base port
uint8 i8253_intnum[4] = { 0, 0, 0, 0 }; //interrupt number
uint8 i8253_verb[4] = { 0, 0, 0, 0 }; //verbose flag
/* function prototypes */
t_stat i8253_cfg(uint8 base, uint8 devnum);
t_stat i8253_cfg(uint16 base, uint16 devnum, uint8 dummy);
t_stat i8253_clr(void);
t_stat i8253_show_param (FILE *st, UNIT *uptr, int32 val, CONST void *desc);
t_stat i8253_svc (UNIT *uptr);
t_stat i8253_reset (DEVICE *dptr);
uint8 i8253t0(t_bool io, uint8 data, uint8 devnum);
@@ -88,6 +98,8 @@ DEBTAB i8253_debug[] = {
};
MTAB i8253_mod[] = {
{ MTAB_XTD | MTAB_VDV, 0, "PARAM", NULL, NULL, i8253_show_param, NULL,
"show configured parametes for i8253" },
{ 0 }
};
@@ -98,7 +110,7 @@ DEVICE i8253_dev = {
i8253_unit, //units
i8253_reg, //registers
i8253_mod, //modifiers
I8253_NUM, //numunits
I8253_NUM, //numunits
16, //aradix
16, //awidth
1, //aincr
@@ -111,25 +123,69 @@ DEVICE i8253_dev = {
NULL, //attach
NULL, //detach
NULL, //ctxt
0, //flags
DEV_DEBUG+DEV_DISABLE+DEV_DIS, //flags
0, //dctrl
i8253_debug, //debflags
NULL, //msize
NULL //lname
NULL, //lname
NULL, //help routine
NULL, //attach help routine
NULL, //help context
&i8253_desc //device description
};
/* Service routines to handle simulator functions */
// i8253 configuration
t_stat i8253_cfg(uint8 base, uint8 devnum)
t_stat i8253_cfg(uint16 base, uint16 devnum, uint8 dummy)
{
sim_printf(" i8253[%d]: at base port 0%02XH\n",
devnum, base & 0xFF);
reg_dev(i8253t0, base, devnum);
reg_dev(i8253t1, base + 1, devnum);
reg_dev(i8253t2, base + 2, devnum);
reg_dev(i8253c, base + 3, devnum);
i8253_baseport[devnum] = base & 0xff;
sim_printf(" i8253%d: installed at base port 0%02XH\n",
devnum, i8253_baseport[devnum]);
reg_dev(i8253t0, i8253_baseport[devnum], devnum, 0);
reg_dev(i8253t1, i8253_baseport[devnum] + 1, devnum, 0);
reg_dev(i8253t2, i8253_baseport[devnum] + 2, devnum, 0);
reg_dev(i8253c, i8253_baseport[devnum] + 3, devnum, 0);
i8253_num++;
return SCPE_OK;
}
t_stat i8253_clr(void)
{
int i;
for (i=0; i<i8253_num; i++) {
unreg_dev(i8253_baseport[i]);
unreg_dev(i8253_baseport[i] + 1);
unreg_dev(i8253_baseport[i] + 2);
unreg_dev(i8253_baseport[i] + 3);
i8253_baseport[i] = -1;
i8253_intnum[i] = 0;
i8253_verb[i] = 0;
}
i8253_num = 0;
return SCPE_OK;
}
// show configuration parameters
t_stat i8253_show_param (FILE *st, UNIT *uptr, int32 val, CONST void *desc)
{
int i;
if (uptr == NULL)
return SCPE_ARG;
fprintf(st, "Device %s\n", ((i8253_dev.flags & DEV_DIS) == 0) ? "Enabled" : "Disabled");
for (i=0; i<i8253_num; i++) {
fprintf(st, "Unit %d at Base port ", i);
fprintf(st, "0%02X ", i8253_baseport[i]);
fprintf(st, "Interrupt # is ");
fprintf(st, "%d ", i8253_intnum[i]);
fprintf(st, "Mode ");
fprintf(st, "%s", i8253_verb[i] ? "Verbose" : "Quiet");
if (i<i8253_num && i8253_num != 1) fprintf(st, "\n");
}
return SCPE_OK;
}
@@ -147,7 +203,7 @@ t_stat i8253_reset (DEVICE *dptr)
{
uint8 devnum;
for (devnum=0; devnum<I8253_NUM; devnum++) {
for (devnum=0; devnum<i8253_num+1; devnum++) {
i8253_unit[devnum].u3 = 0; /* status */
i8253_unit[devnum].u4 = 0; /* mode instruction */
i8253_unit[devnum].u5 = 0; /* command instruction */
@@ -208,6 +264,4 @@ uint8 i8253c(t_bool io, uint8 data, uint8 devnum)
return 0;
}
#endif /* I8253_NUM > 0 */
/* end of i8253.c */

View File

@@ -26,7 +26,7 @@
MODIFICATIONS:
?? ??? 10 - Original file.
16 Dec 12 - Modified to use isbc_80_10.cfg file to set baseport and size.
16 Dec 12 - Modified to use isbc_80_10.cfg file to set i8255_baseport and size.
24 Apr 15 -- Modified to use simh_debug
NOTES:
@@ -77,12 +77,15 @@
#include "system_defs.h" /* system header in system dir */
#if defined (I8255_NUM) && (I8255_NUM > 0)
#define i8255_NAME "Intel i8255 PIA Chip"
/* internal function prototypes */
t_stat i8255_cfg(uint8 base, uint8 devnum);
t_stat i8255_cfg(uint16 base, uint16 devnum, uint8 dummy);
t_stat i8255_clr(void);
t_stat i8255_show_param (FILE *st, UNIT *uptr, int32 val, CONST void *desc);
t_stat i8255_reset (DEVICE *dptr);
t_stat i8255_reset_dev ();
uint8 i8255a(t_bool io, uint8 data, uint8 devnum);
uint8 i8255b(t_bool io, uint8 data, uint8 devnum);
uint8 i8255c(t_bool io, uint8 data, uint8 devnum);
@@ -90,15 +93,24 @@ uint8 i8255s(t_bool io, uint8 data, uint8 devnum);
/* external function prototypes */
extern uint8 reg_dev(uint8 (*routine)(t_bool, uint8, uint8), uint8, uint8);
extern uint8 reg_dev(uint8 (*routine)(t_bool, uint8, uint8), uint16, uint16, uint8);
extern uint8 unreg_dev(uint16);
/* globals */
static const char* i8255_desc(DEVICE *dptr) {
return i8255_NAME;
}
int i8255_num = 0;
int i8255_baseport[] = { -1, -1, -1, -1 }; //base port
uint8 i8255_intnum[4] = { 0, 0, 0, 0 }; //interrupt number
uint8 i8255_verb[4] = { 0, 0, 0, 0 }; //verbose flag
/* these bytes represent the input and output to/from a port instance */
uint8 i8255_A[I8255_NUM]; //port A byte I/O
uint8 i8255_B[I8255_NUM]; //port B byte I/O
uint8 i8255_C[I8255_NUM]; //port C byte I/O
uint8 i8255_A[4]; //port A byte I/O
uint8 i8255_B[4]; //port B byte I/O
uint8 i8255_C[4]; //port C byte I/O
/* external globals */
@@ -132,6 +144,18 @@ REG i8255_reg[] = {
{ NULL }
};
MTAB i8255_mod[] = {
// { MTAB_XTD | MTAB_VDV, 0, NULL, "VERB", &isbc202_set_verb,
// NULL, NULL, "Sets the verbose mode for i8255"},
// { MTAB_XTD | MTAB_VDV, 0, NULL, "PORT", &isbc202_set_port,
// NULL, NULL, "Sets the base port for i8255"},
// { MTAB_XTD | MTAB_VDV, 0, NULL, "INT", &isbc202_set_int,
// NULL, NULL, "Sets the interrupt number for i8255"},
{ MTAB_XTD | MTAB_VDV, 0, "PARAM", NULL, NULL, i8255_show_param, NULL,
"show configured parametes for i8255" },
{ 0 }
};
DEBTAB i8255_debug[] = {
{ "ALL", DEBUG_all },
{ "FLOW", DEBUG_flow },
@@ -148,7 +172,7 @@ DEVICE i8255_dev = {
"I8255", //name
i8255_unit, //units
i8255_reg, //registers
NULL, //modifiers
i8255_mod, //modifiers
I8255_NUM, //numunits
16, //aradix
16, //awidth
@@ -162,33 +186,88 @@ DEVICE i8255_dev = {
NULL, //attach
NULL, //detach
NULL, //ctxt
0, //flags
DEV_DEBUG+DEV_DISABLE+DEV_DIS, //flags
0, //dctrl
i8255_debug, //debflags
NULL, //msize
NULL //lname
NULL, //lname
NULL, //help routine
NULL, //attach help routine
NULL, //help context
&i8255_desc //device description
};
// i8255 configuration
t_stat i8255_cfg(uint8 base, uint8 devnum)
t_stat i8255_cfg(uint16 base, uint16 devnum, uint8 dummy)
{
sim_printf(" i8255[%d]: at base port 0%02XH\n",
devnum, base & 0xFF);
reg_dev(i8255a, base, devnum);
reg_dev(i8255b, base + 1, devnum);
reg_dev(i8255c, base + 2, devnum);
reg_dev(i8255s, base + 3, devnum);
DEVICE *dptr;
dptr = find_dev (i8255_dev.name);
i8255_baseport[devnum] = base & 0xff;
sim_printf(" i8255%d: installed at base port 0%02XH\n",
devnum, i8255_baseport[devnum]);
reg_dev(i8255a, i8255_baseport[devnum], devnum, 0);
reg_dev(i8255b, i8255_baseport[devnum] + 1, devnum, 0);
reg_dev(i8255c, i8255_baseport[devnum] + 2, devnum, 0);
reg_dev(i8255s, i8255_baseport[devnum] + 3, devnum, 0);
i8255_num++;
return SCPE_OK;
}
t_stat i8255_clr(void)
{
int i;
for (i=0; i<i8255_num; i++) {
unreg_dev(i8255_baseport[i]);
unreg_dev(i8255_baseport[i] + 1);
unreg_dev(i8255_baseport[i] + 2);
unreg_dev(i8255_baseport[i] + 3);
i8255_baseport[i] = -1;
i8255_intnum[i] = 0;
i8255_verb[i] = 0;
}
i8255_num = 0;
return SCPE_OK;
}
// show configuration parameters
t_stat i8255_show_param (FILE *st, UNIT *uptr, int32 val, CONST void *desc)
{
int i;
if (uptr == NULL)
return SCPE_ARG;
fprintf(st, "Device %s\n", ((i8255_dev.flags & DEV_DIS) == 0) ? "Enabled" : "Disabled");
for (i=0; i<i8255_num; i++) {
fprintf(st, "Unit %d at Base port ", i);
fprintf(st, "0%02X ", i8255_baseport[i]);
fprintf(st, "Interrupt # is ");
fprintf(st, "%d ", i8255_intnum[i]);
fprintf(st, "Mode ");
fprintf(st, "%s", i8255_verb[i] ? "Verbose" : "Quiet");
if (i<i8255_num && i8255_num != 1) fprintf(st, "\n");
}
return SCPE_OK;
}
/* Reset routine */
t_stat i8255_reset (DEVICE *dptr)
{
// if ((dptr->flags & DEV_DIS) == 0) { // enabled
i8255_reset_dev(); //software reset
// }
return SCPE_OK;
}
t_stat i8255_reset_dev ()
{
uint8 devnum;
for (devnum = 0; devnum < I8255_NUM; devnum++) {
for (devnum = 0; devnum < i8255_num+1; devnum++) {
i8255_unit[devnum].u3 = 0x9B; /* control */
i8255_A[devnum] = 0xFF; /* Port A */
i8255_B[devnum] = 0xFF; /* Port B */
@@ -270,6 +349,4 @@ uint8 i8255c(t_bool io, uint8 data, uint8 devnum)
return 0;
}
#endif /* I8255_NUM > 0 */
/* end of i8255.c */

View File

@@ -35,11 +35,13 @@
#include "system_defs.h" /* system header in system dir */
#if defined (I8259_NUM) && (I8259_NUM > 0)
#define i8259_NAME "Intel i8259 PIC Chip"
/* function prototypes */
t_stat i8259_cfg(uint8 base, uint8 devnum);
t_stat i8259_cfg(uint16 base, uint16 devnum, uint8 dummy);
t_stat i8259_clr(void);
t_stat i8259_show_param (FILE *st, UNIT *uptr, int32 val, CONST void *desc);
uint8 i8259a(t_bool io, uint8 data, uint8 devnum);
uint8 i8259b(t_bool io, uint8 data, uint8 devnum);
void i8259_dump(uint8 devnum);
@@ -47,27 +49,37 @@ t_stat i8259_reset (DEVICE *dptr);
/* external globals */
static const char* i8259_desc(DEVICE *dptr) {
return i8259_NAME;
}
int i8259_num = 0;
uint8 icw_num0 = 1, icw_num1 = 1;
/* external function prototypes */
extern uint8 reg_dev(uint8 (*routine)(t_bool, uint8, uint8), uint8, uint8);
extern uint8 reg_dev(uint8 (*routine)(t_bool, uint8, uint8), uint16, uint16, uint8);
extern uint8 unreg_dev(uint16);
/* globals */
/* these bytes represent the input and output to/from a port instance */
/* these bytes represent the input and output to/from a device instance */
uint8 i8259_IR[4]; //interrupt inputs (bits 0-7)
uint8 i8259_CAS[4]; //interrupt cascade I/O (bits 0-2)
uint8 i8259_INT[4]; //interrupt output (bit 0)
uint8 i8259_base[I8259_NUM];
uint8 i8259_icw1[I8259_NUM];
uint8 i8259_icw2[I8259_NUM];
uint8 i8259_icw3[I8259_NUM];
uint8 i8259_icw4[I8259_NUM];
uint8 i8259_ocw1[I8259_NUM];
uint8 i8259_ocw2[I8259_NUM];
uint8 i8259_ocw3[I8259_NUM];
uint8 icw_num0 = 1, icw_num1 = 1;
uint8 i8259_base[4];
uint8 i8259_icw1[4];
uint8 i8259_icw2[4];
uint8 i8259_icw3[4];
uint8 i8259_icw4[4];
uint8 i8259_ocw1[4];
uint8 i8259_ocw2[4];
uint8 i8259_ocw3[4];
int i8259_baseport[] = { -1, -1, -1, -1 }; //base port
uint8 i8259_intnum[4] = { 0, 0, 0, 0 }; //interrupt number
uint8 i8259_verb[4] = { 0, 0, 0, 0 }; //verbose flag
/* i8259 Standard I/O Data Structures */
/* up to 4 i8259 devices */
@@ -105,13 +117,19 @@ DEBTAB i8259_debug[] = {
{ NULL }
};
MTAB i8259_mod[] = {
{ MTAB_XTD | MTAB_VDV, 0, "PARAM", NULL, NULL, i8259_show_param, NULL,
"show configured parametes for i8259" },
{ 0 }
};
/* address width is set to 16 bits to use devices in 8086/8088 implementations */
DEVICE i8259_dev = {
"I8259", //name
i8259_unit, //units
i8259_reg, //registers
NULL, //modifiers
i8259_mod, //modifiers
I8259_NUM, //numunits
16, //aradix
16, //awidth
@@ -125,11 +143,15 @@ DEVICE i8259_dev = {
NULL, //attach
NULL, //detach
NULL, //ctxt
0, //flags
DEV_DEBUG+DEV_DISABLE+DEV_DIS, //flags
0, //dctrl
i8259_debug, //debflags
NULL, //msize
NULL //lname
NULL, //lname
NULL, //help routine
NULL, //attach help routine
NULL, //help context
&i8259_desc //device description
};
/* I/O instruction handlers, called from the CPU module when an
@@ -138,12 +160,50 @@ DEVICE i8259_dev = {
// i8259 configuration
t_stat i8259_cfg(uint8 base, uint8 devnum)
t_stat i8259_cfg(uint16 base, uint16 devnum, uint8 dummy)
{
sim_printf(" i8259[%d]: at base port 0%02XH\n",
devnum, base & 0xFF);
reg_dev(i8259a, base, devnum);
reg_dev(i8259b, base + 1, devnum);
i8259_baseport[devnum] = base & 0xff;
sim_printf(" i8259%d: installed at base port 0%02XH\n",
devnum, i8259_baseport[devnum]);
reg_dev(i8259a, i8259_baseport[devnum], devnum, 0);
reg_dev(i8259b, i8259_baseport[devnum] + 1, devnum, 0);
i8259_num++;
return SCPE_OK;
}
t_stat i8259_clr(void)
{
int i;
for (i=0; i<i8259_num; i++) {
unreg_dev(i8259_baseport[i]);
unreg_dev(i8259_baseport[i] + 1);
i8259_baseport[i] = -1;
i8259_intnum[i] = 0;
i8259_verb[i] = 0;
}
i8259_num = 0;
return SCPE_OK;
}
// show configuration parameters
t_stat i8259_show_param (FILE *st, UNIT *uptr, int32 val, CONST void *desc)
{
int i;
if (uptr == NULL)
return SCPE_ARG;
fprintf(st, "Device %s\n", ((i8259_dev.flags & DEV_DIS) == 0) ? "Enabled" : "Disabled");
for (i=0; i<i8259_num; i++) {
fprintf(st, "Unit %d at Base port ", i);
fprintf(st, "0%02X ", i8259_baseport[i]);
fprintf(st, "Interrupt # is ");
fprintf(st, "%d ", i8259_intnum[i]);
fprintf(st, "Mode ");
fprintf(st, "%s", i8259_verb[i] ? "Verbose" : "Quiet");
if (i<i8259_num && i8259_num != 1) fprintf(st, "\n");
}
return SCPE_OK;
}
@@ -153,7 +213,7 @@ t_stat i8259_reset (DEVICE *dptr)
{
uint8 devnum;
for (devnum=0; devnum<I8259_NUM; devnum++) {
for (devnum=0; devnum<i8259_num+1; devnum++) {
i8259_unit[devnum].u3 = 0x00; /* IRR */
i8259_unit[devnum].u4 = 0x00; /* ISR */
i8259_unit[devnum].u5 = 0x00; /* IMR */
@@ -246,6 +306,4 @@ void i8259_dump(uint8 devnum)
sim_printf(" OCW3=%02X\n", i8259_ocw3[devnum]);
}
#endif /* I8259_NUM > 0 */
/* end of i8259.c */

View File

@@ -36,8 +36,6 @@
#include "system_defs.h"
#if defined (I8272_NUM) && (I8272_NUM > 0)
#define UNIT_V_WPMODE (UNIT_V_UF) /* Write protect */
#define UNIT_WPMODE (1 << UNIT_V_WPMODE)
@@ -702,23 +700,23 @@ t_stat i8272_attach (UNIT *uptr, CONST char *cptr)
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 */
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
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
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
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
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]);
@@ -893,6 +891,4 @@ uint8 i8272_r01(t_bool io, uint8 data)
return 0;
}
#endif /* I8272_NUM > 0 */
/* end of i8272.c */

View File

@@ -38,9 +38,13 @@
#include "system_defs.h"
#define EPROM_NAME "Intel EPROM Chip"
/* function prototypes */
t_stat EPROM_cfg (uint16 base, uint16 size, uint8 devnum);
t_stat EPROM_clr(void);
t_stat EPROM_show_param (FILE *st, UNIT *uptr, int32 val, CONST void *desc);
t_stat EPROM_attach (UNIT *uptr, CONST char *cptr);
t_stat EPROM_reset (DEVICE *dptr);
uint8 EPROM_get_mbyte (uint16 addr, uint8 devnum);
@@ -51,11 +55,26 @@ uint8 EPROM_get_mbyte (uint16 addr, uint8 devnum);
/* globals */
static const char* EPROM_desc(DEVICE *dptr) {
return EPROM_NAME;
}
int ieprom_num = 0;
/* SIMH EPROM Standard I/O Data Structures */
UNIT EPROM_unit[] = {
{UDATA (NULL, UNIT_ATTABLE+UNIT_BINK+UNIT_ROABLE+UNIT_RO+UNIT_BUFABLE+UNIT_MUSTBUF, 0), 0},
{UDATA (NULL, UNIT_ATTABLE+UNIT_BINK+UNIT_ROABLE+UNIT_RO+UNIT_BUFABLE+UNIT_MUSTBUF, 0), 0}
{UDATA (NULL, UNIT_ATTABLE+UNIT_BINK+UNIT_ROABLE+UNIT_RO+UNIT_BUFABLE+UNIT_MUSTBUF, 0) },
{UDATA (NULL, UNIT_ATTABLE+UNIT_BINK+UNIT_ROABLE+UNIT_RO+UNIT_BUFABLE+UNIT_MUSTBUF, 0) }
};
MTAB EPROM_mod[] = {
// { MTAB_XTD | MTAB_VDV, 0, NULL, "SIZE", &isbc464_set_size,
// NULL, NULL, "Sets the ROM size for EPROM" },
// { MTAB_XTD | MTAB_VDV, 0, NULL, "BASE", &isbc464_set_base,
// NULL, NULL, "Sets the ROM base for EPROM" },
{ MTAB_XTD|MTAB_VDV, 0, "PARAM", NULL, NULL, &EPROM_show_param, NULL,
"Parameters" },
{ 0 }
};
DEBTAB EPROM_debug[] = {
@@ -73,7 +92,7 @@ DEVICE EPROM_dev = {
"EPROM", //name
EPROM_unit, //units
NULL, //registers
NULL, //modifiers
EPROM_mod, //modifiers
EPROM_NUM, //numunits
16, //aradix
16, //awidth
@@ -82,16 +101,20 @@ DEVICE EPROM_dev = {
8, //dwidth
NULL, //examine
NULL, //deposit
&EPROM_reset, //reset
&EPROM_reset, //reset
NULL, //boot
&EPROM_attach, //attach
NULL, //detach
NULL, //ctxt
DEV_DEBUG, //flags
DEV_DEBUG+DEV_DISABLE+DEV_DIS, //flags
0, //dctrl
EPROM_debug, //debflags
NULL, //msize
NULL //lname
NULL, //lname
NULL, //help routine
NULL, //attach help routine
NULL, //help context
&EPROM_desc //device description
};
/* EPROM functions */
@@ -100,15 +123,29 @@ DEVICE EPROM_dev = {
t_stat EPROM_cfg(uint16 base, uint16 size, uint8 devnum)
{
EPROM_unit[devnum].capac = size; /* set EPROM size */
EPROM_unit[devnum].u3 = base & 0xFFFF; /* set EPROM base */
EPROM_unit[devnum].filebuf = (uint8 *)calloc(size, sizeof(uint8));
if (EPROM_unit[devnum].filebuf == NULL) {
sim_printf (" EPROM[%d]: Calloc error\n", devnum);
EPROM_unit[ieprom_num].capac = size; /* set EPROM size */
EPROM_unit[ieprom_num].u3 = base; /* set EPROM base */
EPROM_unit[ieprom_num].filebuf = (uint8 *)calloc(size, sizeof(uint8));
if (EPROM_unit[ieprom_num].filebuf == NULL) {
sim_printf (" EPROM%d: Calloc error\n", ieprom_num);
return SCPE_MEM;
}
sim_printf(" EPROM[%d]: 0%04XH bytes at base 0%04XH\n",
devnum, EPROM_unit[devnum].capac, EPROM_unit[devnum].u3);
sim_printf(" EPROM%d: 0%04XH bytes at base address 0%04XH\n",
ieprom_num, EPROM_unit[ieprom_num].capac, EPROM_unit[ieprom_num].u3);
ieprom_num++;
return SCPE_OK;
}
t_stat EPROM_clr(void)
{
int i;
for(i=0; i<ieprom_num; i++) {
EPROM_unit[i].capac = 0;
EPROM_unit[i].u3 = 0;
free(EPROM_unit[i].filebuf);
}
ieprom_num = 0;
return SCPE_OK;
}
@@ -116,10 +153,23 @@ t_stat EPROM_cfg(uint16 base, uint16 size, uint8 devnum)
t_stat EPROM_reset (DEVICE *dptr)
{
// uint8 devnum;
return SCPE_OK;
}
// show configuration parameters
t_stat EPROM_show_param (FILE *st, UNIT *uptr, int32 val, CONST void *desc)
{
int i;
// for (devnum = 0; devnum <= EPROM_NUM; devnum++) {
// }
if (uptr == NULL)
return SCPE_ARG;
fprintf(st, "Device %s\n", ((EPROM_dev.flags & DEV_DIS) == 0) ? "Enabled" : "Disabled");
for (i=0; i<ieprom_num; i++) {
fprintf(st, "Unit %d at Base Address 0%04XH (%dD) for 0%04XH (%dD) Bytes ",
i,
EPROM_unit[i].u3, EPROM_unit[i].u3, EPROM_unit[i].capac, EPROM_unit[i].capac);
}
return SCPE_OK;
}
@@ -129,6 +179,8 @@ t_stat EPROM_attach (UNIT *uptr, CONST char *cptr)
{
t_stat r;
if (uptr == NULL)
return SCPE_ARG;
if ((r = attach_unit (uptr, cptr)) != SCPE_OK) {
sim_printf ("EPROM_attach: Error %d\n", r);
return r;
@@ -143,7 +195,7 @@ uint8 EPROM_get_mbyte(uint16 addr, uint8 devnum)
uint8 val;
val = *((uint8 *)EPROM_unit[devnum].filebuf + (addr - EPROM_unit[devnum].u3));
return (val &= 0xFF);
return (val & 0xFF);
}
/* end of iEPROM.c */

View File

@@ -168,11 +168,11 @@ MTAB IO_mod[] = {
/* address width is set to 16 bits to use devices in 8086/8088 implementations */
DEVICE IO_dev = {
"IO", //name
IO_unit, //units
IO_reg, //registers
IO_mod, //modifiers
IO_NUM, //numunits
"IO", //name
IO_unit, //units
IO_reg, //registers
IO_mod, //modifiers
IO_NUM, //numunits
16, //aradix
16, //awidth
1, //aincr
@@ -180,14 +180,14 @@ DEVICE IO_dev = {
8, //dwidth
NULL, //examine
NULL, //deposit
&IO_reset, //reset
&IO_reset, //reset
NULL, //boot
&IO_attach, //attach
&IO_attach, //attach
NULL, //detach
NULL, //ctxt
0, //flags
0, //dctrl
IO_debug, //debflags
IO_debug, //debflags
NULL, //msize
NULL //lname
};

View File

@@ -69,27 +69,36 @@
#define RRSTS 0x1B //Returns diskette result byte to master
#define RDSTS 0x1C //Returns diskette device status byte to master
#define ioc_cont_NAME "Intel IOC Controller"
/* external globals */
extern uint16 PCX;
/* function prototypes */
t_stat ioc_cont_cfg(uint8 base, uint8 devnum);
t_stat ioc_cont_cfg(uint16 base, uint16 devnum, uint8 dummy);
t_stat ioc_cont_clr(void);
t_stat ioc_cont_show_param (FILE *st, UNIT *uptr, int32 val, CONST void *desc);
t_stat ioc_cont_reset (DEVICE *dptr);
uint8 ioc_cont0(t_bool io, uint8 data, uint8 devnum); /* ioc_cont*/
uint8 ioc_cont1(t_bool io, uint8 data, uint8 devnum); /* ioc_cont*/
/* external function prototypes */
extern uint8 reg_dev(uint8 (*routine)(t_bool, uint8, uint8), uint8, uint8);
extern uint8 reg_dev(uint8 (*routine)(t_bool, uint8, uint8), uint16, uint16, uint8);
extern uint8 unreg_dev(uint16);
/* globals */
static const char* ioc_cont_desc(DEVICE *dptr) {
return ioc_cont_NAME;
}
uint8 dbb_stat;
uint8 dbb_cmd;
uint8 dbb_in;
uint8 dbb_out;
uint8 ioc_cont_baseport = -1; //base port
UNIT ioc_cont_unit[] = {
{ UDATA (0, 0, 0) }, /* ioc_cont*/
@@ -111,13 +120,19 @@ DEBTAB ioc_cont_debug[] = {
{ NULL }
};
MTAB ioc_cont_mod[] = {
{ MTAB_XTD | MTAB_VDV, 0, "PARAM", NULL, NULL, ioc_cont_show_param, NULL,
"show configured parametes for ioc_cont" },
{ 0 }
};
/* address width is set to 16 bits to use devices in 8086/8088 implementations */
DEVICE ioc_cont_dev = {
"IOC-CONT", //name
ioc_cont_unit, //units
ioc_cont_reg, //registers
NULL, //modifiers
ioc_cont_mod, //modifiers
1, //numunits
16, //aradix
16, //awidth
@@ -131,21 +146,42 @@ DEVICE ioc_cont_dev = {
NULL, //attach
NULL, //detach
NULL, //ctxt
0, //flags
DEV_DEBUG+DEV_DISABLE+DEV_DIS, //flags
0, //dctrl
ioc_cont_debug, //debflags
NULL, //msize
NULL //lname
NULL//&ioc_cont_desc //device description
};
// ioc_cont configuration
t_stat ioc_cont_cfg(uint8 base, uint8 devnum)
t_stat ioc_cont_cfg(uint16 base, uint16 devnum, uint8 dummy)
{
sim_printf(" ioc-cont[%d]: at base port 0%02XH\n",
devnum, base & 0xFF);
reg_dev(ioc_cont0, base, devnum);
reg_dev(ioc_cont1, base + 1, devnum);
sim_printf(" ioc-cont: at base port 0%02XH\n",
base & 0xFF);
ioc_cont_baseport = base & 0xff;
reg_dev(ioc_cont0, base, 0, 0);
reg_dev(ioc_cont1, base + 1, 0, 0);
return SCPE_OK;
}
t_stat ioc_cont_clr(void)
{
unreg_dev(ioc_cont_baseport);
unreg_dev(ioc_cont_baseport + 1);
ioc_cont_baseport = -1;
return SCPE_OK;
}
// show configuration parameters
t_stat ioc_cont_show_param (FILE *st, UNIT *uptr, int32 val, CONST void *desc)
{
if (uptr == NULL)
return SCPE_ARG;
fprintf(st, "%s, Base port 0%04XH",
((ioc_cont_dev.flags & DEV_DIS) == 0) ? "Enabled" : "Disabled",
ioc_cont_baseport);
return SCPE_OK;
}

View File

@@ -27,15 +27,12 @@
*/
#include "system_defs.h"
#define IPC 0
/* function prototypes */
t_stat SBC_config(void);
t_stat SBC_reset (DEVICE *dptr);
uint8 get_mbyte(uint16 addr);
uint16 get_mword(uint16 addr);
void put_mbyte(uint16 addr, uint8 val);
void put_mword(uint16 addr, uint16 val);
/* external function prototypes */
@@ -45,27 +42,27 @@ extern void multibus_put_mbyte(uint16 addr, uint8 val);
extern uint8 EPROM_get_mbyte(uint16 addr, uint8 devnum);
extern uint8 RAM_get_mbyte(uint16 addr);
extern void RAM_put_mbyte(uint16 addr, uint8 val);
extern t_stat i8251_cfg(uint8 base, uint8 devnum);
extern t_stat i8251_cfg(uint8 base, uint8 devnum, uint8 dummy);
extern t_stat i8251_reset(DEVICE *dptr);
extern t_stat i8253_cfg(uint8 base, uint8 devnum);
extern t_stat i8253_cfg(uint8 base, uint8 devnum, uint8 dummy);
extern t_stat i8253_reset(DEVICE *dptr);
extern t_stat i8255_cfg(uint8 base, uint8 devnum);
extern t_stat i8255_cfg(uint8 base, uint8 devnum, uint8 dummy);
extern t_stat i8255_reset(DEVICE *dptr);
extern t_stat i8259_cfg(uint8 base, uint8 devnum);
extern t_stat i8259_cfg(uint8 base, uint8 devnum, uint8 dummy);
extern t_stat i8259_reset(DEVICE *dptr);
extern t_stat EPROM_reset(DEVICE *dptr);
extern t_stat RAM_reset(DEVICE *dptr);
extern t_stat ipc_cont_reset(DEVICE *dptr);
extern t_stat ipc_cont_cfg(uint8 base, uint8 devnum);
extern t_stat ipc_cont_cfg(uint8 base, uint8 devnum, uint8 dummy);
extern t_stat ioc_cont_reset(DEVICE *dptr);
extern t_stat ioc_cont_cfg(uint8 base, uint8 devnum);
extern uint8 reg_dev(uint8 (*routine)(t_bool, uint8, uint8), uint8, uint8);
extern t_stat ioc_cont_cfg(uint8 base, uint8 devnum, uint8 dummy);
extern uint8 reg_dev(uint8 (*routine)(t_bool, uint8, uint8), uint16, uint16, uint8);
extern t_stat EPROM_cfg(uint16 base, uint16 size, uint8 devnum);
extern t_stat RAM_cfg(uint16 base, uint16 size);
extern t_stat RAM_cfg(uint16 base, uint16 size, uint8 dummy);
/* globals */
int onetime = 0;
int ipb_onetime = 0;
/* extern globals */
@@ -86,18 +83,6 @@ extern DEVICE ioc_cont_dev;
t_stat SBC_config(void)
{
sim_printf("Configuring IPB SBC\n Onboard Devices:\n");
i8251_cfg(I8251_BASE_0, 0);
i8251_cfg(I8251_BASE_1, 1);
i8253_cfg(I8253_BASE, 0);
i8255_cfg(I8255_BASE_0, 0);
i8255_cfg(I8255_BASE_1, 1);
i8259_cfg(I8259_BASE_0, 0);
i8259_cfg(I8259_BASE_1, 1);
ipc_cont_cfg(ICONT_BASE, 0);
ioc_cont_cfg(DBB_BASE, 0);
EPROM_cfg(ROM_BASE, ROM_SIZE, 0);
RAM_cfg(RAM_BASE, RAM_SIZE);
return SCPE_OK;
}
@@ -106,78 +91,10 @@ t_stat SBC_config(void)
t_stat SBC_reset (DEVICE *dptr)
{
if (onetime == 0) {
SBC_config();
onetime++;
if (ipb_onetime == 0) {
ipb_onetime++;
}
i8080_reset(&i8080_dev);
i8251_reset(&i8251_dev);
i8253_reset(&i8253_dev);
i8255_reset(&i8255_dev);
i8259_reset(&i8259_dev);
ipc_cont_reset(&ipc_cont_dev);
ioc_cont_reset(&ioc_cont_dev);
return SCPE_OK;
}
/* get a byte from memory - handle RAM, ROM and Multibus memory */
uint8 get_mbyte(uint16 addr)
{
SET_XACK(0); /* set XACK */
if (addr >= 0xF800) { //monitor ROM - always there
return EPROM_get_mbyte(addr - 0xF000, 0); //top half of EPROM
}
if ((addr < 0x1000) && ((ipc_cont_unit.u3 & 0x04) == 0)) { //startup
return EPROM_get_mbyte(addr, 0); //top half of EPROM for boot
}
if ((addr >= 0xE800) && (addr < 0xF000) && ((ipc_cont_unit.u3 & 0x10) == 0)) { //diagnostic ROM
return EPROM_get_mbyte(addr - 0xE800, 0); //bottom half of EPROM
}
if (addr < 0x8000) { //IPB RAM
return RAM_get_mbyte(addr);
}
return multibus_get_mbyte(addr); //check multibus cards
}
/* get a word from memory */
uint16 get_mword(uint16 addr)
{
uint16 val;
val = get_mbyte(addr);
val |= (get_mbyte(addr+1) << 8);
return val;
}
/* put a byte to memory - handle RAM, ROM and Multibus memory */
void put_mbyte(uint16 addr, uint8 val)
{
SET_XACK(0); /* set no XACK */
if (addr >= 0xF800) { //monitor ROM - always there
return; //do nothing
}
if ((addr < 0x1000) && ((ipc_cont_unit.u3 & 0x04) == 0)) { //startup
return; //do nothing
}
if ((addr >= 0xE800) && (addr < 0xF000) && ((ipc_cont_unit.u3 & 0x10) == 0)) { //diagnostic ROM
return; //do nothing
}
if (addr < 0x8000) {
RAM_put_mbyte(addr, val); //IPB RAM
return;
}
multibus_put_mbyte(addr, val); //check multibus cards
}
/* put a word to memory */
void put_mword(uint16 addr, uint16 val)
{
put_mbyte(addr, val & 0xff);
put_mbyte(addr+1, val >> 8);
}
/* end of ipb.c */

View File

@@ -33,18 +33,28 @@
#include "system_defs.h" /* system header in system dir */
#define ipc_cont_NAME "Intel IPB/IPC Controller"
/* function prototypes */
t_stat ipc_cont_cfg(uint8 base, uint8 devnum);
t_stat ipc_cont_cfg(uint16 base, uint16 devnum, uint8 dummy);
t_stat ipc_cont_clr(void);
t_stat ipc_cont_show_param (FILE *st, UNIT *uptr, int32 val, CONST void *desc);
uint8 ipc_cont(t_bool io, uint8 data, uint8 devnum); /* ipc_cont*/
t_stat ipc_cont_reset (DEVICE *dptr);
/* external function prototypes */
extern uint8 reg_dev(uint8 (*routine)(t_bool, uint8, uint8), uint8, uint8);
extern uint8 reg_dev(uint8 (*routine)(t_bool, uint8, uint8), uint16, uint16, uint8);
extern uint8 unreg_dev(uint16);
/* globals */
static const char* ipc_cont_desc(DEVICE *dptr) {
return ipc_cont_NAME;
}
uint8 ipc_cont_baseport = -1; //base port
UNIT ipc_cont_unit =
{ UDATA (0, 0, 0) }; /* ipc_cont*/
@@ -65,13 +75,19 @@ DEBTAB ipc_cont_debug[] = {
{ NULL }
};
MTAB ipc_cont_mod[] = {
{ MTAB_XTD | MTAB_VDV, 0, "PARAM", NULL, NULL, ipc_cont_show_param, NULL,
"show configured parametes for ipc_cont" },
{ 0 }
};
/* address width is set to 16 bits to use devices in 8086/8088 implementations */
DEVICE ipc_cont_dev = {
"IPC-CONT", //name
&ipc_cont_unit, //units
ipc_cont_reg, //registers
NULL, //modifiers
ipc_cont_mod, //modifiers
1, //numunits
16, //aradix
16, //awidth
@@ -85,20 +101,40 @@ DEVICE ipc_cont_dev = {
NULL, //attach
NULL, //detach
NULL, //ctxt
0, //flags
DEV_DEBUG+DEV_DISABLE+DEV_DIS, //flags
0, //dctrl
ipc_cont_debug, //debflags
NULL, //msize
NULL //lname
NULL//&ipc_cont_desc //device description
};
// ipc_cont configuration
t_stat ipc_cont_cfg(uint8 base, uint8 devnum)
t_stat ipc_cont_cfg(uint16 base, uint16 devnum, uint8 dummy)
{
sim_printf(" ipc-cont[%d]: at port 0%02XH\n",
devnum, base & 0xFF);
reg_dev(ipc_cont, base, devnum);
sim_printf(" ipc-cont: at port 0%02XH\n",
base & 0xFF);
ipc_cont_baseport = base & 0xff;
reg_dev(ipc_cont, base, 0, 0);
return SCPE_OK;
}
t_stat ipc_cont_clr(void)
{
unreg_dev(ipc_cont_baseport);
ipc_cont_baseport = -1;
return SCPE_OK;
}
// show configuration parameters
t_stat ipc_cont_show_param (FILE *st, UNIT *uptr, int32 val, CONST void *desc)
{
if (uptr == NULL)
return SCPE_ARG;
fprintf(st, "%s, Base port 0%04XH",
((ipc_cont_dev.flags & DEV_DIS) == 0) ? "Enabled" : "Disabled",
ipc_cont_baseport);
return SCPE_OK;
}
@@ -122,7 +158,8 @@ uint8 ipc_cont(t_bool io, uint8 data, uint8 devnum)
return ipc_cont_unit.u3;
} else { /* write control port */
//this simulates an 74LS259 register
//d0-d2 address the reg(in reverse order!), d3 is the data to be latched (inverted)
//d0-d2 address the reg(in reverse order!)
//d3 is the data to be latched (inverted)
switch(data & 0x07) {
case 5: //interrupt enable 8085 INTR
if(data & 0x08) //bit low

View File

@@ -30,15 +30,12 @@
*/
#include "system_defs.h"
#define IPC 1
/* function prototypes */
t_stat SBC_config(void);
t_stat SBC_reset (DEVICE *dptr);
uint8 get_mbyte(uint16 addr);
uint16 get_mword(uint16 addr);
void put_mbyte(uint16 addr, uint8 val);
void put_mword(uint16 addr, uint16 val);
/* external function prototypes */
@@ -48,23 +45,23 @@ extern void multibus_put_mbyte(uint16 addr, uint8 val);
extern uint8 EPROM_get_mbyte(uint16 addr, uint8 devnum);
extern uint8 RAM_get_mbyte(uint16 addr);
extern void RAM_put_mbyte(uint16 addr, uint8 val);
extern t_stat i8251_cfg(uint8 base, uint8 devnum);
extern t_stat i8251_cfg(uint16 base, uint16 devnum, uint8 dummy);
extern t_stat i8253_cfg(uint16 base, uint16 devnum, uint8 dummy);
extern t_stat i8255_cfg(uint16 base, uint16 devnum, uint8 dummy);
extern t_stat i8259_cfg(uint16 base, uint16 devnum, uint8 dummy);
extern t_stat i8251_reset(DEVICE *dptr);
extern t_stat i8253_cfg(uint8 base, uint8 devnum);
extern t_stat i8253_reset(DEVICE *dptr);
extern t_stat i8255_cfg(uint8 base, uint8 devnum);
extern t_stat i8255_reset(DEVICE *dptr);
extern t_stat i8259_cfg(uint8 base, uint8 devnum);
extern t_stat i8259_reset(DEVICE *dptr);
extern t_stat EPROM_reset(DEVICE *dptr);
extern t_stat RAM_reset(DEVICE *dptr);
extern t_stat ipc_cont_reset(DEVICE *dptr);
extern t_stat ipc_cont_cfg(uint8 base, uint8 devnum);
extern t_stat ioc_cont_cfg(uint16 base, uint16 devnum, uint8 dummy);
extern t_stat ipc_cont_cfg(uint16 base, uint16 devnum, uint8 dummy);
extern t_stat ioc_cont_reset(DEVICE *dptr);
extern t_stat ioc_cont_cfg(uint8 base, uint8 devnum);
extern uint8 reg_dev(uint8 (*routine)(t_bool, uint8, uint8), uint8, uint8);
extern t_stat EPROM_cfg(uint16 base, uint16 size, uint8 devnum);
extern t_stat RAM_cfg(uint16 base, uint16 size);
extern t_stat RAM_cfg(uint16 base, uint16 size, uint8 dummy);
/* external globals */
@@ -85,22 +82,22 @@ extern DEVICE ioc_cont_dev;
/* globals */
int onetime = 0;
int ipc_onetime = 0;
t_stat SBC_config(void)
{
sim_printf("Configuring IPC SBC\n Onboard Devices:\n");
i8251_cfg(I8251_BASE_0, 0);
i8251_cfg(I8251_BASE_1, 1);
i8253_cfg(I8253_BASE, 0);
i8255_cfg(I8255_BASE_0, 0);
i8255_cfg(I8255_BASE_1, 1);
i8259_cfg(I8259_BASE_0, 0);
i8259_cfg(I8259_BASE_1, 1);
ipc_cont_cfg(ICONT_BASE, 0);
ioc_cont_cfg(DBB_BASE, 0);
i8251_cfg(I8251_BASE_0, 0, 0);
i8251_cfg(I8251_BASE_1, 1, 0);
i8253_cfg(I8253_BASE, 0, 0);
i8255_cfg(I8255_BASE_0, 0, 0);
i8255_cfg(I8255_BASE_1, 1, 0);
i8259_cfg(I8259_BASE_0, 0, 0);
i8259_cfg(I8259_BASE_1, 1, 0);
ipc_cont_cfg(ICONT_BASE, 0, 0);
ioc_cont_cfg(DBB_BASE, 0, 0);
EPROM_cfg(ROM_BASE, ROM_SIZE, 0);
RAM_cfg(RAM_BASE, RAM_SIZE);
RAM_cfg(RAM_BASE, RAM_SIZE, 0);
return SCPE_OK;
}
@@ -109,9 +106,9 @@ t_stat SBC_config(void)
t_stat SBC_reset (DEVICE *dptr)
{
if (onetime == 0) {
if (ipc_onetime == 0) {
SBC_config();
onetime++;
ipc_onetime++;
}
i8080_reset(&i8080_dev);
i8251_reset(&i8251_dev);
@@ -123,65 +120,4 @@ t_stat SBC_reset (DEVICE *dptr)
return SCPE_OK;
}
/* get a byte from memory - handle RAM, ROM and Multibus memory */
uint8 get_mbyte(uint16 addr)
{
SET_XACK(1); /* set no XACK */
if (addr >= 0xF800) { //monitor ROM - always there
return EPROM_get_mbyte(addr - 0xF000, 0); //top half of EPROM
}
if ((addr < 0x1000) && ((ipc_cont_unit.u3 & 0x04) == 0)) { //startup
return EPROM_get_mbyte(addr, 0); //top half of EPROM for boot
}
if ((addr >= 0xE800) && (addr < 0xF000) && ((ipc_cont_unit.u3 & 0x10) == 0)) { //diagnostic ROM
return EPROM_get_mbyte(addr - 0xE800, 0); //bottom half of EPROM
}
if (addr < 0x8000) { //IPC RAM
return RAM_get_mbyte(addr);
}
SET_XACK(0); /* set no XACK */
return multibus_get_mbyte(addr); //check multibus cards
}
/* get a word from memory */
uint16 get_mword(uint16 addr)
{
uint16 val;
val = get_mbyte(addr);
val |= (get_mbyte(addr+1) << 8);
return val;
}
/* put a byte to memory - handle RAM, ROM and Multibus memory */
void put_mbyte(uint16 addr, uint8 val)
{
SET_XACK(0); /* set no XACK */
if (addr >= 0xF800) { //monitor ROM - always there
return;
}
if ((addr < 0x1000) && ((ipc_cont_unit.u3 & 0x04) == 0)) { //startup
return;
}
if ((addr >= 0xE800) && (addr < 0xF000) && ((ipc_cont_unit.u3 & 0x10) == 0)) { //diagnostic ROM
return;
}
if (addr < 0x8000) {
RAM_put_mbyte(addr, val); //IPB RAM
return;
}
multibus_put_mbyte(addr, val); //check multibus cards
}
/* put a word to memory */
void put_mword(uint16 addr, uint16 val)
{
put_mbyte(addr, val & 0xff);
put_mbyte(addr+1, val >> 8);
}
/* end of ipc.c */

View File

@@ -36,18 +36,43 @@
#include "system_defs.h"
#define BASE_ADDR u3
#define iRAM_NAME "Intel RAM Chip"
/* function prototypes */
t_stat RAM_cfg(uint16 base, uint16 size);
t_stat RAM_cfg(uint16 base, uint16 size, uint8 dummy);
t_stat RAM_clr(void);
t_stat RAM_reset (DEVICE *dptr);
t_stat RAM_set_size(UNIT *uptr, int32 val, CONST char *cptr, void *desc);
t_stat RAM_set_base(UNIT *uptr, int32 val, CONST char *cptr, void *desc);
t_stat RAM_show_param (FILE *st, UNIT *uptr, int32 val, CONST void *desc);
uint8 RAM_get_mbyte(uint16 addr);
void RAM_put_mbyte(uint16 addr, uint8 val);
/* external function prototypes */
/* external globals */
// globals
static const char* iRAM_desc(DEVICE *dptr) {
return iRAM_NAME;
}
/* SIMH RAM Standard I/O Data Structures */
UNIT RAM_unit = { UDATA (NULL, UNIT_BINK, 0), KBD_POLL_WAIT };
UNIT RAM_unit = { UDATA (NULL, UNIT_BINK, 0) };
MTAB RAM_mod[] = {
{ MTAB_XTD | MTAB_VDV, 0, NULL, "BASE", &RAM_set_base,
NULL, NULL, "Sets the base address for RAM"},
{ MTAB_XTD | MTAB_VDV, 0, NULL, "SIZE", &RAM_set_size,
NULL, NULL, "Sets the size for RAM"},
{ MTAB_XTD | MTAB_VDV, 0, "PARAM", NULL, NULL, RAM_show_param, NULL,
"show configured parametes for RAM" },
{ 0 }
};
DEBTAB RAM_debug[] = {
{ "ALL", DEBUG_all },
@@ -64,7 +89,7 @@ DEVICE RAM_dev = {
"RAM", //name
&RAM_unit, //units
NULL, //registers
NULL, //modifiers
RAM_mod, //modifiers
1, //numunits
16, //aradix
16, //awidth
@@ -78,18 +103,22 @@ DEVICE RAM_dev = {
NULL, //attach
NULL, //detach
NULL, //ctxt
DEV_DEBUG, //flags
DEV_DEBUG+DEV_DISABLE+DEV_DIS, //flags
0, //dctrl
RAM_debug, //debflags
NULL, //msize
NULL //lname
NULL, //lname
NULL, //help routine
NULL, //attach help routine
NULL, //help context
&iRAM_desc //device description
};
/* RAM functions */
// RAM configuration
t_stat RAM_cfg(uint16 base, uint16 size)
t_stat RAM_cfg(uint16 base, uint16 size, uint8 dummy)
{
RAM_unit.capac = size; /* set RAM size */
RAM_unit.u3 = base; /* set RAM base */
@@ -98,11 +127,19 @@ t_stat RAM_cfg(uint16 base, uint16 size)
sim_printf (" RAM: Calloc error\n");
return SCPE_MEM;
}
sim_printf(" RAM: 0%04XH bytes at base 0%04XH\n",
sim_printf(" RAM: 0%04XH bytes at base address 0%04XH\n",
size, base);
return SCPE_OK;
}
t_stat RAM_clr(void)
{
RAM_unit.capac = 0;
RAM_unit.u3 = 0;
free(RAM_unit.filebuf);
return SCPE_OK;
}
/* RAM reset */
t_stat RAM_reset (DEVICE *dptr)
@@ -110,6 +147,64 @@ t_stat RAM_reset (DEVICE *dptr)
return SCPE_OK;
}
// set size parameter
t_stat RAM_set_size(UNIT *uptr, int32 val, CONST char *cptr, void *desc)
{
uint32 size, result, i;
if (cptr == NULL)
return SCPE_ARG;
result = sscanf(cptr, "%i%n", &size, &i);
if ((result == 1) && (cptr[i] == 'K') && ((cptr[i + 1] == 0) ||
((cptr[i + 1] == 'B') && (cptr[i + 2] == 0)))) {
if (size & 0xff8f) {
sim_printf("RAM: Size error\n");
return SCPE_ARG;
} else {
RAM_unit.capac = (size * 1024) - 1;
sim_printf("RAM: Size=%04XH\n", RAM_unit.capac);
return SCPE_OK;
}
}
return SCPE_ARG;
}
// set base address parameter
t_stat RAM_set_base(UNIT *uptr, int32 val, CONST char *cptr, void *desc)
{
uint32 size, result, i;
if (cptr == NULL)
return SCPE_ARG;
result = sscanf(cptr, "%i%n", &size, &i);
if ((result == 1) && (cptr[i] == 'K') && ((cptr[i + 1] == 0) ||
((cptr[i + 1] == 'B') && (cptr[i + 2] == 0)))) {
if (size & 0xff8f) {
sim_printf("RAM: Base error\n");
return SCPE_ARG;
} else {
RAM_unit.BASE_ADDR = size * 1024;
sim_printf("RAM: Base=%04XH\n", RAM_unit.BASE_ADDR);
return SCPE_OK;
}
}
return SCPE_ARG;
}
// show configuration parameters
t_stat RAM_show_param (FILE *st, UNIT *uptr, int32 val, CONST void *desc)
{
if (uptr == NULL)
return SCPE_ARG;
fprintf(st, "%s at Base Address 0%04XH (%dD) for 0%04XH (%dD) Bytes ",
((RAM_dev.flags & DEV_DIS) == 0) ? "Enabled" : "Disabled",
RAM_unit.u3, RAM_unit.u3, RAM_unit.capac, RAM_unit.capac);
return SCPE_OK;
}
/* get a byte from memory */
uint8 RAM_get_mbyte(uint16 addr)

156
Intel-Systems/common/irq.c Normal file
View File

@@ -0,0 +1,156 @@
/* irq.c: Intel Interrupt simulator
Copyright (c) 2010, William A. Beech
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 NONINFRINGEMENT. IN NO EVENT SHALL
WILLIAM A. BEECH 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 name of William A. Beech shall not be
used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from William A. Beech.
MODIFICATIONS:
20 Sep 20 - Original file.
NOTES:
*/
#include "system_defs.h"
#define irq_NAME "Intel Interrupt Simulator"
/* function prototypes */
t_stat irq_svc(UNIT *uptr);
t_stat irq_reset(DEVICE *dptr);
void set_irq(int32 irq_num);
void clr_irq(int32 irq_num);
/* external function prototypes */
//extern t_stat SBC_reset(DEVICE *dptr); /* reset the iSBC80/10 emulator */
extern void set_cpuint(int32 irq_num);
/* local globals */
int32 mbirq = 0; /* set no multibus interrupts */
static const char* irq_desc(DEVICE *dptr) {
return irq_NAME;
}
/* external globals */
extern uint8 xack; /* XACK signal */
extern int32 irq_req; /* i8080 INT signal */
extern uint16 PCX;
extern DEVICE isbc064_dev;
extern DEVICE isbc464_dev;
/* multibus Standard SIMH Device Data Structures */
UNIT irq_unit = {
UDATA (&irq_svc, 0, 0), 1
};
REG irq_reg[] = {
{ HRDATA (MBIRQ, mbirq, 32) },
{ NULL }
};
DEBTAB irq_debug[] = {
{ "ALL", DEBUG_all },
{ "FLOW", DEBUG_flow },
{ "READ", DEBUG_read },
{ "WRITE", DEBUG_write },
{ "LEV1", DEBUG_level1 },
{ "LEV2", DEBUG_level2 },
{ NULL }
};
DEVICE irq_dev = {
"IRQ", //name
&irq_unit, //units
irq_reg, //registers
NULL, //modifiers
1, //numunits
16, //aradix
16, //awidth
1, //aincr
16, //dradix
8, //dwidth
NULL, //examine
NULL, //deposit
&irq_reset, //reset
NULL, //boot
NULL, //attach
NULL, //detach
NULL, //ctxt
DEV_DEBUG, //flags
0, //dctrl
irq_debug, //debflags
NULL, //msize
NULL, //lname
NULL, //help routine
NULL, //attach help routine
NULL, //help context
&irq_desc //device description
};
/* Service routines to handle simulator functions */
/* Reset routine */
t_stat irq_reset(DEVICE *dptr)
{
// if (SBC_reset(NULL) == 0) {
sim_printf(" Interrupt: Reset\n");
sim_activate (&irq_unit, irq_unit.wait); /* activate unit */
return SCPE_OK;
// } else {
// sim_printf(" Interrupt: SBC not selected\n");
// return SCPE_OK;
// }
}
/* service routine - actually does the simulated interrupts */
t_stat irq_svc(UNIT *uptr)
{
switch (mbirq) {
case INT_2:
set_cpuint(INT_R);
break;
default:
break;
}
sim_activate (&irq_unit, irq_unit.wait); /* continue poll */
return SCPE_OK;
}
void set_irq(int32 irq_num)
{
mbirq |= irq_num;
}
void clr_irq(int32 irq_num)
{
mbirq &= ~irq_num;
}
/* end of irq.c */

View File

@@ -37,12 +37,14 @@
#include "system_defs.h"
#if defined (SBC064_NUM) && (SBC064_NUM > 0) //if board allowed with this system
#define BASE_ADDR u3
#define isbc064_NAME "Intel iSBC 064 RAM Board"
/* prototypes */
t_stat isbc064_cfg(uint16 base, uint16 size, uint8 dummy);
t_stat isbc064_clr(void);
t_stat isbc064_set_size(UNIT *uptr, int32 val, CONST char *cptr, void *desc);
t_stat isbc064_set_base(UNIT *uptr, int32 val, CONST char *cptr, void *desc);
t_stat isbc064_show_param (FILE *st, UNIT *uptr, int32 val, CONST void *desc);
@@ -54,7 +56,9 @@ void isbc064_put_mbyte(uint16 addr, uint8 val);
/* local globals */
int isbc064_onetime = 1;
static const char* isbc064_desc(DEVICE *dptr) {
return isbc064_NAME;
}
/* external globals */
@@ -74,7 +78,7 @@ MTAB isbc064_mod[] = {
&isbc064_set_size, /* validation routine */
NULL, /* display routine */
NULL, /* location descriptor */
"Sets the RAM size for iSB 064" /* help string */
"Sets the RAM size for iSBC 064" /* help string */
},
{ MTAB_XTD | MTAB_VDV, /* mask */
0 /* match */,
@@ -126,7 +130,7 @@ DEVICE isbc064_dev = {
NULL, //attach
NULL, //detach
NULL, //ctxt
DEV_DISABLE+DEV_DIS, //flags
DEV_DEBUG+DEV_DISABLE+DEV_DIS, //flags
0, //dctrl
isbc064_debug, //debflags
NULL, //msize
@@ -134,11 +138,34 @@ DEVICE isbc064_dev = {
NULL, //help routine
NULL, //attach help routine
NULL, //help context
NULL //device description
&isbc064_desc //device description
};
/* Service routines to handle simulator functions */
// isbc064 configuration
t_stat isbc064_cfg(uint16 base, uint16 size, uint8 dummy)
{
isbc064_unit.capac = size;
isbc064_unit.u3 = base;
isbc064_dev.units->filebuf = (uint8 *)calloc(isbc064_unit.capac, sizeof(uint8)); //alloc buffer
if (isbc064_dev.units->filebuf == NULL) { //CALLOC error
sim_printf (" SBC064: Calloc error\n");
return SCPE_MEM;
}
sim_printf(" SBC064: Enabled 0%04XH bytes at base 0%04XH\n",
isbc064_dev.units->capac, isbc064_dev.units->BASE_ADDR);
return SCPE_OK;
}
t_stat isbc064_clr(void)
{
isbc064_unit.capac = 0;
isbc064_unit.u3 = 0;
free(isbc064_unit.filebuf);
return SCPE_OK;
}
// set size parameter
@@ -190,7 +217,7 @@ t_stat isbc064_set_base(UNIT *uptr, int32 val, CONST char *cptr, void *desc)
t_stat isbc064_show_param (FILE *st, UNIT *uptr, int32 val, CONST void *desc)
{
fprintf(st, "%s Base=%04XH Size=%04XH ",
fprintf(st, "Device %s, Base address=0%04XH, Size=0%04XH ",
((isbc064_dev.flags & DEV_DIS) == 0) ? "Enabled" : "Disabled",
isbc064_unit.BASE_ADDR, isbc064_unit.capac);
return SCPE_OK;
@@ -202,24 +229,6 @@ t_stat isbc064_reset (DEVICE *dptr)
{
if (dptr == NULL)
return SCPE_ARG;
if (isbc064_onetime) {
isbc064_dev.units->capac = SBC064_SIZE; //set default size
isbc064_dev.units->BASE_ADDR = SBC064_BASE; //set default base
isbc064_onetime = 0;
}
if ((dptr->flags & DEV_DIS) == 0) { //already enabled
isbc064_dev.units->filebuf = (uint8 *)calloc(isbc064_unit.capac, sizeof(uint8)); //alloc buffer
if (isbc064_dev.units->filebuf == NULL) { //CALLOC error
sim_printf (" sbc064: Calloc error\n");
return SCPE_MEM;
}
sim_printf(" sbc064: Enabled 0%04XH bytes at base 0%04XH\n",
isbc064_dev.units->capac, isbc064_dev.units->BASE_ADDR);
} else {
if (isbc064_dev.units->filebuf)
free(isbc064_dev.units->filebuf); //return allocated memory
sim_printf(" sbc064: Disabled\n");
}
return SCPE_OK;
}
@@ -241,6 +250,4 @@ void isbc064_put_mbyte(uint16 addr, uint8 val)
return;
}
#endif /* SBC064_NUM > 0 */
/* end of isbc064.c */

View File

@@ -126,7 +126,7 @@
Byte 5 - Buffer Low Address
Byte 6 - Buffer High Address
Byte 7 - Buffer High Address
Byte 8 - Block Number
@@ -160,8 +160,6 @@
#include "system_defs.h" /* system header in system dir */
#if defined (SBC201_NUM) && (SBC201_NUM > 0)
#define UNIT_V_WPMODE (UNIT_V_UF) /* Write protect */
#define UNIT_WPMODE (1 << UNIT_V_WPMODE)
@@ -214,13 +212,15 @@ extern uint16 PCX;
/* external function prototypes */
extern uint8 reg_dev(uint8 (*routine)(t_bool, uint8, uint8), uint8, uint8);
extern uint8 unreg_dev(uint8);
extern uint8 reg_dev(uint8 (*routine)(t_bool, uint8, uint8), uint16, uint16, uint8);
extern uint8 unreg_dev(uint16 port);
extern uint8 get_mbyte(uint16 addr);
extern void put_mbyte(uint16 addr, uint8 val);
/* function prototypes */
t_stat isbc201_cfg(uint16 baseport, uint16 devnum, uint8 intnum);
t_stat isbc201_clr(void);
t_stat isbc201_set_mode (UNIT *uptr, int32 val, CONST char *cptr, void *desc);
t_stat isbc201_set_port (UNIT *uptr, int32 val, CONST char *cptr, void *desc);
t_stat isbc201_set_int (UNIT *uptr, int32 val, CONST char *cptr, void *desc);
@@ -239,16 +239,16 @@ void isbc201_diskio(void); //do actual disk i/o
/* globals */
int isbc201_onetime = 1;
static const char* isbc201_desc(DEVICE *dptr) {
return isbc201_NAME;
}
typedef struct { //FDD definition
uint8 sec;
uint8 cyl;
} FDDDEF;
typedef struct { //FDC definition
typedef struct { //FDC board definition
uint8 baseport; //FDC base port
uint8 intnum; //interrupt number
uint8 verb; //verbose flag
@@ -258,17 +258,17 @@ typedef struct { //FDC definition
uint8 rtype; //FDC result type
uint8 rbyte0; //FDC result byte for type 00
uint8 rbyte1; //FDC result byte for type 10
uint8 intff; //fdc interrupt FF
uint8 intff; //FDC interrupt FF
FDDDEF fdd[FDD_NUM]; //indexed by the FDD number
} FDCDEF;
FDCDEF fdc201; //indexed by the isbc-202 instance number
FDCDEF fdc201; //indexed by the isbc-201 instance number
/* isbc201 Standard I/O Data Structures */
UNIT isbc201_unit[] = { //2 FDDs
{ UDATA (0, UNIT_ATTABLE+UNIT_DISABLE+UNIT_BUFABLE+UNIT_MUSTBUF+UNIT_FIX, MDSSD) },
{ UDATA (0, UNIT_ATTABLE+UNIT_DISABLE+UNIT_BUFABLE+UNIT_MUSTBUF+UNIT_FIX, MDSSD) }
{ UDATA (0, UNIT_ATTABLE+UNIT_DISABLE+UNIT_ROABLE+UNIT_RO+UNIT_BUFABLE+UNIT_MUSTBUF+UNIT_FIX, MDSSD) },
{ UDATA (0, UNIT_ATTABLE+UNIT_DISABLE+UNIT_ROABLE+UNIT_RO+UNIT_BUFABLE+UNIT_MUSTBUF+UNIT_FIX, MDSSD) }
};
REG isbc201_reg[] = {
@@ -336,6 +336,50 @@ DEVICE isbc201_dev = {
&isbc201_desc //device description
};
// iSBC 201 configuration
t_stat isbc201_cfg(uint16 baseport, uint16 devnum, uint8 intnum)
{
int i;
UNIT *uptr;
// one-time initialization for all FDDs for this FDC instance
for (i = 0; i < FDD_NUM; i++) {
uptr = isbc201_dev.units + i;
uptr->u6 = i; //fdd unit number
uptr->flags &= ~UNIT_ATT;
}
fdc201.baseport = baseport & 0xff; //set port
fdc201.intnum = intnum; //set interrupt
fdc201.verb = 0; //clear verb
reg_dev(isbc201r0, fdc201.baseport, 0, 0); //read status
reg_dev(isbc201r1, fdc201.baseport + 1, 0, 0); //read rslt type/write IOPB addr-l
reg_dev(isbc201r2, fdc201.baseport + 2, 0, 0); //write IOPB addr-h and start
reg_dev(isbc201r3, fdc201.baseport + 3, 0, 0); //read rstl byte
reg_dev(isbc201r7, fdc201.baseport + 7, 0, 0); //write reset fdc201
isbc201_reset_dev(); //software reset
// if (fdc201.verb)
sim_printf(" sbc201: Enabled base port at 0%02XH, Interrupt #=%02X, %s\n",
fdc201.baseport, fdc201.intnum, fdc201.verb ? "Verbose" : "Quiet" );
return SCPE_OK;
}
// iSBC 201 deconfiguration
t_stat isbc201_clr(void)
{
fdc201.intnum = -1; //set default interrupt
fdc201.verb = 0; //set verb = 0
unreg_dev(fdc201.baseport); //read status
unreg_dev(fdc201.baseport + 1); //read rslt type/write IOPB addr-l
unreg_dev(fdc201.baseport + 2); //write IOPB addr-h and start
unreg_dev(fdc201.baseport + 3); //read rstl byte
unreg_dev(fdc201.baseport + 7); //write reset fdc201
// if (fdc201.verb)
sim_printf(" sbc201: Disabled\n");
return SCPE_OK;
}
/* fdc201 set mode = Write protect */
t_stat isbc201_set_mode (UNIT *uptr, int32 val, CONST char *cptr, void *desc)
@@ -343,7 +387,8 @@ t_stat isbc201_set_mode (UNIT *uptr, int32 val, CONST char *cptr, void *desc)
if (uptr == NULL)
return SCPE_ARG;
if (uptr->flags & UNIT_ATT)
return sim_messagef (SCPE_ALATT, "%s is already attached to %s\n", sim_uname(uptr), uptr->filename);
return sim_messagef (SCPE_ALATT, "%s is already attached to %s\n",
sim_uname(uptr), uptr->filename);
if (val & UNIT_WPMODE) { /* write protect */
uptr->flags |= val;
if (fdc201.verb)
@@ -356,7 +401,7 @@ t_stat isbc201_set_mode (UNIT *uptr, int32 val, CONST char *cptr, void *desc)
return SCPE_OK;
}
// set base address parameter
// set base port address parameter
t_stat isbc201_set_port(UNIT *uptr, int32 val, CONST char *cptr, void *desc)
{
@@ -366,8 +411,13 @@ t_stat isbc201_set_port(UNIT *uptr, int32 val, CONST char *cptr, void *desc)
return SCPE_ARG;
result = sscanf(cptr, "%02x", &size);
fdc201.baseport = size;
if (fdc201.verb)
sim_printf("SBC201: Base port=%04X\n", fdc201.baseport);
// if (fdc201.verb)
sim_printf("SBC201: Installed at base port=%04X\n", fdc201.baseport);
reg_dev(isbc201r0, fdc201.baseport, 0, 0); //read status
reg_dev(isbc201r1, fdc201.baseport + 1, 0, 0); //read rslt type/write IOPB addr-l
reg_dev(isbc201r2, fdc201.baseport + 2, 0, 0); //write IOPB addr-h and start
reg_dev(isbc201r3, fdc201.baseport + 3, 0, 0); //read rstl byte
reg_dev(isbc201r7, fdc201.baseport + 7, 0, 0); //write reset fdc201
return SCPE_OK;
}
@@ -381,7 +431,7 @@ t_stat isbc201_set_int(UNIT *uptr, int32 val, CONST char *cptr, void *desc)
return SCPE_ARG;
result = sscanf(cptr, "%02x", &size);
fdc201.intnum = size;
if (fdc201.verb)
// if (fdc201.verb)
sim_printf("SBC201: Interrupt number=%04X\n", fdc201.intnum);
return SCPE_OK;
}
@@ -398,7 +448,6 @@ t_stat isbc201_set_verb(UNIT *uptr, int32 val, CONST char *cptr, void *desc)
}
if (strncasecmp(cptr, "ON", 3) == 0) {
fdc201.verb = 1;
sim_printf(" SBC201: fdc201.verb=%d\n", fdc201.verb);
return SCPE_OK;
}
return SCPE_ARG;
@@ -422,41 +471,9 @@ t_stat isbc201_show_param (FILE *st, UNIT *uptr, int32 val, CONST void *desc)
t_stat isbc201_reset(DEVICE *dptr)
{
int i;
UNIT *uptr;
if (dptr == NULL)
return SCPE_ARG;
if (isbc201_onetime) {
fdc201.baseport = SBC201_BASE; //set default base
fdc201.intnum = SBC201_INT; //set default interrupt
fdc201.verb = 0; //set verb = 0
isbc201_onetime = 0;
// one-time initialization for all FDDs for this FDC instance
for (i = 0; i < FDD_NUM; i++) {
uptr = isbc201_dev.units + i;
uptr->u6 = i; //fdd unit number
}
}
if ((dptr->flags & DEV_DIS) == 0) { // enabled
reg_dev(isbc201r0, fdc201.baseport, 0); //read status
reg_dev(isbc201r1, fdc201.baseport + 1, 0); //read rslt type/write IOPB addr-l
reg_dev(isbc201r2, fdc201.baseport + 2, 0); //write IOPB addr-h and start
reg_dev(isbc201r3, fdc201.baseport + 3, 0); //read rstl byte
reg_dev(isbc201r7, fdc201.baseport + 7, 0); //write reset fdc201
isbc201_reset_dev(); //software reset
// if (fdc201.verb)
sim_printf(" sbc201: Enabled base port at 0%02XH Interrupt #=%02X %s\n",
fdc201.baseport, fdc201.intnum, fdc201.verb ? "Verbose" : "Quiet" );
} else {
unreg_dev(fdc201.baseport); //read status
unreg_dev(fdc201.baseport + 1); //read rslt type/write IOPB addr-l
unreg_dev(fdc201.baseport + 2); //write IOPB addr-h and start
unreg_dev(fdc201.baseport + 3); //read rstl byte
unreg_dev(fdc201.baseport + 7); //write reset fdc201
// if (fdc201.verb)
sim_printf(" sbc201: Disabled\n");
}
isbc201_reset_dev();
return SCPE_OK;
}
@@ -467,13 +484,13 @@ void isbc201_reset_dev(void)
int32 i;
UNIT *uptr;
fdc201.stat = 0; //clear status
fdc201.stat = 0; //clear status
for (i = 0; i < FDD_NUM; i++) { /* handle all units */
uptr = isbc201_dev.units + i;
fdc201.stat |= FDCPRE; //set the FDC status
fdc201.stat |= FDCPRE; //set the FDC status
fdc201.rtype = ROK;
fdc201.rbyte0 = 0; //set no error
if (uptr->flags & UNIT_ATT) { /* if attached */
if (uptr->flags & UNIT_ATT) { /* if attached */
switch(i){
case 0:
fdc201.stat |= RDY0; //set FDD 0 ready
@@ -496,18 +513,18 @@ t_stat isbc201_attach (UNIT *uptr, CONST char *cptr)
t_stat r;
uint8 fddnum;
fddnum = uptr->u6;
if ((r = attach_unit (uptr, cptr)) != SCPE_OK) {
sim_printf(" SBC201_attach: Attach error %d\n", r);
return r;
}
fddnum = uptr->u6;
switch(fddnum){
case 0:
fdc201.stat |= RDY0; //set FDD 0 ready
fdc201.stat |= RDY0; //set FDD 0 ready
fdc201.rbyte1 |= RB1RD0;
break;
case 1:
fdc201.stat |= RDY1; //set FDD 1 ready
fdc201.stat |= RDY1; //set FDD 1 ready
fdc201.rbyte1 |= RB1RD1;
break;
}
@@ -524,7 +541,7 @@ t_stat isbc201_attach (UNIT *uptr, CONST char *cptr)
uint8 isbc201r0(t_bool io, uint8 data, uint8 devnum)
{
if (io == 0) { /* read status*/
if (io == 0) { /* read status*/
return fdc201.stat;
}
return 0;
@@ -532,11 +549,12 @@ uint8 isbc201r0(t_bool io, uint8 data, uint8 devnum)
uint8 isbc201r1(t_bool io, uint8 data, uint8 devnum)
{
if (io == 0) { /* read data port */
fdc201.intff = 0; //clear interrupt FF
if (io == 0) { /* read data port */
fdc201.intff = 0; //clear interrupt FF
fdc201.stat &= ~FDCINT;
fdc201.rtype = ROK;
return fdc201.rtype;
} else { /* write data port */
} else { /* write data port */
fdc201.iopb = data;
}
return 0;
@@ -544,20 +562,20 @@ uint8 isbc201r1(t_bool io, uint8 data, uint8 devnum)
uint8 isbc201r2(t_bool io, uint8 data, uint8 devnum)
{
if (io == 0) { /* read data port */
if (io == 0) { /* read data port */
;
} else { /* write data port */
} else { /* write data port */
fdc201.iopb |= (data << 8);
isbc201_diskio();
if (fdc201.intff)
fdc201.stat |= FDCINT;
}
}
return 0;
}
uint8 isbc201r3(t_bool io, uint8 data, uint8 devnum)
{
if (io == 0) { /* read data port */
if (io == 0) { /* read data port */
if (fdc201.rtype == ROK) {
return fdc201.rbyte0;
} else {
@@ -567,17 +585,17 @@ uint8 isbc201r3(t_bool io, uint8 data, uint8 devnum)
return fdc201.rbyte0;
}
}
} else { /* write data port */
; //stop diskette operation
} else { /* write data port */
; //stop diskette operation after current linked IOPB finishes
}
return 0;
}
uint8 isbc201r7(t_bool io, uint8 data, uint8 devnum)
{
if (io == 0) { /* read data port */
if (io == 0) { /* read data port */
;
} else { /* write data port */
} else { /* write data port */
isbc201_reset_dev();
}
return 0;
@@ -596,26 +614,29 @@ void isbc201_diskio(void)
uint8 *fbuf;
//parse the IOPB
cw = get_mbyte(fdc201.iopb);
di = get_mbyte(fdc201.iopb + 1);
nr = get_mbyte(fdc201.iopb + 2);
ta = get_mbyte(fdc201.iopb + 3);
sa = get_mbyte(fdc201.iopb + 4) & 0x1f;
ba = get_mbyte(fdc201.iopb + 5);
ba |= (get_mbyte(fdc201.iopb + 6) << 8);
bn = get_mbyte(fdc201.iopb + 7);
cw = get_mbyte(fdc201.iopb); //Channel Word
di = get_mbyte(fdc201.iopb + 1); //Diskette Instruction
nr = get_mbyte(fdc201.iopb + 2); //Number of Records
ta = get_mbyte(fdc201.iopb + 3); //Track Address
sa = get_mbyte(fdc201.iopb + 4) & 0x1f; //Sector Address - without bank/fddnum
ba = get_mbyte(fdc201.iopb + 5);
ba |= (get_mbyte(fdc201.iopb + 6) << 8); //Buffer Address
bn = get_mbyte(fdc201.iopb + 7); //Block Number
ni = get_mbyte(fdc201.iopb + 8);
ni |= (get_mbyte(fdc201.iopb + 9) << 8);
fddnum = (di & 0x10) >> 4;
uptr = isbc201_dev.units + fddnum;
fbuf = (uint8 *) (isbc201_dev.units + fddnum)->filebuf;
ni |= (get_mbyte(fdc201.iopb + 9) << 8); //Next IOPB Address
fddnum = (di & 0x10) >> 4; //Floppy Disk Number
uptr = isbc201_dev.units + fddnum; //Unit Pointer
fbuf = (uint8 *) uptr->filebuf; //File Buffer
if (fdc201.verb)
sim_printf("\n SBC201: FDD %d - nr=%02XH ta=%02XH sa=%02XH IOPB=%04XH PCX=%04XH",
fddnum, nr, ta, sa, fdc201.iopb, PCX);
//check for not ready
switch(fddnum) {
case 0:
if ((fdc201.stat & RDY0) == 0) {
fdc201.rtype = ROK;
fdc201.rbyte0 = RB0NR;
fdc201.intff = 1; //set interrupt FF
fdc201.intff = 1; //set interrupt FF
sim_printf("\n SBC201: FDD %d - Ready error", fddnum);
return;
}
@@ -624,7 +645,7 @@ void isbc201_diskio(void)
if ((fdc201.stat & RDY1) == 0) {
fdc201.rtype = ROK;
fdc201.rbyte0 = RB0NR;
fdc201.intff = 1; //set interrupt FF
fdc201.intff = 1; //set interrupt FF
sim_printf("\n SBC201: FDD %d - Ready error", fddnum);
return;
}
@@ -632,7 +653,7 @@ void isbc201_diskio(void)
}
//check for address error
if (
((di & 0x07) != DHOME) && (
((di & 0x07) != DHOME) && ( //this is not in manual
(sa > MAXSECSD) ||
((sa + nr) > (MAXSECSD + 1)) ||
(sa == 0) ||
@@ -640,60 +661,61 @@ void isbc201_diskio(void)
)) {
fdc201.rtype = ROK;
fdc201.rbyte0 = RB0ADR;
fdc201.intff = 1; //set interrupt FF
sim_printf("\n SBC201: FDD %d - Address error at %04X", fddnum, PCX);
fdc201.intff = 1; //set interrupt FF
sim_printf("\n SBC201: FDD %d - Address error nr=%02XH ta=%02XH sa=%02XH IOPB=%04XH PCX=%04XH",
fddnum, nr, ta, sa, fdc201.iopb, PCX);
return;
}
switch (di & 0x07) {
case DNOP:
fdc201.rtype = ROK;
fdc201.rbyte0 = 0;
fdc201.intff = 1; //set interrupt FF
fdc201.rbyte0 = 0; //set no error
fdc201.intff = 1; //set interrupt FF
break;
case DSEEK:
fdc201.fdd[fddnum].sec = sa;
fdc201.fdd[fddnum].cyl = ta;
fdc201.rtype = ROK;
fdc201.rbyte0 = 0;
fdc201.intff = 1; //set interrupt FF
fdc201.rbyte0 = 0; //set no error
fdc201.intff = 1; //set interrupt FF
break;
case DHOME:
fdc201.fdd[fddnum].sec = sa;
fdc201.fdd[fddnum].cyl = 0;
fdc201.rtype = ROK;
fdc201.rbyte0 = 0;
fdc201.intff = 1; //set interrupt FF
fdc201.rbyte0 = 0; //set no error
fdc201.intff = 1; //set interrupt FF
break;
case DVCRC:
fdc201.rtype = ROK;
fdc201.rbyte0 = 0;
fdc201.intff = 1; //set interrupt FF
fdc201.intff = 1; //set interrupt FF
break;
case DFMT:
//check for WP
if(uptr->flags & UNIT_WPMODE) {
fdc201.rtype = ROK;
fdc201.rbyte0 = RB0WP;
fdc201.intff = 1; //set interrupt FF
sim_printf("\n SBC201: FDD %d - Write protect error 1", fddnum);
fdc201.intff = 1; //set interrupt FF
sim_printf("\n SBC201: FDD %d - Write protect error DFMT", fddnum);
return;
}
fmtb = get_mbyte(ba); //get the format byte
fmtb = get_mbyte(ba); //get the format byte
//calculate offset into disk image
dskoff = ((ta * MAXSECSD) + (sa - 1)) * SECSIZ;
for(i=0; i<=((uint32)(MAXSECSD) * SECSIZ); i++) {
*(fbuf + (dskoff + i)) = fmtb;
}
fdc201.rtype = ROK;
fdc201.rbyte0 = 0;
fdc201.intff = 1; //set interrupt FF
fdc201.rbyte0 = 0; //set no error
fdc201.intff = 1; //set interrupt FF
break;
case DREAD:
nrptr = 0;
while(nrptr < nr) {
//calculate offset into disk image
dskoff = ((ta * MAXSECSD) + (sa - 1)) * SECSIZ;
//copy sector from image to RAM
//copy sector from disk image to RAM
for (i=0; i<SECSIZ; i++) {
data = *(fbuf + (dskoff + i));
put_mbyte(ba + i, data);
@@ -703,23 +725,24 @@ void isbc201_diskio(void)
nrptr++;
}
fdc201.rtype = ROK;
fdc201.rbyte0 = 0;
fdc201.intff = 1; //set interrupt FF
fdc201.rbyte0 = 0; //set no error
fdc201.intff = 1; //set interrupt FF
break;
case DWRITE:
//check for WP
if(uptr->flags & UNIT_WPMODE) {
fdc201.rtype = ROK;
fdc201.rbyte0 = RB0WP;
fdc201.intff = 1; //set interrupt FF
sim_printf("\n SBC201: FDD %d - Write protect error 2", fddnum);
fdc201.intff = 1; //set interrupt FF
sim_printf("\n SBC201: FDD %d - Write protect error DWRITE", fddnum);
return;
}
nrptr = 0;
while(nrptr < nr) {
//calculate offset into disk image
dskoff = ((ta * MAXSECSD) + (sa - 1)) * SECSIZ;
for (i=0; i<SECSIZ; i++) { //copy sector from image to RAM
//copy sector from RAM to disk image
for (i=0; i<SECSIZ; i++) {
data = get_mbyte(ba + i);
*(fbuf + (dskoff + i)) = data;
}
@@ -728,15 +751,14 @@ void isbc201_diskio(void)
nrptr++;
}
fdc201.rtype = ROK;
fdc201.rbyte0 = 0;
fdc201.intff = 1; //set interrupt FF
fdc201.rbyte0 = 0; //set no error
fdc201.intff = 1; //set interrupt FF
break;
default:
sim_printf("\n SBC201: FDD %d - isbc201_diskio bad di=%02X", fddnum, di & 0x07);
sim_printf("\n SBC201: FDD %d - isbc201_diskio bad di=%02X",
fddnum, di & 0x07);
break;
}
}
#endif /* SBC201_NUM > 0 */
/* end of isbc201.c */

View File

@@ -145,15 +145,13 @@
#include "system_defs.h" /* system header in system dir */
#if defined (SBC202_NUM) && (SBC202_NUM > 0)
#define UNIT_V_WPMODE (UNIT_V_UF) /* Write protect */
#define UNIT_WPMODE (1 << UNIT_V_WPMODE)
#define FDD_NUM 4
#define SECSIZ 128
//disk controoler operations
//disk controller operations
#define DNOP 0x00 //disk no operation
#define DSEEK 0x01 //disk seek
#define DFMT 0x02 //disk format
@@ -204,13 +202,15 @@ extern uint16 PCX;
/* external function prototypes */
extern uint8 reg_dev(uint8 (*routine)(t_bool, uint8, uint8), uint8, uint8);
extern uint8 unreg_dev(uint8);
extern uint8 reg_dev(uint8 (*routine)(t_bool, uint8, uint8), uint16, uint16, uint8);
extern uint8 unreg_dev(uint16);
extern uint8 get_mbyte(uint16 addr);
extern void put_mbyte(uint16 addr, uint8 val);
/* function prototypes */
t_stat isbc202_cfg(uint16 base, uint16 size, uint8 devnum);
t_stat isbc202_clr(void);
t_stat isbc202_set_port(UNIT *uptr, int32 val, CONST char *cptr, void *desc);
t_stat isbc202_set_int(UNIT *uptr, int32 val, CONST char *cptr, void *desc);
t_stat isbc202_set_verb(UNIT *uptr, int32 val, CONST char *cptr, void *desc);
@@ -229,7 +229,6 @@ void isbc202_diskio(void); //do actual disk i/o
/* globals */
int isbc202_onetime = 1;
static const char* isbc202_desc(DEVICE *dptr) {
return isbc202_NAME;
}
@@ -237,6 +236,7 @@ static const char* isbc202_desc(DEVICE *dptr) {
typedef struct { //FDD definition
uint8 sec;
uint8 cyl;
uint8 att;
} FDDDEF;
typedef struct { //FDC definition
@@ -258,10 +258,10 @@ FDCDEF fdc202; //indexed by the isbc-202 instance numbe
/* isbc202 Standard I/O Data Structures */
UNIT isbc202_unit[] = { // 4 FDDs
{ UDATA (0, UNIT_ATTABLE+UNIT_DISABLE+UNIT_BUFABLE+UNIT_MUSTBUF+UNIT_FIX, MDSDD) },
{ UDATA (0, UNIT_ATTABLE+UNIT_DISABLE+UNIT_BUFABLE+UNIT_MUSTBUF+UNIT_FIX, MDSDD) },
{ UDATA (0, UNIT_ATTABLE+UNIT_DISABLE+UNIT_BUFABLE+UNIT_MUSTBUF+UNIT_FIX, MDSDD) },
{ UDATA (0, UNIT_ATTABLE+UNIT_DISABLE+UNIT_BUFABLE+UNIT_MUSTBUF+UNIT_FIX, MDSDD) },
{ UDATA (0, UNIT_ATTABLE+UNIT_DISABLE+UNIT_ROABLE+UNIT_RO+UNIT_BUFABLE+UNIT_MUSTBUF+UNIT_FIX, MDSDD) },
{ UDATA (0, UNIT_ATTABLE+UNIT_DISABLE+UNIT_ROABLE+UNIT_RO+UNIT_BUFABLE+UNIT_MUSTBUF+UNIT_FIX, MDSDD) },
{ UDATA (0, UNIT_ATTABLE+UNIT_DISABLE+UNIT_ROABLE+UNIT_RO+UNIT_BUFABLE+UNIT_MUSTBUF+UNIT_FIX, MDSDD) },
{ UDATA (0, UNIT_ATTABLE+UNIT_DISABLE+UNIT_ROABLE+UNIT_RO+UNIT_BUFABLE+UNIT_MUSTBUF+UNIT_FIX, MDSDD) },
{ NULL }
};
@@ -330,6 +330,48 @@ DEVICE isbc202_dev = {
&isbc202_desc //device description
};
// isbc 202 configuration
t_stat isbc202_cfg(uint16 baseport, uint16 devnum, uint8 intnum)
{
int i;
UNIT *uptr;
// one-time initialization for all FDDs for this FDC instance
for (i = 0; i < FDD_NUM; i++) {
uptr = isbc202_dev.units + i;
uptr->u6 = i; //fdd unit number
uptr->flags &= ~UNIT_ATT;
}
fdc202.baseport = baseport & 0xff; //set port
fdc202.intnum = intnum; //set interrupt
fdc202.verb = 0; //clear verb
reg_dev(isbc202r0, fdc202.baseport, 0, 0); //read status
reg_dev(isbc202r1, fdc202.baseport + 1, 0, 0); //read rslt type/write IOPB addr-l
reg_dev(isbc202r2, fdc202.baseport + 2, 0, 0); //write IOPB addr-h and start
reg_dev(isbc202r3, fdc202.baseport + 3, 0, 0); //read rstl byte
reg_dev(isbc202r7, fdc202.baseport + 7, 0, 0); //write reset fdc201
isbc202_reset_dev(); //software reset
// if (fdc202.verb)
sim_printf(" sbc202: Enabled base port at 0%02XH, Interrupt #=%02X, %s\n",
fdc202.baseport, fdc202.intnum, fdc202.verb ? "Verbose" : "Quiet" );
return SCPE_OK;
}
t_stat isbc202_clr(void)
{
fdc202.intnum = -1; //set default interrupt
fdc202.verb = 0; //set verb = 0
unreg_dev(fdc202.baseport); //read status
unreg_dev(fdc202.baseport + 1); //read rslt type/write IOPB addr-l
unreg_dev(fdc202.baseport + 2); //write IOPB addr-h and start
unreg_dev(fdc202.baseport + 3); //read rstl byte
unreg_dev(fdc202.baseport + 7); //write reset fdc201
// if (fdc202.verb)
sim_printf(" sbc202: Disabled\n");
return SCPE_OK;
}
/* isbc202 set mode = Write protect */
t_stat isbc202_set_mode (UNIT *uptr, int32 val, CONST char *cptr, void *desc)
@@ -337,21 +379,21 @@ t_stat isbc202_set_mode (UNIT *uptr, int32 val, CONST char *cptr, void *desc)
if (uptr == NULL)
return SCPE_ARG;
if (uptr->flags & UNIT_ATT)
return sim_messagef (SCPE_ALATT, "%s is already attached to %s\n", sim_uname(uptr),
uptr->filename);
return sim_messagef (SCPE_ALATT, "%s is already attached to %s\n",
sim_uname(uptr), uptr->filename);
if (val & UNIT_WPMODE) { /* write protect */
uptr->flags |= val;
if (fdc202.verb)
sim_printf(" sbc202: WP\n");
// if (fdc202.verb)
sim_printf(" SBC202: WP\n");
} else { /* read write */
uptr->flags &= ~val;
if (fdc202.verb)
sim_printf(" sbc202: RW\n");
// if (fdc202.verb)
sim_printf(" SBC202: RW\n");
}
return SCPE_OK;
}
// set base address parameter
// set base port address parameter
t_stat isbc202_set_port(UNIT *uptr, int32 val, CONST char *cptr, void *desc)
{
@@ -361,8 +403,13 @@ t_stat isbc202_set_port(UNIT *uptr, int32 val, CONST char *cptr, void *desc)
return SCPE_ARG;
result = sscanf(cptr, "%02x", &size);
fdc202.baseport = size;
if (fdc202.verb)
sim_printf("SBC202: Base port=%04X\n", fdc202.baseport);
// if (fdc202.verb)
sim_printf("SBC202: Installed at base port=%04X\n", fdc202.baseport);
reg_dev(isbc202r0, fdc202.baseport, 0, 0); //read status
reg_dev(isbc202r1, fdc202.baseport + 1, 0, 0); //read rslt type/write IOPB addr-l
reg_dev(isbc202r2, fdc202.baseport + 2, 0, 0); //write IOPB addr-h and start
reg_dev(isbc202r3, fdc202.baseport + 3, 0, 0); //read rstl byte
reg_dev(isbc202r7, fdc202.baseport + 7, 0, 0); //write reset fdc201
return SCPE_OK;
}
@@ -376,10 +423,11 @@ t_stat isbc202_set_int(UNIT *uptr, int32 val, CONST char *cptr, void *desc)
return SCPE_ARG;
result = sscanf(cptr, "%02x", &size);
fdc202.intnum = size;
if (fdc202.verb)
// if (fdc202.verb)
sim_printf("SBC202: Interrupt number=%04X\n", fdc202.intnum);
return SCPE_OK;
}
// set verbose mode
t_stat isbc202_set_verb(UNIT *uptr, int32 val, CONST char *cptr, void *desc)
{
@@ -393,7 +441,6 @@ t_stat isbc202_set_verb(UNIT *uptr, int32 val, CONST char *cptr, void *desc)
}
if (strncasecmp(cptr, "ON", 3) == 0) {
fdc202.verb = 1;
sim_printf(" SBC202: fdc202.verb=%d\n", fdc202.verb);
return SCPE_OK;
}
return SCPE_ARG;
@@ -403,6 +450,8 @@ t_stat isbc202_set_verb(UNIT *uptr, int32 val, CONST char *cptr, void *desc)
t_stat isbc202_show_param (FILE *st, UNIT *uptr, int32 val, CONST void *desc)
{
int i = 0;
if (uptr == NULL)
return SCPE_ARG;
fprintf(st, "%s Base port at %04X Interrupt # is %i %s",
@@ -417,41 +466,9 @@ t_stat isbc202_show_param (FILE *st, UNIT *uptr, int32 val, CONST void *desc)
t_stat isbc202_reset(DEVICE *dptr)
{
int i;
UNIT *uptr;
if (dptr == NULL)
return SCPE_ARG;
if (isbc202_onetime) {
fdc202.baseport = SBC202_BASE; //set default base
fdc202.intnum = SBC202_INT; //set default interrupt
fdc202.verb = 0; //set verb = off
isbc202_onetime = 0;
// one-time initialization for all FDDs for this FDC instance
for (i = 0; i < FDD_NUM; i++) {
uptr = isbc202_dev.units + i;
uptr->u6 = i; //fdd unit number
}
}
if ((dptr->flags & DEV_DIS) == 0) { // enabled
reg_dev(isbc202r0, fdc202.baseport, 0); //read status
reg_dev(isbc202r1, fdc202.baseport + 1, 0); //read rslt type/write IOPB addr-l
reg_dev(isbc202r2, fdc202.baseport + 2, 0); //write IOPB addr-h and start
reg_dev(isbc202r3, fdc202.baseport + 3, 0); //read rstl byte
reg_dev(isbc202r7, fdc202.baseport + 7, 0); //write reset fdc201
isbc202_reset_dev(); //software reset
// if (fdc202.verb)
sim_printf(" sbc202: Enabled base port at 0%02XH Interrupt #=%02X %s\n",
fdc202.baseport, fdc202.intnum, fdc202.verb ? "Verbose" : "Quiet" );
} else {
unreg_dev(fdc202.baseport); //read status
unreg_dev(fdc202.baseport + 1); //read rslt type/write IOPB addr-l
unreg_dev(fdc202.baseport + 2); //write IOPB addr-h and start
unreg_dev(fdc202.baseport + 3); //read rstl byte
unreg_dev(fdc202.baseport + 7); //write reset fdc201
// if (fdc202.verb)
sim_printf(" sbc202: Disabled\n");
}
isbc202_reset_dev(); //software reset
return SCPE_OK;
}
@@ -462,13 +479,13 @@ void isbc202_reset_dev(void)
int32 i;
UNIT *uptr;
fdc202.stat = 0; //clear status
fdc202.stat = 0; //clear status
for (i = 0; i < FDD_NUM; i++) { /* handle all units */
uptr = isbc202_dev.units + i;
fdc202.stat |= FDCPRE | FDCDD; //set the FDC status
fdc202.stat |= FDCPRE | FDCDD; //set the FDC status
fdc202.rtype = ROK;
fdc202.rbyte0 = 0; //set no error
if (uptr->flags & UNIT_ATT) { /* if attached */
if (uptr->flags & UNIT_ATT) { /* if attached */
switch(i){
case 0:
fdc202.stat |= RDY0; //set FDD 0 ready
@@ -499,31 +516,31 @@ t_stat isbc202_attach (UNIT *uptr, CONST char *cptr)
t_stat r;
uint8 fddnum;
fddnum = uptr->u6;
if ((r = attach_unit (uptr, cptr)) != SCPE_OK) {
sim_printf(" isbc202_attach: Attach error %d\n", r);
return r;
}
fddnum = uptr->u6;
switch(fddnum){
case 0:
fdc202.stat |= RDY0; //set FDD 0 ready
fdc202.stat |= RDY0; //set FDD 0 ready
fdc202.rbyte1 |= RB1RD0;
break;
case 1:
fdc202.stat |= RDY1; //set FDD 1 ready
fdc202.stat |= RDY1; //set FDD 1 ready
fdc202.rbyte1 |= RB1RD1;
break;
case 2:
fdc202.stat |= RDY2; //set FDD 2 ready
fdc202.stat |= RDY2; //set FDD 2 ready
fdc202.rbyte1 |= RB1RD2;
break;
case 3:
fdc202.stat |= RDY3; //set FDD 3 ready
fdc202.stat |= RDY3; //set FDD 3 ready
fdc202.rbyte1 |= RB1RD3;
break;
}
fdc202.rtype = ROK;
fdc202.rbyte0 = 0; //set no error
fdc202.rbyte0 = 0; //set no error
return SCPE_OK;
}
@@ -531,7 +548,7 @@ t_stat isbc202_attach (UNIT *uptr, CONST char *cptr)
uint8 isbc202r0(t_bool io, uint8 data, uint8 devnum)
{
if (io == 0) { /* read ststus*/
if (io == 0) { /* read ststus*/
return fdc202.stat;
}
return 0;
@@ -539,12 +556,12 @@ uint8 isbc202r0(t_bool io, uint8 data, uint8 devnum)
uint8 isbc202r1(t_bool io, uint8 data, uint8 devnum)
{
if (io == 0) { /* read data port */
fdc202.intff = 0; //clear interrupt FF
if (io == 0) { /* read data port */
fdc202.intff = 0; //clear interrupt FF
fdc202.stat &= ~FDCINT;
fdc202.rtype = ROK;
return fdc202.rtype;
} else { /* write data port */
} else { /* write data port */
fdc202.iopb = data;
}
return 0;
@@ -552,9 +569,9 @@ uint8 isbc202r1(t_bool io, uint8 data, uint8 devnum)
uint8 isbc202r2(t_bool io, uint8 data, uint8 devnum)
{
if (io == 0) { /* read data port */
if (io == 0) { /* read data port */
;
} else { /* write data port */
} else { /* write data port */
fdc202.iopb |= (data << 8);
isbc202_diskio();
if (fdc202.intff)
@@ -565,7 +582,7 @@ uint8 isbc202r2(t_bool io, uint8 data, uint8 devnum)
uint8 isbc202r3(t_bool io, uint8 data, uint8 devnum)
{
if (io == 0) { /* read data port */
if (io == 0) { /* read data port */
if (fdc202.rtype == ROK) {
return fdc202.rbyte0;
} else {
@@ -575,7 +592,7 @@ uint8 isbc202r3(t_bool io, uint8 data, uint8 devnum)
return fdc202.rbyte0;
}
}
} else { /* write data port */
} else { /* write data port */
; //stop diskette operation
}
return 0;
@@ -583,9 +600,9 @@ uint8 isbc202r3(t_bool io, uint8 data, uint8 devnum)
uint8 isbc202r7(t_bool io, uint8 data, uint8 devnum)
{
if (io == 0) { /* read data port */
if (io == 0) { /* read data port */
;
} else { /* write data port */
} else { /* write data port */
isbc202_reset_dev();
}
return 0;
@@ -615,21 +632,20 @@ void isbc202_diskio(void)
uptr = isbc202_dev.units + fddnum;
fbuf = (uint8 *) uptr->filebuf;
//check for not ready
switch(fddnum) {
switch(fddnum) {
case 0:
if ((fdc202.stat & RDY0) == 0) {
fdc202.rtype = ROK;
fdc202.rbyte0 = RB0NR;
fdc202.intff = 1; //set interrupt FF
fdc202.intff = 1; //set interrupt FF
sim_printf("\n SBC202: FDD %d - Ready error", fddnum);
return;
}
break;
case 1:
if ((fdc202.stat & RDY1) == 0) {
fdc202.rtype = ROK;
fdc202.rbyte0 = RB0NR;
fdc202.intff = 1; //set interrupt FF
fdc202.intff = 1; //set interrupt FF
sim_printf("\n SBC202: FDD %d - Ready error", fddnum);
return;
}
@@ -638,7 +654,7 @@ void isbc202_diskio(void)
if ((fdc202.stat & RDY2) == 0) {
fdc202.rtype = ROK;
fdc202.rbyte0 = RB0NR;
fdc202.intff = 1; //set interrupt FF
fdc202.intff = 1; //set interrupt FF
sim_printf("\n SBC202: FDD %d - Ready error", fddnum);
return;
}
@@ -647,7 +663,7 @@ void isbc202_diskio(void)
if ((fdc202.stat & RDY3) == 0) {
fdc202.rtype = ROK;
fdc202.rbyte0 = RB0NR;
fdc202.intff = 1; //set interrupt FF
fdc202.intff = 1; //set interrupt FF
sim_printf("\n SBC202: FDD %d - Ready error", fddnum);
return;
}
@@ -655,7 +671,7 @@ void isbc202_diskio(void)
}
//check for address error
if (
((di & 0x07) != DHOME) && (
((di & 0x07) != DHOME) && ( //this is not in manual
(sa > MAXSECDD) ||
((sa + nr) > (MAXSECDD + 1)) ||
(sa == 0) ||
@@ -663,10 +679,10 @@ void isbc202_diskio(void)
)) {
fdc202.rtype = ROK;
fdc202.rbyte0 = RB0ADR;
fdc202.intff = 1; //set interrupt FF
sim_printf("\n SBC202: FDD %d - Address error sa=%02X nr=%02X ta=%02X PCX=%04X",
fddnum, sa, nr, ta, PCX);
return;
fdc202.intff = 1; //set interrupt FF
sim_printf("\n SBC202: FDD %d - Address error nr=%02XH ta=%02XH sa=%02XH IOPB=%04XH PCX=%04XH",
fddnum, nr, ta, sa, fdc202.iopb, PCX);
return;
}
switch (di & 0x07) {
case DNOP:
@@ -702,7 +718,7 @@ void isbc202_diskio(void)
sim_printf("\n SBC202: FDD %d - Write protect error DFMT", fddnum);
return;
}
fmtb = get_mbyte(ba); //get the format byte
fmtb = get_mbyte(ba); //get the format byte
//calculate offset into disk image
dskoff = ((ta * MAXSECDD) + (sa - 1)) * SECSIZ;
for(i=0; i<=((uint32)(MAXSECDD) * SECSIZ); i++) {
@@ -763,6 +779,4 @@ void isbc202_diskio(void)
}
}
#endif /* SBC202_NUM > 0 */
/* end of isbc202.c */

View File

@@ -29,7 +29,7 @@
NOTES:
This controller will mount 1 Hard Disk removable and three Hard Disk fixed disk
This controller will mount 1 removable Hard Disk (IBM 2315)and three Hard Disk fixed disk
images on drives :F0: thru :F3: addressed at ports 068H to 06FH.
Registers:
@@ -128,7 +128,7 @@
#include "system_defs.h" /* system header in system dir */
#if defined (SBC206_NUM) && (SBC206_NUM > 0)
//#if defined (SBC206_NUM) && (SBC206_NUM > 0)
#define UNIT_V_WPMODE (UNIT_V_UF) /* Write protect */
#define UNIT_WPMODE (1 << UNIT_V_WPMODE)
@@ -170,7 +170,7 @@
#define RB1RD1 0x80 //drive 1 ready
//disk geometry values
#define MDSHD 3796992 //hard disk HD size
#define MDSHD 3796992 //hard disk size MB
#define MAXSECHD 144 //hard disk last sector (2 heads/2 tracks)
#define MAXTRKHD 206 //hard disk last track
@@ -182,13 +182,15 @@ extern uint16 PCX;
/* external function prototypes */
extern uint8 reg_dev(uint8 (*routine)(t_bool, uint8, uint8), uint8, uint8);
extern uint8 unreg_dev(uint8);
extern uint8 reg_dev(uint8 (*routine)(t_bool, uint8, uint8), uint16, uint16, uint8);
extern uint8 unreg_dev(uint16 port);
extern uint8 get_mbyte(uint16 addr);
extern void put_mbyte(uint16 addr, uint8 val);
/* function prototypes */
t_stat isbc206_cfg(uint16 base, uint16 size, uint8 devnum);
t_stat isbc206_clr(void);
t_stat isbc206_set_port(UNIT *uptr, int32 val, CONST char *cptr, void *desc);
t_stat isbc206_set_int(UNIT *uptr, int32 val, CONST char *cptr, void *desc);
t_stat isbc206_set_verb(UNIT *uptr, int32 val, CONST char *cptr, void *desc);
@@ -207,10 +209,10 @@ void isbc206_diskio(void); //do actual disk i/o
/* globals */
int isbc206_onetime = 1;
static const char* isbc206_desc(DEVICE *dptr) {
return isbc206_NAME;
}
typedef struct { //HDD definition
int t0;
int rdy;
@@ -219,7 +221,7 @@ typedef struct { //HDD definition
} HDDDEF;
typedef struct { //HDC definition
uint8 baseport; //HDC base port
uint8 baseport; //HDC base port
uint8 intnum; //interrupt number
uint8 verb; //verbose flag
uint16 iopb; //HDC IOPB
@@ -236,8 +238,8 @@ HDCDEF hdc206; //indexed by the isbc-206 instance numbe
UNIT isbc206_unit[] = { // 2 HDDs
{ UDATA (0, UNIT_ATTABLE+UNIT_DISABLE+UNIT_BUFABLE+UNIT_MUSTBUF|UNIT_FIX, MDSHD) },
{ UDATA (0, UNIT_ATTABLE+UNIT_DISABLE+UNIT_BUFABLE+UNIT_MUSTBUF|UNIT_FIX, MDSHD) },
{ UDATA (0, UNIT_ATTABLE+UNIT_DISABLE+UNIT_ROABLE+UNIT_RO+UNIT_BUFABLE+UNIT_MUSTBUF+UNIT_FIX, MDSHD) },
{ UDATA (0, UNIT_ATTABLE+UNIT_DISABLE+UNIT_ROABLE+UNIT_RO+UNIT_BUFABLE+UNIT_MUSTBUF+UNIT_FIX, MDSHD) },
{ NULL }
};
@@ -278,7 +280,7 @@ DEBTAB isbc206_debug[] = {
/* address width is set to 16 bits to use devices in 8086/8088 implementations */
DEVICE isbc206_dev = {
"SBC206", //name
"SBC206", //name
isbc206_unit, //units
isbc206_reg, //registers
isbc206_mod, //modifiers
@@ -299,9 +301,56 @@ DEVICE isbc206_dev = {
0, //dctrl
isbc206_debug, //debflags
NULL, //msize
NULL //lname
NULL, //lname
NULL, //help routine
NULL, //attach help routine
NULL, //help context
&isbc206_desc //device description
};
// iSBC 201 configuration
t_stat isbc206_cfg(uint16 baseport, uint16 devnum, uint8 intnum)
{
int i;
UNIT *uptr;
// one-time initialization for all FDDs for this FDC instance
for (i = 0; i < HDD_NUM; i++) {
uptr = isbc206_dev.units + i;
uptr->u6 = i; //fdd unit number
}
hdc206.baseport = baseport & 0xff; //set port
hdc206.intnum = intnum; //set interrupt
hdc206.verb = 0; //clear verb
reg_dev(isbc206r0, hdc206.baseport, 0, 0); //read status
reg_dev(isbc206r1, hdc206.baseport + 1, 0, 0); //read rslt type/write IOPB addr-l
reg_dev(isbc206r2, hdc206.baseport + 2, 0, 0); //write IOPB addr-h and start
reg_dev(isbc206r3, hdc206.baseport + 3, 0, 0); //read rstl byte
reg_dev(isbc206r7, hdc206.baseport + 7, 0, 0); //write reset fdc201
isbc206_reset_dev(); //software reset
// if (hdc206.verb)
sim_printf(" sbc206: Enabled base port at 0%02XH, Interrupt #=%02X, %s\n",
hdc206.baseport, hdc206.intnum, hdc206.verb ? "Verbose" : "Quiet" );
return SCPE_OK;
}
// iSBC 201 deconfiguration
t_stat isbc206_clr(void)
{
hdc206.intnum = -1; //set default interrupt
hdc206.verb = 0; //set verb = 0
unreg_dev(hdc206.baseport); //read status
unreg_dev(hdc206.baseport + 1); //read rslt type/write IOPB addr-l
unreg_dev(hdc206.baseport + 2); //write IOPB addr-h and start
unreg_dev(hdc206.baseport + 3); //read rstl byte
unreg_dev(hdc206.baseport + 7); //write reset fdc201
// if (hdc206.verb)
sim_printf(" sbc206: Disabled\n");
return SCPE_OK;
}
/* isbc206 set mode = Write protect */
t_stat isbc206_set_mode (UNIT *uptr, int32 val, CONST char *cptr, void *desc)
@@ -388,41 +437,9 @@ t_stat isbc206_show_param (FILE *st, UNIT *uptr, int32 val, CONST void *desc)
t_stat isbc206_reset(DEVICE *dptr)
{
int i;
UNIT *uptr;
if (dptr == NULL)
return SCPE_ARG;
if (isbc206_onetime) {
hdc206.baseport = SBC206_BASE; //set default base
hdc206.intnum = SBC206_INT; //set default interrupt
hdc206.verb = 0; //set verb = 0
isbc206_onetime = 0;
// one-time initialization for all FDDs for this FDC instance
for (i = 0; i < HDD_NUM; i++) {
uptr = isbc206_dev.units + i;
uptr->u6 = i; //fdd unit number
}
}
if ((dptr->flags & DEV_DIS) == 0) { // enabled
reg_dev(isbc206r0, hdc206.baseport, 0); //read status
reg_dev(isbc206r1, hdc206.baseport + 1, 0); //read rslt type/write IOPB addr-l
reg_dev(isbc206r2, hdc206.baseport + 2, 0); //write IOPB addr-h and start
reg_dev(isbc206r3, hdc206.baseport + 3, 0); //read rstl byte
reg_dev(isbc206r7, hdc206.baseport + 7, 0); //write reset fdc201
isbc206_reset_dev(); //software reset
if (hdc206.verb)
sim_printf(" sbc206: Enabled base port at 0%02XH Interrupt #=%02X %s\n",
hdc206.baseport, hdc206.intnum, hdc206.verb ? "Verbose" : "Quiet" );
} else {
unreg_dev(hdc206.baseport); //read status
unreg_dev(hdc206.baseport + 1); //read rslt type/write IOPB addr-l
unreg_dev(hdc206.baseport + 2); //write IOPB addr-h and start
unreg_dev(hdc206.baseport + 3); //read rstl byte
unreg_dev(hdc206.baseport + 7); //write reset fdc201
if (hdc206.verb)
sim_printf(" sbc206: Disabled\n");
}
isbc206_reset_dev(); //software reset
return SCPE_OK;
}
@@ -601,7 +618,7 @@ void isbc206_diskio(void)
hdc206.rtype = ROK;
hdc206.rbyte0 = RB0ADR;
hdc206.intff = 1; //set interrupt FF
sim_printf("\n SBC206: FDD %d - Address error sa=%02X nr=%02X ta=%02X PCX=%04X",
sim_printf("\n SBC206: HDD %d - Address error sa=%02X nr=%02X ta=%02X PCX=%04X",
hddnum, sa, nr, ta, PCX);
return;
}
@@ -699,6 +716,6 @@ void isbc206_diskio(void)
}
}
#endif /* SBC206_NUM > 0 */
//#endif /* SBC206_NUM > 0 */
/* end of isbc206.c */

View File

@@ -27,7 +27,7 @@
MODIFICATIONS:
?? ??? 11 - 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:
@@ -84,17 +84,17 @@
Read/Write DMAC Address Registers
Used to simultaneously load a channel's current-address register and base-address
Used to simultaneously load a channel's current-address register and baseport-address
register with the memory address of the first byte to be transferred. (The Channel
0 current/base address register must be loaded prior to initiating a diskette read
0 current/baseport address register must be loaded prior to initiating a diskette read
or write operation.) Since each channel's address registers are 16 bits in length
(64K address range), two "write address register" commands must be executed in
order to load the complete current/base address registers for any channel.
order to load the complete current/baseport address registers for any channel.
Read/Write DMAC Word Count Registers
The Write DMAC Word Count Register command is used to simultaneously load a
channel's current and base word-count registers with the number of bytes
channel's current and baseport word-count registers with the number of bytes
to be transferred during a subsequent DMA operation. Since the word-count
registers are 16-bits in length, two commands must be executed to load both
halves of the registers.
@@ -397,8 +397,6 @@
#include "system_defs.h"
#if defined (SBC208_NUM) && (SBC208_NUM > 0)
#define UNIT_V_WPMODE (UNIT_V_UF) /* Write protect */
#define UNIT_WPMODE (1 << UNIT_V_WPMODE)
@@ -471,9 +469,12 @@
#define FDD_NUM 4
#define isbc208_NAME "Intel iSBC 208 Floppy Disk Controller Board"
/* internal function prototypes */
t_stat isbc208_cfg(uint8 base);
t_stat isbc208_cfg(uint16 baseport, uint16 size, uint8 devnum);
t_stat isbc208_clr(void);
t_stat isbc208_reset (DEVICE *dptr);
void isbc208_reset1 (void);
t_stat isbc208_attach (UNIT *uptr, const char *cptr);
@@ -506,7 +507,8 @@ uint8 isbc208_r15(t_bool io, uint8 data, uint8 devnum);
extern void set_irq(int32 int_num);
extern void clr_irq(int32 int_num);
extern uint8 reg_dev(uint8 (*routine)(t_bool, uint8, uint8), uint8, uint8);
extern uint8 reg_dev(uint8 (*routine)(t_bool, uint8, uint8), uint16, uint16, uint8);
extern uint8 unreg_dev(uint16);
extern void multibus_put_mbyte(uint16 addr, uint8 val);
extern int32 multibus_get_mbyte(uint16 addr);
@@ -514,6 +516,13 @@ extern int32 multibus_get_mbyte(uint16 addr);
extern uint16 PCX;
/* globals */
int isbc208_onetime = 1;
static const char* isbc208_desc(DEVICE *dptr) {
return isbc208_NAME;
}
/* 8237 physical register definitions */
uint16 i8237_r0; // 8237 ch 0 address register
uint16 i8237_r1; // 8237 ch 0 count register
@@ -662,46 +671,50 @@ DEVICE isbc208_dev = {
&isbc208_attach, //attach
NULL, //detach
NULL, //ctxt
DEV_DEBUG|DEV_DISABLE|DEV_DIS, //flags
DEV_DEBUG+DEV_DISABLE+DEV_DIS, //flags
0, //dctrl
isbc208_debug, //debflags
NULL, //msize
NULL //lname
NULL, //lname
NULL, //help routine
NULL, //attach help routine
NULL, //help context
&isbc208_desc //device description
};
/* Service routines to handle simulator functions */
// configuration routine
t_stat isbc208_cfg(uint8 base)
t_stat isbc208_cfg(uint16 baseport, uint16 devnum, uint8 intnum)
{
int32 i;
UNIT *uptr;
sim_printf(" sbc208: at base 0%02XH\n",
base);
reg_dev(isbc208_r0, base + 0, 0); //8237 registers
reg_dev(isbc208_r1, base + 1, 0);
reg_dev(isbc208_r2, base + 2, 0);
reg_dev(isbc208_r3, base + 3, 0);
reg_dev(isbc208_r4, base + 4, 0);
reg_dev(isbc208_r5, base + 5, 0);
reg_dev(isbc208_r6, base + 6, 0);
reg_dev(isbc208_r7, base + 7, 0);
reg_dev(isbc208_r8, base + 8, 0);
reg_dev(isbc208_r9, base + 9, 0);
reg_dev(isbc208_rA, base + 10, 0);
reg_dev(isbc208_rB, base + 11, 0);
reg_dev(isbc208_rC, base + 12, 0);
reg_dev(isbc208_rD, base + 13, 0);
reg_dev(isbc208_rE, base + 14, 0);
reg_dev(isbc208_rF, base + 15, 0);
reg_dev(isbc208_r10, base + 16, 0); //8272 registers
reg_dev(isbc208_r11, base + 17, 0);
reg_dev(isbc208_r12, base + 18, 0); //devices on iSBC 208
reg_dev(isbc208_r13, base + 19, 0);
reg_dev(isbc208_r14, base + 20, 0);
reg_dev(isbc208_r15, base + 21, 0);
sim_printf(" sbc208: at baseport 0%02XH\n",
baseport);
reg_dev(isbc208_r0, baseport + 0, 0, 0); //8237 registers
reg_dev(isbc208_r1, baseport + 1, 0, 0);
reg_dev(isbc208_r2, baseport + 2, 0, 0);
reg_dev(isbc208_r3, baseport + 3, 0, 0);
reg_dev(isbc208_r4, baseport + 4, 0, 0);
reg_dev(isbc208_r5, baseport + 5, 0, 0);
reg_dev(isbc208_r6, baseport + 6, 0, 0);
reg_dev(isbc208_r7, baseport + 7, 0, 0);
reg_dev(isbc208_r8, baseport + 8, 0, 0);
reg_dev(isbc208_r9, baseport + 9, 0, 0);
reg_dev(isbc208_rA, baseport + 10, 0, 0);
reg_dev(isbc208_rB, baseport + 11, 0, 0);
reg_dev(isbc208_rC, baseport + 12, 0, 0);
reg_dev(isbc208_rD, baseport + 13, 0, 0);
reg_dev(isbc208_rE, baseport + 14, 0, 0);
reg_dev(isbc208_rF, baseport + 15, 0, 0);
reg_dev(isbc208_r10, baseport + 16, 0, 0); //8272 registers
reg_dev(isbc208_r11, baseport + 17, 0, 0);
reg_dev(isbc208_r12, baseport + 18, 0, 0); //devices on iSBC 208
reg_dev(isbc208_r13, baseport + 19, 0, 0);
reg_dev(isbc208_r14, baseport + 20, 0, 0);
reg_dev(isbc208_r15, baseport + 21, 0, 0);
// one-time initialization for all FDDs
for (i = 0; i < FDD_NUM; i++) {
uptr = isbc208_dev.units + i;
@@ -715,6 +728,20 @@ t_stat isbc208_cfg(uint8 base)
return SCPE_OK;
}
t_stat isbc208_clr(void)
{
// fdc208.intnum = -1; //set default interrupt
// fdc208.verb = 0; //set verb = 0
// unreg_dev(fdc208.baseport); //read status
// unreg_dev(fdc208.baseport + 1); //read rslt type/write IOPB addr-l
// unreg_dev(fdc208.baseport + 2); //write IOPB addr-h and start
// unreg_dev(fdc208.baseport + 3); //read rstl byte
// unreg_dev(fdc208.baseport + 7); //write reset fdc201
// if (fdc202.verb)
sim_printf(" sbc208: Disabled\n");
return SCPE_OK;
}
/* Reset routine */
t_stat isbc208_reset (DEVICE *dptr)
@@ -1167,7 +1194,7 @@ uint8 isbc208_r0(t_bool io, uint8 data, uint8 devnum)
i8237_rD++;
return (i8237_r0 & 0xFF);
}
} else { /* write base & current address CH 0 */
} else { /* write baseport & current address CH 0 */
if (i8237_rD) { /* high byte */
i8237_rD = 0;
i8237_r0 |= (data << 8);
@@ -1189,7 +1216,7 @@ uint8 isbc208_r1(t_bool io, uint8 data, uint8 devnum)
i8237_rD++;
return (i8237_r1 & 0xFF);
}
} else { /* write base & current address CH 0 */
} else { /* write baseport & current address CH 0 */
if (i8237_rD) { /* high byte */
i8237_rD = 0;
i8237_r1 |= (data << 8);
@@ -1211,7 +1238,7 @@ uint8 isbc208_r2(t_bool io, uint8 data, uint8 devnum)
i8237_rD++;
return (i8237_r2 & 0xFF);
}
} else { /* write base & current address CH 1 */
} else { /* write baseport & current address CH 1 */
if (i8237_rD) { /* high byte */
i8237_rD = 0;
i8237_r2 |= (data << 8);
@@ -1233,7 +1260,7 @@ uint8 isbc208_r3(t_bool io, uint8 data, uint8 devnum)
i8237_rD++;
return (i8237_r3 & 0xFF);
}
} else { /* write base & current address CH 1 */
} else { /* write baseport & current address CH 1 */
if (i8237_rD) { /* high byte */
i8237_rD = 0;
i8237_r3 |= (data << 8);
@@ -1255,7 +1282,7 @@ uint8 isbc208_r4(t_bool io, uint8 data, uint8 devnum)
i8237_rD++;
return (i8237_r4 & 0xFF);
}
} else { /* write base & current address CH 2 */
} else { /* write baseport & current address CH 2 */
if (i8237_rD) { /* high byte */
i8237_rD = 0;
i8237_r4 |= (data << 8);
@@ -1277,7 +1304,7 @@ uint8 isbc208_r5(t_bool io, uint8 data, uint8 devnum)
i8237_rD++;
return (i8237_r5 & 0xFF);
}
} else { /* write base & current address CH 2 */
} else { /* write baseport & current address CH 2 */
if (i8237_rD) { /* high byte */
i8237_rD = 0;
i8237_r5 |= (data << 8);
@@ -1299,7 +1326,7 @@ uint8 isbc208_r6(t_bool io, uint8 data, uint8 devnum)
i8237_rD++;
return (i8237_r6 & 0xFF);
}
} else { /* write base & current address CH 3 */
} else { /* write baseport & current address CH 3 */
if (i8237_rD) { /* high byte */
i8237_rD = 0;
i8237_r6 |= (data << 8);
@@ -1321,7 +1348,7 @@ uint8 isbc208_r7(t_bool io, uint8 data, uint8 devnum)
i8237_rD++;
return (i8237_r7 & 0xFF);
}
} else { /* write base & current address CH 3 */
} else { /* write baseport & current address CH 3 */
if (i8237_rD) { /* high byte */
i8237_rD = 0;
i8237_r7 |= (data << 8);
@@ -1487,7 +1514,5 @@ uint8 isbc208_r15(t_bool io, uint8 data, uint8 devnum)
return 0;
}
}
#endif /* SBC208_NUM > 0 */
/* end of isbc208.c */

View File

@@ -28,17 +28,22 @@
29 Oct 17 - Original file.
NOTES:
TO DO:
Set up for actual ROM sizes 2708-...
*/
#include "system_defs.h"
#if defined (SBC464_NUM) && (SBC464_NUM > 0)
#define BASE_ADDR u3
#define isbc464_NAME "Intel iSBC 464 ROM Board"
/* prototypes */
t_stat isbc464_cfg(uint16 base, uint16 size, uint8 dummy);
t_stat isbc464_clr(void);
t_stat isbc464_set_base(UNIT *uptr, int32 val, CONST char *cptr, void *desc);
t_stat isbc464_set_size(UNIT *uptr, int32 val, CONST char *cptr, void *desc);
t_stat isbc464_show_param (FILE *st, UNIT *uptr, int32 val, CONST void *desc);
@@ -55,18 +60,20 @@ extern uint8 xack; /* XACK signal */
/* local globals */
int isbc464_onetime = 1;
static const char* isbc464_desc(DEVICE *dptr) {
return isbc464_NAME;
}
/* isbc464 Standard I/O Data Structures */
UNIT isbc464_unit = {
UDATA (NULL, UNIT_ATTABLE+UNIT_BINK+UNIT_ROABLE+UNIT_RO+UNIT_BUFABLE+
UNIT_MUSTBUF, 0)
UDATA (NULL, UNIT_ATTABLE+UNIT_BINK+UNIT_ROABLE+UNIT_RO+UNIT_BUFABLE+UNIT_MUSTBUF, 0)
};
MTAB isbc464_mod[] = {
{ MTAB_XTD | MTAB_VDV, 0, NULL, "SIZE", &isbc464_set_size,
NULL, NULL, "Sets the ROM size for iSBC464" },
{ MTAB_XTD | MTAB_VDV, 0, NULL, "BASE", &isbc464_set_base,
{ MTAB_XTD | MTAB_VDV, 0, NULL, "BASE", &isbc464_set_base,
NULL, NULL, "Sets the ROM base for iSBC464" },
{ MTAB_XTD|MTAB_VDV, 0, "PARAM", NULL, NULL, &isbc464_show_param, NULL,
"Parameter" },
@@ -88,7 +95,7 @@ DEVICE isbc464_dev = {
"SBC464", //name
&isbc464_unit, //units
NULL, //registers
isbc464_mod, //modifiers
isbc464_mod, //modifiers
1, //numunits
16, //aradix
16, //awidth
@@ -102,15 +109,43 @@ DEVICE isbc464_dev = {
isbc464_attach, //attach
NULL, //detach
NULL, //ctxt
DEV_DISABLE+DEV_DIS, //flags
DEV_DEBUG+DEV_DISABLE+DEV_DIS, //flags
0, //dctrl
isbc464_debug, //debflags
NULL, //msize
NULL //lname
NULL, //lname
NULL, //help routine
NULL, //attach help routine
NULL, //help context
&isbc464_desc //device description
};
/* isbc464 globals */
// isbc464 configuration
t_stat isbc464_cfg(uint16 base, uint16 size, uint8 dummy)
{
isbc464_unit.capac = size;
isbc464_unit.u3 = base;
isbc464_unit.filebuf = (uint8 *)calloc(size, sizeof(uint8));
if (isbc464_unit.filebuf == NULL) {
sim_printf (" isbc464: Calloc error\n");
return SCPE_MEM;
}
sim_printf(" isbc464: 0%04XH bytes at base address 0%04XH\n",
isbc464_unit.capac, isbc464_unit.u3);
return SCPE_OK;
}
t_stat isbc464_clr(void)
{
isbc464_unit.capac = 0;
isbc464_unit.u3 = 0;
free(isbc464_unit.filebuf);
return SCPE_OK;
}
// set size parameter
t_stat isbc464_set_size(UNIT *uptr, int32 val, CONST char *cptr, void *desc)
@@ -183,7 +218,7 @@ t_stat isbc464_set_base(UNIT *uptr, int32 val, CONST char *cptr, void *desc)
t_stat isbc464_show_param (FILE *st, UNIT *uptr, int32 val, CONST void *desc)
{
fprintf(st, "%s Size=%04X Base=%04X ",
fprintf(st, "%s, Size=%04X, Base=%04X ",
((isbc464_dev.flags & DEV_DIS) == 0) ? "Enabled" : "Disabled",
uptr->capac, uptr->BASE_ADDR);
return SCPE_OK;
@@ -193,13 +228,13 @@ t_stat isbc464_show_param (FILE *st, UNIT *uptr, int32 val, CONST void *desc)
t_stat isbc464_reset (DEVICE *dptr)
{
if (dptr == NULL)
return SCPE_ARG;
if (isbc464_onetime) {
isbc464_dev.units->capac = SBC464_SIZE; //set default size
isbc464_dev.units->BASE_ADDR = SBC464_BASE; //set default base
isbc464_onetime = 0;
}
if (dptr == NULL)
return SCPE_ARG;
if ((dptr->flags & DEV_DIS) == 0) { //already enabled
isbc464_dev.units->filebuf = (uint8 *)calloc(isbc464_dev.units->capac, sizeof(uint8)); //alloc buffer
if (isbc464_dev.units->filebuf == NULL) { //CALLOC error
@@ -208,7 +243,7 @@ t_stat isbc464_reset (DEVICE *dptr)
}
sim_printf(" sbc464: Enabled 0%04XH bytes at base 0%04XH\n",
isbc464_dev.units->capac, isbc464_dev.units->BASE_ADDR);
} else {
} else { //disabled
if (isbc464_dev.units->filebuf)
free(isbc464_dev.units->filebuf); //return allocated memory
sim_printf(" sbc464: Disabled\n");
@@ -240,6 +275,4 @@ uint8 isbc464_get_mbyte(uint16 addr)
return (val & 0xFF);
}
#endif /* SBC464_NUM > 0 */
/* end of isbc464.c */

193
Intel-Systems/common/mem.c Normal file
View File

@@ -0,0 +1,193 @@
/* mem.c: Intel memory simulator
Copyright (c) 2020, William A. Beech
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 NONINFRINGEMENT. IN NO EVENT SHALL
WILLIAM A. BEECH 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 name of William A. Beech shall not be
used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from William A. Beech.
23 Nov 20 - Original file.
*/
#include "system_defs.h"
/* function prototypes */
uint8 get_mbyte(uint16 addr);
uint16 get_mword(uint16 addr);
void put_mbyte(uint16 addr, uint8 val);
void put_mword(uint16 addr, uint16 val);
/* external function prototypes */
extern uint8 multibus_get_mbyte(uint16 addr);
extern void multibus_put_mbyte(uint16 addr, uint8 val);
extern uint8 EPROM_get_mbyte(uint16 addr, uint8 devnum);
extern UNIT EPROM_unit[];
extern uint8 RAM_get_mbyte(uint16 addr);
extern void RAM_put_mbyte(uint16 addr, uint8 val);
extern UNIT RAM_unit[];
extern int mem_map;
extern uint8 monitor_boot;
/* globals */
/* extern globals */
extern uint16 PCX; /* program counter */
extern uint8 xack; /* XACK signal */
extern UNIT i8255_unit; //for isbc memory control
extern UNIT ipc_cont_unit;
extern UNIT ioc_cont_unit;
extern uint8 i8255_C[4]; //port C byte I/O
/* get a byte from memory - handle MODEL, RAM, ROM and Multibus memory */
uint8 get_mbyte(uint16 addr)
{
uint8 val;
SET_XACK(0); /* clear xack */
if ((mem_map <= 1) && (addr >= 0xF800)) { //monitor ROM - always there IPB/IPC
SET_XACK(1); //set xack
return EPROM_get_mbyte(addr - 0xF000, 0); //top half of EPROM
}
if ((mem_map <= 1) && (addr < 0x1000) && ((ipc_cont_unit.u3 & 0x04) == 0)) { //startup IPB/IPC
SET_XACK(1); //set xack
return EPROM_get_mbyte(addr, 0); //top half of EPROM for boot
}
if ((mem_map <= 1) && (addr >= 0xE800) && (addr < 0xF000) && ((ipc_cont_unit.u3 & 0x10) == 0)) { //diagnostic ROM IPB/IPC
SET_XACK(1); //set xack
return EPROM_get_mbyte(addr - 0xE800, 0); //bottom half of EPROM
}
if (mem_map == 1) { //IPC RAM
SET_XACK(1); //set xack
return RAM_get_mbyte(addr);
}
if ((mem_map == 0) && (addr < 0x8000)) { //IPB RAM
SET_XACK(1); //set xack
return RAM_get_mbyte(addr);
}
if (mem_map == 2) { //800
if (((monitor_boot & 0x04) == 0) && (addr >= EPROM_unit[0].u3) && (addr <= (EPROM_unit[0].u3 + EPROM_unit[0].capac)))
return EPROM_get_mbyte(addr, 0);
else if ((addr >= EPROM_unit[1].u3) && (addr <= (EPROM_unit[1].u3 + EPROM_unit[1].capac)))
return EPROM_get_mbyte(addr, 1);
}
if (mem_map == 3) { //isdk80
if ((addr >= EPROM_unit->u3) && ((uint16)addr <= (EPROM_unit->u3 + EPROM_unit->capac))) {
return EPROM_get_mbyte(addr, 0);
} /* if local RAM handle it */
else if ((addr >= RAM_unit->u3) && ((uint16)addr <= (RAM_unit->u3 + RAM_unit->capac))) {
return RAM_get_mbyte(addr);
}
else return 0xff;
}
if (mem_map == 4) { //isys80/XX
/* if local EPROM handle it */
if (i8255_C[0] & 0x80) { /* EPROM enabled */
if ((addr >= EPROM_unit->u3) && ((uint16)addr <= (EPROM_unit->u3 + EPROM_unit->capac))) {
val = EPROM_get_mbyte(addr, 0);
return val;
}
} /* if local RAM handle it */
if (i8255_C[0] & 0x20) { /* RAM enabled */
if ((addr >= RAM_unit->u3) && ((uint16)addr <= (RAM_unit->u3 + RAM_unit->capac))) {
val = RAM_get_mbyte(addr);
return val;
}
} /* otherwise, try the multibus */
}
return multibus_get_mbyte(addr); //check multibus cards
}
/* get a word from memory */
uint16 get_mword(uint16 addr)
{
uint16 val;
val = get_mbyte(addr);
val |= (get_mbyte(addr+1) << 8);
return val;
}
/* put a byte to memory - handle RAM, ROM and Multibus memory */
void put_mbyte(uint16 addr, uint8 val)
{
SET_XACK(0); /* set no XACK */
if (addr >= 0xF800) { //monitor ROM - always there IPB/IPC/800
return; //do nothing
}
if ((mem_map <= 1) && (addr < 0x1000) && ((ipc_cont_unit.u3 & 0x04) == 0)) { //startup IPB/IPC
return; //do nothing
}
if ((mem_map <= 1) && (addr >= 0xE800) && (addr < 0xF000) && ((ipc_cont_unit.u3 & 0x10) == 0)) { //diagnostic ROM IPB/IPC
return; //do nothing
}
if (mem_map == 1) { //IPC RAM
SET_XACK(1); //set xack
RAM_put_mbyte(addr, val); //IPCRAM
return;
}
if ((mem_map == 0) && (addr < 0x8000)) { //IPB RAM
SET_XACK(1); //set xack
RAM_put_mbyte(addr, val); //IPB RAM
return;
}
if (mem_map == 3) { //isdk80
/* if local EPROM handle it */
if ((addr >= EPROM_unit->u3) && ((uint16)addr <= (EPROM_unit->u3 + EPROM_unit->capac))) {
sim_printf("Write to R/O memory address %04X from PC=%04X - ignored\n", addr, PCX);
return;
} /* if local RAM handle it */
if ((addr >= RAM_unit->u3) && ((uint16)addr <= (RAM_unit->u3 + RAM_unit->capac))) {
RAM_put_mbyte(addr, val);
return;
}
}
if (mem_map == 4) { //isys80/xx
/* if local EPROM handle it */
if (i8255_C[0] & 0x80) { /* EPROM enabled */
if ((addr >= EPROM_unit->u3) && ((uint16)addr <= (EPROM_unit->u3 + EPROM_unit->capac))) {
sim_printf("Write to R/O memory address %04X from PC=%04X - ignored\n", addr, PCX);
return;
}
} /* if local RAM handle it */
if (i8255_C[0] & 0x20) { /* RAM enabled */
if ((addr >= RAM_unit->u3) && ((uint16)addr <= (RAM_unit->u3 + RAM_unit->capac))) {
RAM_put_mbyte(addr, val);
return;
}
} /* otherwise, try the multibus */
}
multibus_put_mbyte(addr, val); //check multibus cards
}
/* put a word to memory */
void put_mword(uint16 addr, uint16 val)
{
put_mbyte(addr, val & 0xff);
put_mbyte(addr+1, val >> 8);
}
/* end of mem.c */

View File

@@ -0,0 +1,72 @@
/* monitor.c: Intel MDS-800 Monitor Module simulator
Copyright (c) 2010, William A. Beech
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 NONINFRINGEMENT. IN NO EVENT SHALL
WILLIAM A. BEECH 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 name of William A. Beech shall not be
used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from William A. Beech.
This software was written by Bill Beech, Dec 2010, to allow emulation of Multibus
Computer Systems.
5 October 2017 - Original file.
*/
#include "system_defs.h"
/* function prototypes */
t_stat monitor_cfg(uint16 base, uint16 size, uint8 devnum);
t_stat monitor_reset (DEVICE *dptr);
/* external function prototypes */
extern t_stat i8251_reset(DEVICE *dptr);
extern t_stat i8251_cfg(uint16 base, uint16 devnum, uint8 dummy);
extern t_stat EPROM_reset(DEVICE *dptr);
extern t_stat EPROM_cfg(uint16 base, uint16 size, uint8 devnum);
extern uint8 reg_dev(uint8 (*routine)(t_bool, uint8, uint8), uint16, uint16, uint8);
extern uint8 unreg_dev(uint16);
extern uint8 i3214_monitor_do_boot(t_bool io, uint8 data, uint8 devnum);
// external globals
extern uint32 PCX; /* program counter */
extern DEVICE i8251_dev;
extern DEVICE EPROM_dev;
extern uint8 monitor_boot;
// globals
t_stat monitor_cfg(uint16 base, uint16 size, uint8 devnum)
{
return SCPE_OK;
}
/* Monitor reset routine
put here to cause a reset of the entire IPC system */
t_stat monitor_reset (DEVICE *dptr)
{
monitor_boot = 0x00;
return SCPE_OK;
}
/* end of monitor.c */

View File

@@ -35,31 +35,27 @@
#include "system_defs.h"
#define BASE_ADDR u3
#define multibus_NAME "Intel Multibus Interface"
/* function prototypes */
t_stat multibus_svc(UNIT *uptr);
t_stat multibus_reset(DEVICE *dptr);
void set_irq(int32 int_num);
void clr_irq(int32 int_num);
uint8 nulldev(t_bool io, uint8 port, uint8 devnum);
uint8 reg_dev(uint8 (*routine)(t_bool, uint8, uint8), uint8, uint8);
uint8 unreg_dev(uint8 port);
t_stat multibus_reset (DEVICE *dptr);
uint8 multibus_get_mbyte(uint16 addr);
void multibus_put_mbyte(uint16 addr, uint8 val);
/* external function prototypes */
extern t_stat SBC_reset(DEVICE *dptr); /* reset the iSBC80/10 emulator */
//extern t_stat SBC_reset(DEVICE *dptr); /* reset the iSBC80/10 emulator */
extern uint8 isbc064_get_mbyte(uint16 addr);
extern void isbc064_put_mbyte(uint16 addr, uint8 val);
extern uint8 isbc464_get_mbyte(uint16 addr);
extern void set_cpuint(int32 int_num);
/* local globals */
int32 mbirq = 0; /* set no multibus interrupts */
static const char* multibus_desc(DEVICE *dptr) {
return multibus_NAME;
}
/* external globals */
@@ -76,7 +72,6 @@ UNIT multibus_unit = {
};
REG multibus_reg[] = {
{ HRDATA (MBIRQ, mbirq, 32) },
{ HRDATA (XACK, xack, 8) },
{ NULL }
};
@@ -92,7 +87,7 @@ DEBTAB multibus_debug[] = {
};
DEVICE multibus_dev = {
"MBIRQ", //name
"MBI", //name
&multibus_unit, //units
multibus_reg, //registers
NULL, //modifiers
@@ -117,7 +112,7 @@ DEVICE multibus_dev = {
NULL, //help routine
NULL, //attach help routine
NULL, //help context
NULL //device description
&multibus_desc //device description
};
/* Service routines to handle simulator functions */
@@ -126,182 +121,56 @@ DEVICE multibus_dev = {
t_stat multibus_reset(DEVICE *dptr)
{
if (SBC_reset(NULL) == 0) {
// if (SBC_reset(NULL) == 0) {
sim_printf(" Multibus: Reset\n");
sim_activate (&multibus_unit, multibus_unit.wait); /* activate unit */
return SCPE_OK;
} else {
sim_printf(" Multibus: SBC not selected\n");
return SCPE_OK;
}
// } else {
// sim_printf(" Multibus: SBC not selected\n");
// return SCPE_OK;
// }
}
/* service routine - actually does the simulated interrupts */
t_stat multibus_svc(UNIT *uptr)
{
switch (mbirq) {
case INT_2:
set_cpuint(INT_R);
break;
default:
break;
}
sim_activate (&multibus_unit, multibus_unit.wait); /* continue poll */
return SCPE_OK;
}
void set_irq(int32 int_num)
{
mbirq |= int_num;
}
void clr_irq(int32 int_num)
{
mbirq &= ~int_num;
}
/* This is the I/O configuration table. There are 256 possible
device addresses, if a device is plugged to a port it's routine
address is here, 'nulldev' means no device has been registered.
*/
struct idev {
uint8 (*routine)(t_bool io, uint8 data, uint8 devnum);
uint8 port;
uint8 devnum;
};
struct idev dev_table[256] = {
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 000H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 004H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 008H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 00CH */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 010H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 014H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 018H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 01CH */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 020H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 024H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 028H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 02CH */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 030H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 034H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 038H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 03CH */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 040H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 044H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 048H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 04CH */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 050H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 054H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 058H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 05CH */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 060H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 064H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 068H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 06CH */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 070H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 074H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 078H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 07CH */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 080H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 084H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 088H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 08CH */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 090H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 094H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 098H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 09CH */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 0A0H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 0A4H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 0A8H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 0A0H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 0B0H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 0B4H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 0B8H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 0B0H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 0C0H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 0C4H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 0C8H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 0CCH */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 0D0H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 0D4H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 0D8H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 0DCH */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 0E0H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 0E4H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 0E8H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 0ECH */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 0F0H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 0F4H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 0F8H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev} /* 0FCH */
};
uint8 nulldev(t_bool io, uint8 data, uint8 devnum)
{
SET_XACK(0); /* set no XACK */
// return 0xff; /* multibus has active high pullups and inversion */
return 0; //corrects "illegal disk at port X8H" error in ISIS
}
uint8 reg_dev(uint8 (*routine)(t_bool io, uint8 data, uint8 devnum), uint8 port, uint8 devnum)
{
if (dev_table[port].routine != &nulldev) { /* port already assigned */
if (dev_table[port].routine != routine)
sim_printf(" I/O Port %02X is already assigned\n", port);
} else {
dev_table[port].routine = routine;
dev_table[port].devnum = devnum;
sim_printf(" I/O Port %02X has been assigned\n", port);
}
return 0;
}
uint8 unreg_dev(uint8 port)
{
if (dev_table[port].routine == &nulldev) { /* port already free */
sim_printf(" I/O Port %02X is already free\n", port);
} else {
dev_table[port].routine = &nulldev;
dev_table[port].devnum = 0;
sim_printf(" I/O Port %02X is free\n", port);
}
return 0;
}
/* get a byte from memory */
uint8 multibus_get_mbyte(uint16 addr)
{
SET_XACK(0); /* set no XACK */
#if defined (SBC464_NUM) && (SBC464_NUM > 0)
if ((isbc464_dev.flags & DEV_DIS) == 0) { //ROM is enabled
if (addr >= isbc464_dev.units->BASE_ADDR && addr <
(isbc464_dev.units->BASE_ADDR + isbc464_dev.units->capac))
return(isbc464_get_mbyte(addr));
if ((isbc464_dev.flags & DEV_DIS) == 0) { //ROM is enabled
if (addr >= isbc464_dev.units->BASE_ADDR &&
addr < (isbc464_dev.units->BASE_ADDR + isbc464_dev.units->capac)) {
SET_XACK(1); //set xack
return(isbc464_get_mbyte(addr));
}
#endif
#if defined (SBC064_NUM) && (SBC064_NUM > 0)
if ((isbc064_dev.flags & DEV_DIS) == 0) { //RAM is enabled
if (addr >= isbc064_dev.units->BASE_ADDR && addr <
(isbc064_dev.units->BASE_ADDR + isbc064_dev.units->capac))
return (isbc064_get_mbyte(addr));
}
if ((isbc064_dev.flags & DEV_DIS) == 0) { //iSBC 064 is enabled
if (addr >= isbc064_dev.units->BASE_ADDR &&
addr < (isbc064_dev.units->BASE_ADDR + isbc064_dev.units->capac)) {
SET_XACK(1); //set xack
return (isbc064_get_mbyte(addr));
}
#endif
}
return 0;
}
void multibus_put_mbyte(uint16 addr, uint8 val)
{
SET_XACK(0); /* set no XACK */
#if defined (SBC064_NUM) && (SBC064_NUM > 0)
if ((isbc064_dev.flags & DEV_DIS) == 0) { //device is enabled
if (addr >= isbc064_dev.units->BASE_ADDR && addr <
(isbc064_dev.units->BASE_ADDR + isbc064_dev.units->capac))
isbc064_put_mbyte(addr, val);
if ((isbc064_dev.flags & DEV_DIS) == 0) { //device is enabled
if (addr >= isbc064_dev.units->BASE_ADDR &&
addr < (isbc064_dev.units->BASE_ADDR + isbc064_dev.units->capac)) {
SET_XACK(1); //set xack
isbc064_put_mbyte(addr, val);
}
#endif
}
}
/* end of multibus.c */

View File

@@ -44,14 +44,15 @@ t_stat xtbus_svc(UNIT *uptr);
t_stat xtbus_reset(DEVICE *dptr);
void set_irq(int32 int_num);
void clr_irq(int32 int_num);
uint8 nulldev(t_bool io, uint8 data);
uint16 reg_dev(uint8 (*routine)(t_bool io, uint8 data), uint16 port);
uint8 nulldev(t_bool io, uint8 data, uint8 devnum);
uint16 reg_dev(uint8 (*routine)(t_bool io, uint8 data, uint8 devnum), uint16 port, uint8 devnum);
void dump_dev_table(void);
t_stat xtbus_reset (DEVICE *dptr);
uint8 xtbus_get_mbyte(uint32 addr);
void xtbus_put_mbyte(uint32 addr, uint8 val);
/* external function prototypes */
extern uint8 RAM_get_mbyte(uint32 addr);
extern void RAM_put_mbyte(uint32 addr, uint8 val);
extern t_stat SBC_reset(DEVICE *dptr); /* reset the PC XT simulator */
@@ -84,8 +85,8 @@ DEBTAB xtbus_debug[] = {
DEVICE xtbus_dev = {
"PCBUS", //name
&xtbus_unit, //units
xtbus_reg, //registers
&xtbus_unit, //units
xtbus_reg, //registers
NULL, //modifiers
1, //numunits
16, //aradix
@@ -95,14 +96,14 @@ DEVICE xtbus_dev = {
8, //dwidth
NULL, //examine
NULL, //deposit
&xtbus_reset, //reset
&xtbus_reset, //reset
NULL, //boot
NULL, //attach
NULL, //detach
NULL, //ctxt
DEV_DEBUG, //flags
0, //dctrl
xtbus_debug, //debflags
xtbus_debug, //debflags
NULL, //msize
NULL //lname
};
@@ -155,7 +156,9 @@ The actual 808X can address 65,536 I/O ports but the IBM only uses
the first 1024. */
struct idev {
uint8 (*routine)(t_bool io, uint8 data);
uint8 (*routine)(t_bool io, uint8 data, uint8 devnum);
uint8 port;
uint8 devnum;
};
struct idev dev_table[1024] = {
@@ -417,16 +420,16 @@ struct idev dev_table[1024] = {
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev} /* 3FCH */
};
uint8 nulldev(t_bool flag, uint8 data)
uint8 nulldev(t_bool io, uint8 data, uint8 devnum)
{
sim_printf("xtbus: I/O Port %03X is not assigned io=%d data=%02X\n",
port, flag, data);
if (flag == 0) /* if we got here, no valid I/O device */
port, io, data);
if (io == 0) /* if we got here, no valid I/O device */
return 0xFF;
return 0;
}
uint16 reg_dev(uint8 (*routine)(t_bool io, uint8 data), uint16 port)
uint16 reg_dev(uint8 (*routine)(t_bool io, uint8 data, uint8 devnum), uint16 port, uint8 devnum)
{
if (dev_table[port].routine != &nulldev) { /* port already assigned */
sim_printf("xtbus: I/O Port %03X is already assigned\n", port);

View File

@@ -101,7 +101,7 @@ t_stat EPROM_attach (UNIT *uptr, CONST char *cptr)
sim_debug (DEBUG_flow, &EPROM_dev, "EPROM_attach: cptr=%s\n", cptr);
if ((r = attach_unit (uptr, cptr)) != SCPE_OK) {
sim_debug (DEBUG_flow, &EPROM_dev, "EPROM_attach: Error\n");
sim_printf ("EPROM_attach: Error %d\n", r);
return r;
}
sim_debug (DEBUG_read, &EPROM_dev, "\tAllocate buffer\n");

254
Intel-Systems/common/port.c Normal file
View File

@@ -0,0 +1,254 @@
/* port.c: Intel Port Mapper
Copyright (c) 2010, William A. Beech
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 NONINFRINGEMENT. IN NO EVENT SHALL
WILLIAM A. BEECH 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 name of William A. Beech shall not be
used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from William A. Beech.
MODIFICATIONS:
20 Sep 20 - Original file.
NOTES:
*/
#include "system_defs.h"
#define port_NAME "Intel Port Map Simulator"
/* function prototypes */
t_stat port_svc(UNIT *uptr);
t_stat port_reset(DEVICE *dptr);
uint8 nulldev(t_bool io, uint8 port, uint8 devnum);
extern uint8 reg_dev(uint8 (*routine)(t_bool, uint8, uint8), uint16, uint16, uint8);
void clr_dev();
uint8 unreg_dev(uint16 port);
/* external function prototypes */
//extern t_stat SBC_reset(DEVICE *dptr);
/* local globals */
static const char* port_desc(DEVICE *dptr) {
return port_NAME;
}
/* external globals */
extern uint8 xack; /* XACK signal */
extern uint16 PCX;
/* multibus Standard SIMH Device Data Structures */
UNIT port_unit = {
UDATA (&port_svc, 0, 0), 1
};
REG port_reg[] = {
{ NULL }
};
DEBTAB port_debug[] = {
{ "ALL", DEBUG_all },
{ "FLOW", DEBUG_flow },
{ "READ", DEBUG_read },
{ "WRITE", DEBUG_write },
{ "LEV1", DEBUG_level1 },
{ "LEV2", DEBUG_level2 },
{ NULL }
};
DEVICE port_dev = {
"PORT", //name
&port_unit, //units
port_reg, //registers
NULL, //modifiers
1, //numunits
16, //aradix
16, //awidth
1, //aincr
16, //dradix
8, //dwidth
NULL, //examine
NULL, //deposit
&port_reset, //reset
NULL, //boot
NULL, //attach
NULL, //detach
NULL, //ctxt
DEV_DEBUG, //flags
0, //dctrl
port_debug, //debflags
NULL, //msize
NULL, //lname
NULL, //help routine
NULL, //attach help routine
NULL, //help context
&port_desc //device description
};
/* Service routines to handle simulator functions */
/* Reset routine */
t_stat port_reset(DEVICE *dptr)
{
// if (SBC_reset(NULL) == 0) {
sim_printf(" Port: Reset\n");
sim_activate (&port_unit, port_unit.wait); /* activate unit */
return SCPE_OK;
// } else {
// sim_printf(" Port: SBC not selected\n");
// return SCPE_OK;
// }
}
/* service routine - actually does the simulated interrupts */
t_stat port_svc(UNIT *uptr)
{
sim_activate (&port_unit, port_unit.wait); /* continue poll */
return SCPE_OK;
}
/* This is the I/O configuration table. There are 256 possible
device addresses, if a device is plugged to a port it's routine
address is here, 'nulldev' means no device has been registered.
*/
struct idev {
uint8 (*routine)(t_bool io, uint8 data, uint8 devnum);
uint16 port;
uint16 devnum;
uint8 dummy;
};
struct idev dev_table[256] = {
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 000H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 004H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 008H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 00CH */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 010H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 014H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 018H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 01CH */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 020H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 024H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 028H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 02CH */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 030H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 034H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 038H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 03CH */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 040H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 044H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 048H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 04CH */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 050H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 054H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 058H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 05CH */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 060H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 064H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 068H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 06CH */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 070H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 074H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 078H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 07CH */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 080H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 084H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 088H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 08CH */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 090H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 094H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 098H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 09CH */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 0A0H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 0A4H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 0A8H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 0A0H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 0B0H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 0B4H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 0B8H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 0B0H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 0C0H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 0C4H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 0C8H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 0CCH */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 0D0H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 0D4H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 0D8H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 0DCH */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 0E0H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 0E4H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 0E8H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 0ECH */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 0F0H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 0F4H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 0F8H */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev} /* 0FCH */
};
uint8 nulldev(t_bool io, uint8 data, uint8 devnum)
{
SET_XACK(0); //clear xack
// return 0xff; /* multibus has active high pullups and inversion */
return 0; //corrects "illegal disk at port X8H" error in ISIS
}
uint8 reg_dev(uint8 (*routine)(t_bool io, uint8 data, uint8 devnum),
uint16 port, uint16 devnum, uint8 dummy)
{
if (dev_table[port].routine != &nulldev) { /* port already assigned */
if (dev_table[port].routine != routine)
sim_printf(" I/O Port %02X is already assigned\n", port);
} else {
dev_table[port].routine = routine;
dev_table[port].devnum = devnum;
sim_printf(" I/O Port %02X has been assigned\n", port);
}
return 0;
}
void clr_dev()
{
int i;
for (i=0; i<256; i++)
unreg_dev(i);
}
uint8 unreg_dev(uint16 port)
{
if (dev_table[port].routine == &nulldev) { /* port already free */
;//sim_printf(" I/O Port %02X is already free\n", port);
} else {
dev_table[port].routine = &nulldev;
dev_table[port].devnum = 0;
sim_printf(" I/O Port %02X is free\n", port);
}
return 0;
}
/* end of port.c */

551
Intel-Systems/common/sys.c Normal file
View File

@@ -0,0 +1,551 @@
/* sys.c: Intel System Configuration Device
Copyright (c) 2020, William A. Beech
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 NONINFRINGEMENT. IN NO EVENT SHALL
WILLIAM A. BEECH 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 name of William A. Beech shall not be
used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from William A. Beech.
MODIFICATIONS:
11 Sep 20 - Original file.
NOTES:
*/
#include "system_defs.h" /* system header in system dir */
//option board types
#define SBC064 128
#define SBC464 129
#define SBC201 130
#define SBC202 131
#define SBC204 132
#define SBC206 133
#define SBC208 134
#define ZX200A 135
//Single board computer device types
#define i3214 1
#define i8080 2
#define i8085 3
#define i8251 4
#define i8253 5
#define i8255 6
#define i8259 7
#define IOC_CONT 8
#define IPC_CONT 9
#define MULTI 64
#define EPROM 65
#define RAM 66
//System types
#define MDS_210 0
#define MDS_220 1
#define MDS_225 2
#define MDS_230 3
#define MDS_800 4
#define MDS_810 5
#define SDK_80 6
#define SYS_8010 7
#define SYS_8010A 8
#define SYS_8010B 9
#define SYS_8020 10
#define SYS_80204 11
#define SYS_8024 12
#define SYS_8030 13
#define sys_name "Intel MDS Configuration Controller"
/* external globals */
extern uint16 PCX;
/* function prototypes */
t_stat sys_cfg(uint16 base, uint16 devnum, uint8 dummy);
t_stat sys_clr(void);
t_stat sys_reset(DEVICE *dptr);
static const char* sys_desc(DEVICE *dptr);
t_stat sys_set_model (UNIT *uptr, int32 val, CONST char *cptr, void *desc);
t_stat sys_show_model (FILE *st, UNIT *uptr, int32 val, CONST void *desc);
/* external function prototypes */
extern uint8 reg_dev(uint8 (*routine)(t_bool, uint8, uint8), uint16, uint16, uint8);
extern uint8 unreg_dev(uint16);
extern t_stat i3214_cfg(uint16 base, uint16 devnum, uint8 dummy);
extern t_stat i8251_cfg(uint16 base, uint16 devnum, uint8 dummy);
extern t_stat i8253_cfg(uint16 base, uint16 devnum, uint8 dummy);
extern t_stat i8255_cfg(uint16 base, uint16 devnum, uint8 dummy);
extern t_stat i8259_cfg(uint16 base, uint16 devnum, uint8 dummy);
extern t_stat ioc_cont_cfg(uint16 base, uint16 devnum, uint8 dummy);
extern t_stat ipc_cont_cfg(uint16 base, uint16 devnum, uint8 dummy);
extern t_stat EPROM_cfg(uint16 base, uint16 size, uint8 devnum);
extern t_stat RAM_cfg(uint16 base, uint16 size, uint8 dummy);
extern t_stat isbc064_cfg(uint16 base, uint16 size, uint8 dummy);
extern t_stat isbc464_cfg(uint16 base, uint16 size, uint8 dummy);
extern t_stat i3214_clr(void);
extern t_stat i8251_clr(void);
extern t_stat i8253_clr(void);
extern t_stat i8255_clr(void);
extern t_stat i8259_clr(void);
extern t_stat ioc_cont_clr(void);
extern t_stat ipc_cont_clr(void);
extern t_stat EPROM_clr(void);
extern t_stat RAM_clr(void);
extern t_stat isbc064_clr(void);
extern t_stat isbc464_clr(void);
extern void clr_dev(void);
/* globals */
int model = -1; //force no model
int mem_map = 0; //memory model
typedef struct device {
int id;
const char *name;
int num;
int args;
t_stat (*cfg_routine)(uint16 val1, uint16 val2, uint8 val3);
t_stat (*clr_routine)(void);
uint16 val[8];
} SYS_DEV;
typedef struct system_model {
int id;
const char *name;
int num;
SYS_DEV devices[30];
} SYS_MODEL;
#define SYS_NUM 15
SYS_MODEL models[SYS_NUM+1] = {
{MDS_210, "MDS-210 ", 9,
// id name num arg routine routine1 val1 val2 val3
{{ i8251, "I8251", 2, 1, i8251_cfg, i8251_clr, 0xF4, 0xF6 },
{ i8253, "I8253", 1, 1, i8253_cfg, i8253_clr, 0xF0 },
{ i8255, "I8255", 2, 1, i8255_cfg, i8255_clr, 0xE4, 0xE8 },
{ i8259, "I8259", 2, 1, i8259_cfg, i8259_clr, 0xFA, 0xFC },
{ IOC_CONT, "IOC-CONT", 1, 1, ioc_cont_cfg, ioc_cont_clr, 0xC0 },
{ IPC_CONT, "IPC-CONT", 1, 1, ipc_cont_cfg, ipc_cont_clr, 0xFF },
{ EPROM, "EPROM", 1, 2, EPROM_cfg, EPROM_clr, 0x0000, 0x0FFF },
{ RAM, "RAM", 1, 2, RAM_cfg, RAM_clr, 0x0000, 0x7FFF },
{ SBC464, "SBC464", 1, 2, isbc464_cfg, isbc464_clr, 0xA800, 0x47FF }},
},
{MDS_220, "MDS-220 ", 8,
{{ i8251, "I8251", 2, 1, i8251_cfg, i8251_clr, 0xF4, 0xF6 },
{ i8253, "I8253", 1, 1, i8253_cfg, i8253_clr, 0xF0 },
{ i8255, "I8255", 2, 1, i8255_cfg, i8255_clr, 0xE4, 0xE8 },
{ i8259, "I8259", 2, 1, i8259_cfg, i8259_clr, 0xFA, 0xFC },
{ IOC_CONT, "IOC-CONT", 1, 1, ioc_cont_cfg, ioc_cont_clr, 0xC0 },
{ IPC_CONT, "IPC-CONT", 1, 1, ipc_cont_cfg, ipc_cont_clr, 0xFF },
{ EPROM, "EPROM", 1, 2, EPROM_cfg, EPROM_clr, 0x0000, 0x0FFF },
{ RAM, "RAM", 1, 2, RAM_cfg, RAM_clr, 0x0000, 0x7FFF }}
},
{MDS_225, "MDS-225 ", 8,
{{ i8251, "I8251", 2, 1, i8251_cfg, i8251_clr, 0xF4, 0xF6 },
{ i8253, "I8253", 1, 1, i8253_cfg, i8253_clr, 0xF0 },
{ i8255, "I8255", 2, 1, i8255_cfg, i8255_clr, 0xE4, 0xE8 },
{ i8259, "I8259", 2, 1, i8259_cfg, i8259_clr, 0xFA, 0xFC },
{ IOC_CONT, "IOC-CONT", 1, 1, ioc_cont_cfg, ioc_cont_clr, 0xC0 },
{ IPC_CONT, "IPC-CONT", 1, 1, ipc_cont_cfg, ipc_cont_clr, 0xFF },
{ EPROM, "EPROM", 1, 2, EPROM_cfg, EPROM_clr, 0x0000, 0x0FFF },
{ RAM, "RAM", 1, 2, RAM_cfg, RAM_clr, 0x0000, 0xFFFF }},
},
{MDS_230, "MDS-230 ", 9,
{{ i8251, "I8251", 2, 1, i8251_cfg, i8251_clr, 0xF4, 0xF6 },
{ i8253, "I8253", 1, 1, i8253_cfg, i8253_clr, 0xF0 },
{ i8255, "I8255", 2, 1, i8255_cfg, i8255_clr, 0xE4, 0xE8 },
{ i8259, "I8259", 2, 1, i8259_cfg, i8259_clr, 0xFA, 0xFC },
{ IOC_CONT, "IOC-CONT", 1, 1, ioc_cont_cfg, ioc_cont_clr, 0xC0 },
{ IPC_CONT, "IPC-CONT", 1, 1, ipc_cont_cfg, ipc_cont_clr, 0xFF },
{ EPROM, "EPROM", 1, 2, EPROM_cfg, EPROM_clr, 0x0000, 0x0FFF },
{ RAM, "RAM", 1, 2, RAM_cfg, RAM_clr, 0x0000, 0x7FFF },
{ SBC064, "SBC064", 1, 2, isbc064_cfg, isbc064_clr, 0x8000, 0x7FFF }},
},
{MDS_800, "MDS-800 ", 5,
{{ i3214, "I3214", 1, 1, i3214_cfg, i3214_clr, 0xFC },
{ i8251, "I8251", 2, 1, i8251_cfg, i8251_clr, 0xF4, 0xF6 },
{ EPROM, "EPROM", 1, 2, EPROM_cfg, EPROM_clr, 0x0000, 0x00FF },
{ EPROM, "EPROM", 1, 2, EPROM_cfg, EPROM_clr, 0xF800, 0x07FF },
{ SBC064, "SBC064", 1, 2, isbc064_cfg, isbc064_clr, 0x0000, 0x7FFF }},
},
{MDS_810, "MDS-810 ", 6,
{{ i3214, "I3214", 1, 1, i3214_cfg, i3214_clr, 0xFC },
{ i8251, "I8251", 2, 1, i8251_cfg, i8251_clr, 0xF4, 0xF6 },
{ EPROM, "EPROM", 1, 2, EPROM_cfg, EPROM_clr, 0x0000, 0x00FF },
{ EPROM, "EPROM2", 1, 2, EPROM_cfg, EPROM_clr, 0xF800, 0x07FF },
{ SBC064, "SBC064", 1, 2, isbc064_cfg, isbc064_clr, 0x0000, 0x7FFF },
{ SBC464, "SBC464", 1, 2, isbc464_cfg, isbc464_clr, 0xA800, 0x47FF }},
},
{SDK_80, "SDK-80 ", 4,
{{ i8251, "I8251", 1, 1, i8251_cfg, i8251_clr, 0xFA },
{ i8255, "I8255", 2, 1, i8255_cfg, i8255_clr, 0xF4, 0xEC },
{ EPROM, "EPROM", 1, 2, EPROM_cfg, EPROM_clr, 0x0000, 0x0FFF },
{ RAM, "RAM", 1, 2, RAM_cfg, RAM_clr, 0x1000, 0x03FF }},
},
{SYS_8010, "SYS-80/10 ", 4,
{{ i8251, "I8251", 1, 1, i8251_cfg, i8251_clr, 0xEC },
{ i8255, "I8255", 2, 1, i8255_cfg, i8255_clr, 0xE4, 0xE8 },
{ EPROM, "EPROM", 1, 2, EPROM_cfg, EPROM_clr, 0x0000, 0x0FFF },
{ RAM, "RAM", 1, 2, RAM_cfg, RAM_clr, 0x3c00, 0x03FF }},
},
{SYS_8010A, "SYS-80/10A ", 4,
{{ i8251, "I8251", 1, 1, i8251_cfg, i8251_clr, 0xEC },
{ i8255, "I8255", 2, 1, i8255_cfg, i8255_clr, 0xE4, 0xE8 },
{ EPROM, "EPROM", 1, 2, EPROM_cfg, EPROM_clr, 0x0000, 0x1FFF },
{ RAM, "RAM", 1, 2, RAM_cfg, RAM_clr, 0x3c00, 0x03FF }},
},
{SYS_8010B, "SYS-80/10B ", 4,
{{ i8251, "I8251", 1, 1, i8251_cfg, i8251_clr, 0xEC },
{ i8255, "I8255", 2, 1, i8255_cfg, i8255_clr, 0xE4, 0xE8 },
{ EPROM, "EPROM", 1, 2, EPROM_cfg, EPROM_clr, 0x0000, 0x3FFF },
{ RAM, "RAM", 1, 2, RAM_cfg, RAM_clr, 0x3c00, 0x03FF }},
},
{SYS_8020, "SYS-80/20 ", 6,
{{ i8251, "I8251", 1, 1, i8251_cfg, i8251_clr, 0xEC },
{ i8253, "I8253", 1, 1, i8253_cfg, i8253_clr, 0xDC },
{ i8255, "I8255", 1, 1, i8255_cfg, i8255_clr, 0xE8 },
{ i8259, "I8259", 1, 1, i8259_cfg, i8259_clr, 0xDA },
{ EPROM, "EPROM", 1, 2, EPROM_cfg, EPROM_clr, 0x0000, 0x1FFF },
{ RAM, "RAM", 1, 2, RAM_cfg, RAM_clr, 0x3800, 0x07FF }},
},
{SYS_8020-4, "SYS-80/20-4", 6,
{{ i8251, "I8251", 1, 1, i8251_cfg, i8251_clr, 0xEC },
{ i8253, "I8253", 1, 1, i8253_cfg, i8253_clr, 0xDC },
{ i8255, "I8255", 1, 1, i8255_cfg, i8255_clr, 0xE8 },
{ i8259, "I8259", 1, 1, i8259_cfg, i8259_clr, 0xDA },
{ EPROM, "EPROM", 1, 2, EPROM_cfg, EPROM_clr, 0x0000, 0x1FFF },
{ RAM, "RAM", 1, 2, RAM_cfg, RAM_clr, 0x3000, 0x0FFF }},
},
{SYS_8024, "SYS-80/24 ", 6,
{{ i8251, "I8251", 1, 1, i8251_cfg, i8251_clr, 0xEC },
{ i8253, "I8253", 1, 1, i8253_cfg, i8253_clr, 0xDC },
{ i8255, "I8255", 1, 1, i8255_cfg, i8255_clr, 0xE8 },
{ i8259, "I8259", 1, 1, i8259_cfg, i8259_clr, 0xDA },
{ EPROM, "EPROM", 1, 2, EPROM_cfg, EPROM_clr, 0x0000, 0x1FFF },
{ RAM, "RAM", 1, 2, RAM_cfg, RAM_clr, 0x3c00, 0x03FF }},
},
{SYS_8030, "SYS-80/30 ", 6,
{{ i8251, "I8251", 1, 1, i8251_cfg, i8251_clr, 0xEC },
{ i8253, "I8253", 1, 1, i8253_cfg, i8253_clr, 0xDC },
{ i8255, "I8255", 1, 1, i8255_cfg, i8255_clr, 0xE8 },
{ i8259, "I8259", 1, 1, i8259_cfg, i8259_clr, 0xDA },
{ EPROM, "EPROM", 1, 2, EPROM_cfg, EPROM_clr, 0x0000, 0x1FFF },
{ RAM, "RAM", 1, 2, RAM_cfg, RAM_clr, 0x2000, 0x3FFF }},
},
{0}
};
UNIT sys_unit = { UDATA (NULL, 0, 0) };
REG sys_reg[] = {
{ NULL }
};
MTAB sys_mod[] = {
{ MTAB_XTD | MTAB_VDV, 0, NULL, "MODEL", &sys_set_model, NULL, NULL,
"Sets the system model" },
{ MTAB_XTD | MTAB_VDV, 0, "MODEL", NULL, NULL, &sys_show_model, NULL,
"Shows the system devices" },
{ 0 }
};
DEBTAB sys_debug[] = {
{ "ALL", DEBUG_all },
{ "FLOW", DEBUG_flow },
{ "READ", DEBUG_read },
{ "WRITE", DEBUG_write },
{ "XACK", DEBUG_xack },
{ "LEV1", DEBUG_level1 },
{ "LEV2", DEBUG_level2 },
{ NULL }
};
/* address width is set to 16 bits to use devices in 8086/8088 implementations */
DEVICE sys_dev = {
"SYS", //name
&sys_unit, //units
sys_reg, //registers
sys_mod, //modifiers
1, //numunits
0, //aradix
0, //awidth
0, //aincr
0, //dradix
0, //dwidth
NULL, //examine
NULL, //deposit
sys_reset, //reset
NULL, //boot
NULL, //attach
NULL, //detach
NULL, //ctxt
0, //flags
0, //dctrl
sys_debug, //debflags
NULL, //msize
NULL, //lname
NULL, //help routine
NULL, //attach help routine
NULL, //help context
&sys_desc //device description
};
static const char* sys_desc(DEVICE *dptr) {
return sys_name;
}
t_stat sys_cfg(uint16 base, uint16 devnum, uint8 dummy)
{
int i, j;
DEVICE *dptr;
if (model == (-1)) return SCPE_ARG; //no valid config
sim_printf("sys_cfg: Configure %s:\n", models[model].name);
switch (model) { //set memory map type
case 0: //mds-210
mem_map = 0; //ipb
break;
case 1: //mds-220
mem_map = 0; //ipb
break;
case 2: //mds-225
mem_map = 1; //ipc
break;
case 3: //mds-230
mem_map = 0; //ipb
break;
case 4: //mds-800
mem_map = 2; //800
break;
case 5: //mds-810
mem_map = 2; //800
break;
case 6: //sdk-80
mem_map = 3; //sdk-80
break;
case 7: //sys-8010
mem_map = 4; //sys-8010
break;
case 8: //sys-8010A
mem_map = 4; //sys-8010A
break;
case 9: //sys-8010B
mem_map = 4; //sys-8010B
break;
case 10: //sys-8020
mem_map = 4; //sys-8020
break;
case 11: //sys-8020-4
mem_map = 4; //sys-8020-4
break;
case 12: //sys-8024
mem_map = 4; //sys-8024
break;
case 13: //sys-8030
mem_map = 4; //sys-8030
break;
default:
return SCPE_ARG;
}
for (i=0; i<models[model].num; i++) { //for each device in model
dptr = find_dev (models[model].devices[i].name);
if ((dptr != NULL) && ((dptr->flags & DEV_DIS) != 0)) { // disabled
dptr->flags &= ~DEV_DIS; //enable device
}
for (j=0; j<models[model].devices[i].num; j++) { //for each instance of a device
switch(models[model].devices[i].args) {
case 1: //one argument
models[model].devices[i].cfg_routine (models[model].devices[i].val[j], j, 0);
break;
case 2: //two arguments
models[model].devices[i].cfg_routine (models[model].devices[i].val[j],
models[model].devices[i].val[j+1], j);
break;
case 3: //three arguments
models[model].devices[i].cfg_routine (models[model].devices[i].val[j],
models[model].devices[i].val[j+1], models[model].devices[i].val[j+1] & 0xff);
break;
default:
return SCPE_ARG;
}
}
}
return SCPE_OK;
}
t_stat sys_clr(void)
{
int i, j;
DEVICE *dptr;
printf("sys_clr: Unconfiguring %s\n", models[model].name);
for (i=0; i<models[model].num; i++) { //for each device in model
dptr = find_dev (models[model].devices[i].name);
if ((dptr != NULL) && (dptr->flags & DEV_DIS)) { // enabled
dptr->flags |= DEV_DIS; //disable device
}
for (j=0; j<models[model].devices[i].num; j++) { //for each instance of a device
printf(" %s%d\n", models[model].devices[i].name, j);
models[model].devices[i].clr_routine ();
}
}
sim_name[0] = '\0';
// models[model].name[0] = '\0';
model = -1;
mem_map = 0;
return SCPE_OK;
}
t_stat sys_reset(DEVICE *dptr)
{
if (dptr == NULL)
return SCPE_ARG;
sim_printf("SYS Reset\n");
sys_cfg(0, 0, 0);
return SCPE_OK;
}
/* Set/show CPU model */
t_stat sys_set_model (UNIT *uptr, int32 val, CONST char *cptr, void *desc)
{
int i, j;
DEVICE *dptr;
if (cptr == NULL)
return SCPE_ARG;
if (model != -1) sys_clr();
for (i=0; i<SYS_NUM; i++) { //search stored configurations
if (!strncmp(cptr, models[i].name, strlen(cptr))) { //find the system
model = models[i].id;
strncpy(sim_name, models[i].name, 11);
printf("sys_set_model: Configuring %s\n", sim_name);
switch (model) { //set memory map type
case 0: //mds-210
mem_map = 0; //ipb
break;
case 1: //mds-220
mem_map = 0; //ipb
break;
case 2: //mds-225
mem_map = 1; //ipc
break;
case 3: //mds-230
mem_map = 0; //ipb
break;
case 4: //mds-800
mem_map = 2; //800
break;
case 5: //mds-810
mem_map = 2; //800
break;
case 6: //SDK-80
mem_map = 3; //sdk-80
break;
case 7: //sys-8010
mem_map = 4; //sys-8010
break;
case 8: //sys-8010A
mem_map = 4; //sys-8010A
break;
case 9: //sys-8010B
mem_map = 4; //sys-8010B
break;
case 10: //sys-8020
mem_map = 4; //sys-8020
break;
case 11: //sys-8020-4
mem_map = 4; //sys-8020-4
break;
case 12: //sys-8024
mem_map = 4; //sys-8024
break;
case 13: //sys-8030
mem_map = 4; //sys-8030
break;
default:
return SCPE_ARG;
}
for (i=0; i<models[model].num; i++) { //for each device in model
dptr = find_dev (models[model].devices[i].name);
if ((dptr != NULL) && ((dptr->flags & DEV_DIS) != 0)) { // disabled
dptr->flags &= ~DEV_DIS; //enable device
}
for (j=0; j<models[model].devices[i].num; j++) { //for each instance of a device
switch(models[model].devices[i].args) {
case 1: //one argument
models[model].devices[i].cfg_routine (models[model].devices[i].val[j], j, 0);
break;
case 2: //two arguments
models[model].devices[i].cfg_routine (models[model].devices[i].val[j],
models[model].devices[i].val[j+1], j);
break;
case 3: //three arguments
models[model].devices[i].cfg_routine (models[model].devices[i].val[j],
models[model].devices[i].val[j+1], models[model].devices[i].val[j+1] & 0xff);
break;
default:
return SCPE_ARG;
}
}
}
return SCPE_OK;
}
}
printf("Unknown Model Name %s\n", cptr);
return SCPE_ARG;
}
t_stat sys_show_model (FILE *st, UNIT *uptr, int32 val, CONST void *desc)
{
int i, j;
if (uptr == NULL)
return SCPE_ARG;
return SCPE_OK;
fprintf(st, "%s: %d\n", models[model].name, models[model].num);
for (i=0; i<models[model].num; i++) {
fprintf(st, " %s:", models[model].devices[i].name);
fprintf(st, " %d", models[model].devices[i].num);
fprintf(st, " %d", models[model].devices[i].args);
for (j=0; j<models[model].devices[i].num; j++) {
if (models[model].devices[i].args == 2)
fprintf(st, " 0%04XH 0%04XH", models[model].devices[i].val[j],
models[model].devices[i].val[j+1]);
else
fprintf(st, " 0%04XH", models[model].devices[i].val[j]);
}
fprintf(st, "\n");
}
return SCPE_OK;
}
/* end of sys.c */

View File

@@ -139,8 +139,6 @@
#include "system_defs.h" /* system header in system dir */
#if defined (ZX200A_NUM) && (ZX200A_NUM > 0)
#define UNIT_V_WPMODE (UNIT_V_UF) /* Write protect */
#define UNIT_WPMODE (1 << UNIT_V_WPMODE)
@@ -200,8 +198,8 @@ extern uint16 PCX;
/* external function prototypes */
extern uint8 reg_dev(uint8 (*routine)(t_bool, uint8, uint8), uint8, uint8);
extern uint8 unreg_dev(uint8);
extern uint8 reg_dev(uint8 (*routine)(t_bool, uint8, uint8), uint16, uint16, uint8);
extern uint8 unreg_dev(uint16);
extern uint8 get_mbyte(uint16 addr);
extern void put_mbyte(uint16 addr, uint8 val);
@@ -228,10 +226,10 @@ void zx200a_diskio(void);
/* globals */
int zx200a_onetime = 1;
static const char* zx200a_desc(DEVICE *dptr) {
return zx200a_NAME;
}
typedef struct { //FDD definition
uint8 sec;
uint8 cyl;
@@ -258,12 +256,12 @@ FDCDEF zx200a;
/* ZX-200A Standard I/O Data Structures */
UNIT zx200a_unit[] = {
{ UDATA (0, UNIT_ATTABLE+UNIT_DISABLE+UNIT_BUFABLE+UNIT_MUSTBUF+UNIT_FIX, MDSDD) },
{ UDATA (0, UNIT_ATTABLE+UNIT_DISABLE+UNIT_BUFABLE+UNIT_MUSTBUF+UNIT_FIX, MDSDD) },
{ UDATA (0, UNIT_ATTABLE+UNIT_DISABLE+UNIT_BUFABLE+UNIT_MUSTBUF+UNIT_FIX, MDSDD) },
{ UDATA (0, UNIT_ATTABLE+UNIT_DISABLE+UNIT_BUFABLE+UNIT_MUSTBUF+UNIT_FIX, MDSDD) },
{ UDATA (0, UNIT_ATTABLE+UNIT_DISABLE+UNIT_BUFABLE+UNIT_MUSTBUF+UNIT_FIX, MDSSD) },
{ UDATA (0, UNIT_ATTABLE+UNIT_DISABLE+UNIT_BUFABLE+UNIT_MUSTBUF+UNIT_FIX, MDSSD) },
{ UDATA (0, UNIT_ATTABLE+UNIT_DISABLE+UNIT_ROABLE+UNIT_RO+UNIT_BUFABLE+UNIT_MUSTBUF+UNIT_FIX, MDSDD) },
{ UDATA (0, UNIT_ATTABLE+UNIT_DISABLE+UNIT_ROABLE+UNIT_RO+UNIT_BUFABLE+UNIT_MUSTBUF+UNIT_FIX, MDSDD) },
{ UDATA (0, UNIT_ATTABLE+UNIT_DISABLE+UNIT_ROABLE+UNIT_RO+UNIT_BUFABLE+UNIT_MUSTBUF+UNIT_FIX, MDSDD) },
{ UDATA (0, UNIT_ATTABLE+UNIT_DISABLE+UNIT_ROABLE+UNIT_RO+UNIT_BUFABLE+UNIT_MUSTBUF+UNIT_FIX, MDSDD) },
{ UDATA (0, UNIT_ATTABLE+UNIT_DISABLE+UNIT_ROABLE+UNIT_RO+UNIT_BUFABLE+UNIT_MUSTBUF+UNIT_FIX, MDSSD) },
{ UDATA (0, UNIT_ATTABLE+UNIT_DISABLE+UNIT_ROABLE+UNIT_RO+UNIT_BUFABLE+UNIT_MUSTBUF+UNIT_FIX, MDSSD) },
{ NULL }
};
@@ -323,7 +321,7 @@ DEVICE zx200a_dev = {
&zx200a_attach, //attach
NULL, //detach
NULL, //ctxt
DEV_DISABLE+DEV_DIS, //flags
DEV_DEBUG+DEV_DISABLE+DEV_DIS, //flags
0, //dctrl
zx200a_debug, //debflags
NULL, //msize
@@ -345,19 +343,15 @@ t_stat zx200a_set_mode (UNIT *uptr, int32 val, CONST char *cptr, void *desc)
if (val & UNIT_WPMODE) { /* write protect */
uptr->flags |= val;
if (zx200a.verb)
sim_printf(" sbc202: WP\n");
sim_printf(" ZX200A: WP\n");
} else { /* read write */
uptr->flags &= ~val;
if (zx200a.verb)
sim_printf(" sbc202: RW\n");
sim_printf(" ZX200A: RW\n");
}
return SCPE_OK;
}
/* I/O instruction handlers, called from the CPU module when an
IN or OUT instruction is issued.
*/
/* Service routines to handle simulator functions */
// set base address parameter
@@ -371,7 +365,7 @@ t_stat zx200a_set_port(UNIT *uptr, int32 val, CONST char *cptr, void *desc)
result = sscanf(cptr, "%02x", &size);
zx200a.baseport = size;
if (zx200a.verb)
sim_printf("SBC202: Base port=%04X\n", zx200a.baseport);
sim_printf("ZX200A: Base port=%04X\n", zx200a.baseport);
return SCPE_OK;
}
@@ -386,7 +380,7 @@ t_stat zx200a_set_int(UNIT *uptr, int32 val, CONST char *cptr, void *desc)
result = sscanf(cptr, "%02x", &size);
zx200a.intnum = size;
if (zx200a.verb)
sim_printf("SBC202: Interrupt number=%04X\n", zx200a.intnum);
sim_printf("ZX200A: Interrupt number=%04X\n", zx200a.intnum);
return SCPE_OK;
}
@@ -402,7 +396,7 @@ t_stat zx200a_set_verb(UNIT *uptr, int32 val, CONST char *cptr, void *desc)
}
if (strncasecmp(cptr, "ON", 3) == 0) {
zx200a.verb = 1;
sim_printf(" SBC202: zx200a.verb=%d\n", zx200a.verb);
sim_printf(" ZX200A: zx200a.verb=%d\n", zx200a.verb);
return SCPE_OK;
}
return SCPE_ARG;
@@ -422,6 +416,10 @@ t_stat zx200a_show_param (FILE *st, UNIT *uptr, int32 val, CONST void *desc)
return SCPE_OK;
}
/* I/O instruction handlers, called from the CPU module when an
IN or OUT instruction is issued.
*/
/* Hardware reset routine */
t_stat zx200a_reset(DEVICE *dptr)
@@ -432,8 +430,8 @@ t_stat zx200a_reset(DEVICE *dptr)
if (dptr == NULL)
return SCPE_ARG;
if (zx200a_onetime) {
zx200a.baseport = SBC202_BASE; //set default base
zx200a.intnum = SBC202_INT; //set default interrupt
zx200a.baseport = ZX200A_BASE; //set default base
zx200a.intnum = ZX200A_INT; //set default interrupt
zx200a.verb = 0; //set verb = 0
zx200a_onetime = 0;
// one-time initialization for all FDDs for this FDC instance
@@ -443,18 +441,18 @@ t_stat zx200a_reset(DEVICE *dptr)
}
}
if ((dptr->flags & DEV_DIS) == 0) { // enabled
reg_dev(zx200ar0DD, zx200a.baseport, 0); //read status
reg_dev(zx200ar0DD, zx200a.baseport + 1, 0); //read rslt type/write IOPB addr-l
reg_dev(zx200ar0DD, zx200a.baseport + 2, 0); //write IOPB addr-h and start
reg_dev(zx200ar3, zx200a.baseport + 3, 0); //read rstl byte
reg_dev(zx200ar7, zx200a.baseport + 7, 0); //write reset fdc201
reg_dev(zx200ar0SD, zx200a.baseport + 16, 0); //read status
reg_dev(zx200ar1SD, zx200a.baseport + 17, 0); //read rslt type/write IOPB addr-l
reg_dev(zx200ar2SD, zx200a.baseport + 18, 0); //write IOPB addr-h and start
reg_dev(zx200ar3, zx200a.baseport + 19, 0); //read rstl byte
reg_dev(zx200ar7, zx200a.baseport + 23, 0); //write reset zx200a
reg_dev(zx200ar0DD, zx200a.baseport, 0, 0); //read status
reg_dev(zx200ar0DD, zx200a.baseport + 1, 0, 0); //read rslt type/write IOPB addr-l
reg_dev(zx200ar0DD, zx200a.baseport + 2, 0, 0); //write IOPB addr-h and start
reg_dev(zx200ar3, zx200a.baseport + 3, 0, 0); //read rstl byte
reg_dev(zx200ar7, zx200a.baseport + 7, 0, 0); //write reset fdc201
reg_dev(zx200ar0SD, zx200a.baseport + 16, 0, 0); //read status
reg_dev(zx200ar1SD, zx200a.baseport + 17, 0, 0); //read rslt type/write IOPB addr-l
reg_dev(zx200ar2SD, zx200a.baseport + 18, 0, 0); //write IOPB addr-h and start
reg_dev(zx200ar3, zx200a.baseport + 19, 0, 0); //read rstl byte
reg_dev(zx200ar7, zx200a.baseport + 23, 0, 0); //write reset zx200a
zx200a_reset_dev(); //software reset
if (zx200a.verb)
// if (zx200a.verb)
sim_printf(" ZX200A: Enabled base port at 0%02XH Interrupt #=%02X %s\n",
zx200a.baseport, zx200a.intnum, zx200a.verb ? "Verbose" : "Quiet" );
} else {
@@ -468,7 +466,7 @@ t_stat zx200a_reset(DEVICE *dptr)
unreg_dev(zx200a.baseport + 18); //write IOPB addr-h and start
unreg_dev(zx200a.baseport + 19); //read rstl byte
unreg_dev(zx200a.baseport + 23); //write reset fdc201
if (zx200a.verb)
// if (zx200a.verb)
sim_printf(" ZX200A: Disabled\n");
}
return SCPE_OK;
@@ -896,6 +894,4 @@ void zx200a_diskio(void)
}
}
#endif /* ZX200A_NUM > 0 */
/* end of zx-200a.c */