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:
84
Intel-Systems/common/cpu.c
Normal file
84
Intel-Systems/common/cpu.c
Normal 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 */
|
||||
61
Intel-Systems/common/front_panel.c
Normal file
61
Intel-Systems/common/front_panel.c
Normal 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 */
|
||||
@@ -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 */
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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
|
||||
};
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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
156
Intel-Systems/common/irq.c
Normal 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 */
|
||||
@@ -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 */
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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 */
|
||||
@@ -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
193
Intel-Systems/common/mem.c
Normal 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 */
|
||||
72
Intel-Systems/common/monitor.c
Normal file
72
Intel-Systems/common/monitor.c
Normal 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 */
|
||||
@@ -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 */
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
254
Intel-Systems/common/port.c
Normal 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
551
Intel-Systems/common/sys.c
Normal 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 */
|
||||
@@ -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 */
|
||||
|
||||
Reference in New Issue
Block a user